diff --git a/include/Athena/DNAYaml.hpp b/include/Athena/DNAYaml.hpp index 4afe113..a67d2a1 100644 --- a/include/Athena/DNAYaml.hpp +++ b/include/Athena/DNAYaml.hpp @@ -7,8 +7,6 @@ * Any changes to the types or namespacing must be reflected in 'atdna/main.cpp' */ -#include -#include #include #include #include "DNA.hpp" @@ -376,16 +374,29 @@ inline std::unique_ptr ValToNode(const char* val) template <> inline std::wstring NodeToVal(const YAMLNode* node) { - std::wstring_convert> conv; - return conv.from_bytes(node->m_scalarString); + std::wstring retval; + retval.reserve(node->m_scalarString.length()); + const char* buf = node->m_scalarString.c_str(); + while (*buf) + { + wchar_t wc; + buf += std::mbtowc(&wc, buf, MB_CUR_MAX); + retval += wc; + } + return retval; } template <> inline std::unique_ptr ValToNode(const std::wstring& val) { - std::wstring_convert> conv; YAMLNode* ret = new YAMLNode(YAML_SCALAR_NODE); - ret->m_scalarString = conv.to_bytes(val); + ret->m_scalarString.reserve(val.length()); + for (wchar_t ch : val) + { + char mb[4]; + int c = std::wctomb(mb, ch); + ret->m_scalarString.append(mb, c); + } return std::unique_ptr(ret); } diff --git a/include/Athena/IStreamReader.hpp b/include/Athena/IStreamReader.hpp index 8203fad..06c178d 100644 --- a/include/Athena/IStreamReader.hpp +++ b/include/Athena/IStreamReader.hpp @@ -1,8 +1,7 @@ #ifndef ISTREAMREADER_HPP #define ISTREAMREADER_HPP -#include -#include +#include #include #include "IStream.hpp" @@ -591,7 +590,7 @@ public: */ inline std::string readWStringAsString(atInt32 fixedLen = -1) { - std::wstring tmp; + std::string retval; atUint16 chr = readUint16(); atInt32 i; @@ -603,20 +602,21 @@ public: if (!chr) break; - tmp.push_back(chr); + char mb[4]; + int c = std::wctomb(mb, chr); + retval.append(mb, c); chr = readUint16(); } if (fixedLen >= 0 && i < fixedLen) seek(fixedLen - i); - std::wstring_convert> conv; - return conv.to_bytes(tmp); + return retval; } inline std::string readWStringAsStringLittle(atInt32 fixedLen = -1) { - std::wstring tmp; + std::string retval; atUint16 chr = readUint16Little(); atInt32 i; @@ -628,20 +628,21 @@ public: if (!chr) break; - tmp.push_back(chr); + char mb[4]; + int c = std::wctomb(mb, chr); + retval.append(mb, c); chr = readUint16Little(); } if (fixedLen >= 0 && i < fixedLen) seek(fixedLen - i); - std::wstring_convert> conv; - return conv.to_bytes(tmp); + return retval; } inline std::string readWStringAsStringBig(atInt32 fixedLen = -1) { - std::wstring tmp; + std::string retval; atUint16 chr = readUint16Big(); atInt32 i; @@ -653,15 +654,16 @@ public: if (!chr) break; - tmp.push_back(chr); + char mb[4]; + int c = std::wctomb(mb, chr); + retval.append(mb, c); chr = readUint16Big(); } if (fixedLen >= 0 && i < fixedLen) seek(fixedLen - i); - std::wstring_convert> conv; - return conv.to_bytes(tmp); + return retval; } /*! \brief Reads a string and advances the position in the file diff --git a/include/Athena/IStreamWriter.hpp b/include/Athena/IStreamWriter.hpp index bdda703..1d918ee 100644 --- a/include/Athena/IStreamWriter.hpp +++ b/include/Athena/IStreamWriter.hpp @@ -1,8 +1,6 @@ #ifndef ISTREAMWRITER_HPP #define ISTREAMWRITER_HPP -#include -#include #include "IStream.hpp" namespace Athena @@ -438,76 +436,70 @@ public: */ inline void writeStringAsWString(const std::string& str, atInt32 fixedLen = -1) { - std::string tmpStr = "\xEF\xBB\xBF" + str; + std::string tmpStr = "\xEF\xBB\xBF" + str; + const char* buf = tmpStr.c_str(); - std::wstring_convert> conv; - std::wstring tmp = conv.from_bytes(tmpStr); + if (fixedLen < 0) + { + while (*buf) + { + wchar_t wc; + buf += std::mbtowc(&wc, buf, MB_CUR_MAX); + if (wc != 0xFEFF) + writeUint16(wc); + } + writeUint16(0); + } + else + { + for (atInt32 i=0 ; i> conv; - std::wstring tmp = conv.from_bytes(tmpStr); + const char* buf = tmpStr.c_str(); if (fixedLen < 0) { - for (atUint16 chr : tmp) + while (*buf) { - if (chr != 0xFEFF) - writeUint16Little(chr); + wchar_t wc; + buf += std::mbtowc(&wc, buf, MB_CUR_MAX); + if (wc != 0xFEFF) + writeUint16Little(wc); } writeUint16Little(0); } else { - auto it = tmp.begin(); for (atInt32 i=0 ; i> conv; - std::wstring tmp = conv.from_bytes(tmpStr); + const char* buf = tmpStr.c_str(); if (fixedLen < 0) { - for (atUint16 chr : tmp) + while (*buf) { - if (chr != 0xFEFF) - writeUint16Big(chr); + wchar_t wc; + buf += std::mbtowc(&wc, buf, MB_CUR_MAX); + if (wc != 0xFEFF) + writeUint16Big(wc); } writeUint16Big(0); } else { - auto it = tmp.begin(); for (atInt32 i=0 ; i -#include -#include namespace Athena { @@ -74,27 +72,27 @@ void SkywardSwordQuest::setPlayerName(const std::string& name) if (name.length() > 8) atDebug("WARNING: name cannot be greater than 8 characters, automatically truncating"); - std::wstring_convert> conv; - std::wstring val = conv.from_bytes(name); - + const char* buf = name.c_str(); for (atUint32 i = 0; i < 8; i++) { atUint16& c = *(atUint16*)(m_data.get() + priv::NAME_OFFSET + (i * 2)); - if (i >= val.size()) + if (!*buf) { c = 0; continue; } - c = val[i]; + wchar_t wc; + buf += std::mbtowc(&wc, buf, MB_CUR_MAX); + c = wc; utility::BigUint16(c); } } std::string SkywardSwordQuest::playerName() const { - std::wstring val; + std::string val; for (atUint32 i = 0; i < 8; i++) { @@ -104,11 +102,12 @@ std::string SkywardSwordQuest::playerName() const break; utility::BigUint16(c); - val.push_back(c); + char mb[4]; + int cs = std::wctomb(mb, c); + val.append(mb, cs); } - std::wstring_convert> conv; - return conv.to_bytes(val); + return val; } void SkywardSwordQuest::setRupeeCount(atUint16 value)