我对自己的代码(以及自然的测试)有点怀疑,并希望有人来验证这是否真的与endian无关。
在跨平台项目的内部,我使用UTF-32(std :: u32string)作为字符串类型。但是为了在不同平台上处理I / O更容易,我在将任何文本发送到文件或通过线路之前将UTF-32转换为UTF-8。
我想说这种方法与endian无关。 UTF-8是一种面向字节的编码,这意味着计算机的字节顺序不会影响字节流。大型32位字符按照它们在发送到流中之前在字符串中出现的顺序转换为UTF-8。
这里有来自Json String类的代码片段,以提供我正在做的事情的一个例子
/**
* Provides conversion facilities between UTF-8 and Unicode32 strings.
*/
typedef std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> UnicodeConverter;
/**
* Converts the JSON value to a valid JSON string.
* @param the UTF-8 stream to write to.
* @returns The UTF-8 stream.
*/
inline std::ostream& VToJson(std::ostream& os) const override { return EscapeJsonString(os << STRING_JSON_QUOTE) << STRING_JSON_QUOTE; }
/**
* Streams a json string in its escaped form.
* @param os the UTF-8 stream to write to.
* @returns the original stream.
*/
std::ostream& JsonString::EscapeJsonString(std::ostream &os) const
{
UnicodeConverter conv;
for each (char32_t c in i_Value)
{
// Check if character is a special character
if (c == '\\')
// Output escaped rev solidus
os << "\\\\";
else if (c == '/')
// Output escaped solidus
os << "\\/";
else if (c == '\b')
// Output escaped backspace
os << "\\b";
else if (c == '\f')
// Output escaped formfeed
os << "\\f";
else if (c == '\n')
// Output escaped new line
os << "\\n";
else if (c == '\r')
// Output secaped carriage return
os << "\\r";
else if (c == '\t')
// Output escaped tab
os << "\\t";
else if (is_unicode_control(c))
{
// Output escape
os << "\\u";
// Output hex representation
std::stringstream str;
str << std::setfill('0') << std::setw(4) << std::hex << c;
os << str.str();
}
else
// Normal character
os << conv.to_bytes(c);
}
return os;
}
答案 0 :(得分:1)
一般来说,这种方法可以实现字节序不可知,因为UTF-32仅用于具有相同字节序的系统,而在每种情况下,它与可能具有不同字节序的系统接口使用UTF-8 - 和UTF-8建立在字节流上(因此没有字节顺序)。
但是,转换本身是字节序敏感的,必须正确实现,以便字节顺序不会成为问题(例如,不是memcopy
,而是算术移位)。假设您的标准库实现正确地执行此转换应该是合理的。
添加一些说明,说明为什么此代码不受endianess的影响(22.5 / 4):
对于方面
codecvt_utf8
:
- 小平面应在UTF-8多字节序列和UCS2或UCS4之间转换(取决于 程序中Elem
的大小。
- 字节顺序不应影响如何读取或写入多字节序列 - 多字节序列可以写成文本或二进制文件。
endianess
枚举类型的codecvt_mode
成员仅用于读/写UTF-16和UTF-32多字节序列。