// original code is from here: http://www.codeproject.com/Tips/197097/Converting-ANSI-to-Unicode-and-back // License: The Code Project Open License (CPOL) http://www.codeproject.com/info/cpol10.aspx #ifndef UTFENCODEDECODE_H #define UTFENCODEDECODE_H #include #include #include #include std::string EncodeToUTF8(const std::string &, const std::locale & = std::locale::classic()); std::string DecodeFromUTF8(const std::string &, const std::locale & = std::locale::classic()); template class cp_converter { const std::locale loc; public: cp_converter(const std::locale &L = std::locale::classic()) : loc(L) { } std::wstring widen(const std::string &in) { return this->convert(in); } std::string narrow(const std::wstring &in) { return this->convert(in); } private: typedef std::codecvt codecvt_facet; // widen codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const char *f1, const char *l1, const char *&n1, wchar_t *f2, wchar_t *l2, wchar_t *&n2) const { return facet.in(s, f1, l1, n1, f2, l2, n2); } // narrow codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const wchar_t *f1, const wchar_t *l1, const wchar_t *&n1, char *f2, char *l2, char *&n2) const { return facet.out(s, f1, l1, n1, f2, l2, n2); } template std::basic_string convert(const std::basic_string &in) { auto &facet = std::use_facet(this->loc); std::basic_stringstream os; ct_out buf[buf_size]; mbstate_t state = {0}; codecvt_facet::result result; const ct_in *ipc = &in[0]; do { ct_out *opc = nullptr; result = this->cv(facet, state, ipc, &in[0] + in.length(), ipc, buf, buf + buf_size, opc); os << std::basic_string(buf, opc - buf); } while (ipc < &in[0] + in.length() && result != codecvt_facet::error); if (result != codecvt_facet::ok) throw std::runtime_error("result is not ok!"); return os.str(); } }; #endif