Support for u16string and u32string read/write

This commit is contained in:
Jack Andersen 2017-01-23 21:39:47 -10:00
parent 483870850c
commit dd8b60f779
3 changed files with 218 additions and 2 deletions

View File

@ -493,6 +493,58 @@ inline std::unique_ptr<YAMLNode> ValToNode(const wchar_t* val)
return ValToNode<const std::wstring&>(wstr); return ValToNode<const std::wstring&>(wstr);
} }
template <>
inline std::unique_ptr<YAMLNode> ValToNode(const std::u16string& val)
{
YAMLNode* ret = new YAMLNode(YAML_SCALAR_NODE);
ret->m_scalarString.reserve(val.length());
for (char16_t ch : val)
{
utf8proc_uint8_t mb[4];
utf8proc_ssize_t c = utf8proc_encode_char(utf8proc_int32_t(ch), mb);
if (c < 0)
{
atWarning("invalid UTF-8 character while encoding");
return std::unique_ptr<YAMLNode>(ret);
}
ret->m_scalarString.append(reinterpret_cast<char*>(mb), c);
}
return std::unique_ptr<YAMLNode>(ret);
}
template <>
inline std::unique_ptr<YAMLNode> ValToNode(const char16_t* val)
{
std::u16string wstr(val);
return ValToNode<const std::u16string&>(wstr);
}
template <>
inline std::unique_ptr<YAMLNode> ValToNode(const std::u32string& val)
{
YAMLNode* ret = new YAMLNode(YAML_SCALAR_NODE);
ret->m_scalarString.reserve(val.length());
for (char32_t ch : val)
{
utf8proc_uint8_t mb[4];
utf8proc_ssize_t c = utf8proc_encode_char(utf8proc_int32_t(ch), mb);
if (c < 0)
{
atWarning("invalid UTF-8 character while encoding");
return std::unique_ptr<YAMLNode>(ret);
}
ret->m_scalarString.append(reinterpret_cast<char*>(mb), c);
}
return std::unique_ptr<YAMLNode>(ret);
}
template <>
inline std::unique_ptr<YAMLNode> ValToNode(const char32_t* val)
{
std::u32string wstr(val);
return ValToNode<const std::u32string&>(wstr);
}
class YAMLDocReader class YAMLDocReader
{ {
std::unique_ptr<YAMLNode> m_rootNode; std::unique_ptr<YAMLNode> m_rootNode;
@ -1106,6 +1158,26 @@ public:
{ {
writeVal<const wchar_t*>(name, val); writeVal<const wchar_t*>(name, val);
} }
inline void writeU16String(const char* name, const std::u16string& val)
{
writeVal<std::u16string>(name, val);
}
inline void writeU16String(const char* name, const char16_t* val)
{
writeVal<const char16_t*>(name, val);
}
inline void writeU32String(const char* name, const std::u32string& val)
{
writeVal<std::u32string>(name, val);
}
inline void writeU32String(const char* name, const char32_t* val)
{
writeVal<const char32_t*>(name, val);
}
}; };
int YAMLAthenaReader(athena::io::IStreamReader* reader, int YAMLAthenaReader(athena::io::IStreamReader* reader,

View File

@ -1127,6 +1127,72 @@ public:
inline std::wstring readValBig(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0) inline std::wstring readValBig(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
{return readWStringBig();} {return readWStringBig();}
/** @brief Reads a u16string assuming big-endian characters
* and advances the position in the file
*
* @param fixedLen If non-negative, this is a fixed-length string read
* @return The read wstring
*/
inline std::u16string readU16StringBig(atInt32 fixedLen = -1)
{
if (fixedLen == 0)
return std::u16string();
std::u16string ret;
char16_t chr = readUint16Big();
atInt32 i;
for (i = 1 ; chr != 0 ; ++i)
{
ret += chr;
if (fixedLen >= 0 && i >= fixedLen)
break;
chr = readUint16Big();
}
if (fixedLen >= 0 && i < fixedLen)
seek(fixedLen - i);
return ret;
}
template <class T>
inline std::u16string readValBig(typename std::enable_if<std::is_same<T, std::u16string>::value>::type* = 0)
{return readU16StringBig();}
/** @brief Reads a u32string assuming big-endian characters
* and advances the position in the file
*
* @param fixedLen If non-negative, this is a fixed-length string read
* @return The read wstring
*/
inline std::u32string readU32StringBig(atInt32 fixedLen = -1)
{
if (fixedLen == 0)
return std::u32string();
std::u32string ret;
char32_t chr = readUint32Big();
atInt32 i;
for (i = 1 ; chr != 0 ; ++i)
{
ret += chr;
if (fixedLen >= 0 && i >= fixedLen)
break;
chr = readUint32Big();
}
if (fixedLen >= 0 && i < fixedLen)
seek(fixedLen - i);
return ret;
}
template <class T>
inline std::u32string readValBig(typename std::enable_if<std::is_same<T, std::u32string>::value>::type* = 0)
{return readU32StringBig();}
/** @brief Performs automatic std::vector enumeration reads using numeric type T /** @brief Performs automatic std::vector enumeration reads using numeric type T
* *
* @param vector The std::vector to clear and populate using read data * @param vector The std::vector to clear and populate using read data

View File

@ -979,7 +979,7 @@ public:
if (fixedLen < 0) if (fixedLen < 0)
{ {
for (atUint16 c : str) for (wchar_t c : str)
{ {
writeUint16Big(c); writeUint16Big(c);
@ -993,7 +993,7 @@ public:
auto it = str.begin(); auto it = str.begin();
for (atInt32 i=0 ; i<fixedLen ; ++i) for (atInt32 i=0 ; i<fixedLen ; ++i)
{ {
atUint16 chr; wchar_t chr;
if (it == str.end()) if (it == str.end())
chr = 0; chr = 0;
else else
@ -1004,6 +1004,84 @@ public:
} }
inline void writeValBig(const std::wstring& val) {writeWStringBig(val);} inline void writeValBig(const std::wstring& val) {writeWStringBig(val);}
/** @brief Writes a u16string to the buffer and advances the buffer.
*
* @param str The string to write to the buffer
* @param fixedLen If not -1, the number of characters to zero-fill string to
*
* Endianness is big
*/
inline void writeU16StringBig(const std::u16string& str, atInt32 fixedLen = -1)
{
if (fixedLen == 0)
return;
if (fixedLen < 0)
{
for (char16_t c : str)
{
writeUint16Big(c);
if (c == u'\0')
break;
}
writeUint16Big(0);
}
else
{
auto it = str.begin();
for (atInt32 i=0 ; i<fixedLen ; ++i)
{
char16_t chr;
if (it == str.end())
chr = 0;
else
chr = *it++;
writeUint16Big(chr);
}
}
}
inline void writeValBig(const std::u16string& val) {writeU16StringBig(val);}
/** @brief Writes a u16string to the buffer and advances the buffer.
*
* @param str The string to write to the buffer
* @param fixedLen If not -1, the number of characters to zero-fill string to
*
* Endianness is big
*/
inline void writeU32StringBig(const std::u32string& str, atInt32 fixedLen = -1)
{
if (fixedLen == 0)
return;
if (fixedLen < 0)
{
for (char32_t c : str)
{
writeUint32Big(c);
if (c == U'\0')
break;
}
writeUint32Big(0);
}
else
{
auto it = str.begin();
for (atInt32 i=0 ; i<fixedLen ; ++i)
{
char32_t chr;
if (it == str.end())
chr = 0;
else
chr = *it++;
writeUint32Big(chr);
}
}
}
inline void writeValBig(const std::u32string& val) {writeU32StringBig(val);}
inline void fill(atUint8 val, atUint64 length) inline void fill(atUint8 val, atUint64 length)
{ {
if (length == 0) if (length == 0)