std::string moon::wstring_to_string(const std::wstring& ws) { std::locale sys_loc(""); const wchar_t* src_wstr = ws.c_str(); const size_t MAX_UNICODE_BYTES = 4; const size_t BUFFER_SIZE = ws.size() * MAX_UNICODE_BYTES + 1; std::string extern_buffer(BUFFER_SIZE,0); const wchar_t* intern_from = src_wstr; const wchar_t* intern_from_end = intern_from + ws.size(); const wchar_t* intern_from_next = 0; char* extern_to = &extern_buffer[0]; char* extern_to_end = extern_to + BUFFER_SIZE; char* extern_to_next = 0; typedef std::codecvt<wchar_t, char, mbstate_t> CodecvtFacet; CodecvtFacet::result cvt_rst = std::use_facet<CodecvtFacet>(sys_loc).out( out_cvt_state, intern_from, intern_from_end, intern_from_next, extern_to, extern_to_end, extern_to_next); if (cvt_rst != CodecvtFacet::ok) { switch(cvt_rst) { case CodecvtFacet::partial: std::cerr << "partial"; break; case CodecvtFacet::error: std::cerr << "error"; break; case CodecvtFacet::noconv: std::cerr << "noconv"; break; default: std::cerr << "unknown"; } std::cerr << ", please check out_cvt_state." << std::endl; } return std::move(extern_buffer); }
std::wstring moon::string_to_wstring(const std::string& s) { std::locale sys_loc(""); const size_t BUFFER_SIZE = s.size() + 1; std::wstring intern_buffer(BUFFER_SIZE, 0); const char* extern_from_next = 0; wchar_t* intern_to_next = 0; typedef std::codecvt<wchar_t, char, mbstate_t> CodecvtFacet; CodecvtFacet::result cvt_rst = std::use_facet<CodecvtFacet>(sys_loc).in( in_cvt_state, s.c_str(), s.c_str() + s.size(), extern_from_next, &intern_buffer[0], &intern_buffer[0] + intern_buffer.size(), intern_to_next); if (cvt_rst != CodecvtFacet::ok) { switch(cvt_rst) { case CodecvtFacet::partial: std::cerr << "partial"; break; case CodecvtFacet::error: std::cerr << "error"; break; case CodecvtFacet::noconv: std::cerr << "noconv"; break; default: std::cerr << "unknown"; } std::cerr << ", please check in_cvt_state." << std::endl; } std::wstring result = intern_buffer; return std::move(intern_buffer); }
OutS CodeConvert(const InS& ins) { std::locale sys_loc(""); const In* src_insrc = ins.c_str(); const size_t BUFFER_SIZE = ins.size() * Max_In_Size; const size_t OUT_SIZE = sizeof(Out); // TODO: // reasonable size , it may be too large the allocation to // on the Out[BUFFER_SIZE] Out * extern_buffer = new Out[BUFFER_SIZE]; memset(extern_buffer, 0, BUFFER_SIZE * OUT_SIZE); const In * intern_from = src_insrc; const In * intern_from_end = intern_from + ins.size(); const In * intern_from_next = 0; Out * extern_from = extern_buffer; Out * extern_from_end = extern_from + BUFFER_SIZE; Out * extern_from_next = 0; typedef std::codecvt<In, Out, std::mbstate_t> CodeCvtFacet; // TODO: // it is required to have the typename in front of the // CodeCvtFacet // It is because of the CodeCvtFacet is a dependent scope, which means it required // to explicitly tell the compiler that the CodeCvtFacet is a type // typename CodeCvtFacet::result cvt_rst = std::use_facet<CodeCvtFacet>(sys_loc).out( out_cvt_state, intern_from, intern_from_end, intern_from_next, extern_from, extern_from_end, extern_from_next ); if (cvt_rst != CodeCvtFacet::ok) { switch (cvt_rst) { case CodeCvtFacet::error: std::cerr << "partial"; break; case CodeCvtFacet::partial: std::cerr << "partial"; break; case CodeCvtFacet::noconv: std::cerr << "noconv"; break; default: std::cerr << "unknown"; break; } std::cerr << ", please check out_cvt_state." << std::endl; } OutS result = extern_buffer; delete[] extern_buffer; return result; };