diff --git a/include/athena/DNAYaml.hpp b/include/athena/DNAYaml.hpp index 5e3ffb0..0b295aa 100644 --- a/include/athena/DNAYaml.hpp +++ b/include/athena/DNAYaml.hpp @@ -493,6 +493,58 @@ inline std::unique_ptr ValToNode(const wchar_t* val) return ValToNode(wstr); } +template <> +inline std::unique_ptr 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(ret); + } + ret->m_scalarString.append(reinterpret_cast(mb), c); + } + return std::unique_ptr(ret); +} + +template <> +inline std::unique_ptr ValToNode(const char16_t* val) +{ + std::u16string wstr(val); + return ValToNode(wstr); +} + +template <> +inline std::unique_ptr 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(ret); + } + ret->m_scalarString.append(reinterpret_cast(mb), c); + } + return std::unique_ptr(ret); +} + +template <> +inline std::unique_ptr ValToNode(const char32_t* val) +{ + std::u32string wstr(val); + return ValToNode(wstr); +} + class YAMLDocReader { std::unique_ptr m_rootNode; @@ -1106,6 +1158,26 @@ public: { writeVal(name, val); } + + inline void writeU16String(const char* name, const std::u16string& val) + { + writeVal(name, val); + } + + inline void writeU16String(const char* name, const char16_t* val) + { + writeVal(name, val); + } + + inline void writeU32String(const char* name, const std::u32string& val) + { + writeVal(name, val); + } + + inline void writeU32String(const char* name, const char32_t* val) + { + writeVal(name, val); + } }; int YAMLAthenaReader(athena::io::IStreamReader* reader, diff --git a/include/athena/IStreamReader.hpp b/include/athena/IStreamReader.hpp index cf8a221..e4963cd 100644 --- a/include/athena/IStreamReader.hpp +++ b/include/athena/IStreamReader.hpp @@ -1127,6 +1127,72 @@ public: inline std::wstring readValBig(typename std::enable_if::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 + inline std::u16string readValBig(typename std::enable_if::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 + inline std::u32string readValBig(typename std::enable_if::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 diff --git a/include/athena/IStreamWriter.hpp b/include/athena/IStreamWriter.hpp index 8829aef..ae50c0f 100644 --- a/include/athena/IStreamWriter.hpp +++ b/include/athena/IStreamWriter.hpp @@ -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