#ifndef RFL_PARSING_PARSER_WSTRING_HPP_ #define RFL_PARSING_PARSER_WSTRING_HPP_ #include #include #include "../Result.hpp" #include "../always_false.hpp" #include "Parent.hpp" #include "Parser_base.hpp" #include "schema/Type.hpp" namespace rfl { namespace parsing { template requires AreReaderAndWriter struct Parser { public: using InputVarType = typename R::InputVarType; using OutputVarType = typename W::OutputVarType; using ParentType = Parent; static Result read(const R& _r, const InputVarType& _var) noexcept { if (_r.is_empty(_var)) { return std::wstring(); } auto inStr = Parser::read(_r, _var); if (auto err = inStr.error(); err.has_value()) { return Result(err.value()); } std::mbstate_t state = std::mbstate_t(); auto val = inStr.value(); std::wstring outStr(val.size() * 2, L'\0'); // Explicitly set the size so we don't empty it when we truncate outStr.resize(val.size() * 2); auto* ptr = val.c_str(); // Add 1 for null terminator auto len = std::mbsrtowcs(outStr.data(), &ptr, val.size(), &state); outStr.resize(len); // Truncate the extra bytes return Result(outStr); } template static void write(const W& _w, const std::wstring& _str, const P& _parent) noexcept { if (_str.empty()) { ParentType::add_value(_w, std::string(), _parent); return; } std::mbstate_t state = std::mbstate_t(); std::string outStr(_str.size(), '\0'); outStr.resize(_str.size()); auto* ptr = _str.c_str(); auto len = std::wcsrtombs(outStr.data(), &ptr, _str.size(), &state); outStr.resize(len); ParentType::add_value(_w, outStr, _parent); } static schema::Type to_schema( std::map* _definitions ) { return Parser::to_schema(_definitions ); } }; } // namespace parsing } // namespace rfl #endif