1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
#ifndef RFL_PARSING_PARSER_WSTRING_HPP_
#define RFL_PARSING_PARSER_WSTRING_HPP_
#include <map>
#include <type_traits>
#include "../Result.hpp"
#include "../always_false.hpp"
#include "Parent.hpp"
#include "Parser_base.hpp"
#include "schema/Type.hpp"
namespace rfl {
namespace parsing {
template <class R, class W, class ProcessorsType>
requires AreReaderAndWriter<R, W, std::wstring>
struct Parser<R, W, std::wstring, ProcessorsType> {
public:
using InputVarType = typename R::InputVarType;
using ParentType = Parent<W>;
static Result<std::wstring> read(const R& _r,
const InputVarType& _var) noexcept {
if (_r.is_empty(_var)) {
return std::wstring();
}
auto inStr = Parser<R, W, std::string, ProcessorsType>::read(_r, _var);
if (!inStr) {
return Result<std::wstring>(error(inStr.error()));
}
// if (auto err = inStr.error(); err.has_value()) {
// return Result<std::wstring>(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<std::wstring>(outStr);
}
template <class P>
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<std::string, schema::Type>* _definitions) {
return Parser<R, W, std::string, ProcessorsType>::to_schema(_definitions);
}
};
} // namespace parsing
} // namespace rfl
#endif
|