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);
|
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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue