mirror of https://github.com/libAthena/athena.git
Support for u16string and u32string read/write
This commit is contained in:
parent
483870850c
commit
dd8b60f779
|
@ -493,6 +493,58 @@ inline std::unique_ptr<YAMLNode> ValToNode(const wchar_t* val)
|
|||
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
|
||||
{
|
||||
std::unique_ptr<YAMLNode> m_rootNode;
|
||||
|
@ -1106,6 +1158,26 @@ public:
|
|||
{
|
||||
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,
|
||||
|
|
|
@ -1127,6 +1127,72 @@ public:
|
|||
inline std::wstring readValBig(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
|
||||
{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
|
||||
*
|
||||
* @param vector The std::vector to clear and populate using read data
|
||||
|
|
|
@ -979,7 +979,7 @@ public:
|
|||
|
||||
if (fixedLen < 0)
|
||||
{
|
||||
for (atUint16 c : str)
|
||||
for (wchar_t c : str)
|
||||
{
|
||||
writeUint16Big(c);
|
||||
|
||||
|
@ -993,7 +993,7 @@ public:
|
|||
auto it = str.begin();
|
||||
for (atInt32 i=0 ; i<fixedLen ; ++i)
|
||||
{
|
||||
atUint16 chr;
|
||||
wchar_t chr;
|
||||
if (it == str.end())
|
||||
chr = 0;
|
||||
else
|
||||
|
@ -1004,6 +1004,84 @@ public:
|
|||
}
|
||||
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)
|
||||
{
|
||||
if (length == 0)
|
||||
|
|
Loading…
Reference in New Issue