/** * @brief std::string → std::wstring変換 * * @param[out] dst 変換結果バッファ * @param src 変換するマルチバイト文字列 * @param loc 変換に使用するlocale * @param cvt 変換関数を提供するcodecvt */ void ToWideString(wstring &dst, const string &src, const codecvt<wstring::value_type, string::value_type, mbstate_t>& cvt) { typedef wstring::value_type wchar_type; typedef string::value_type char_type; typedef codecvt<wchar_type, char_type, mbstate_t> cvt_type; size_t len = src.length(); wchar_type * buff = new wchar_type[len*2]; const char_type* const pbegin = src.c_str(); const char_type* const pend = pbegin + src.length(); const char_type* pnext = pbegin; wchar_type* const pwbegin = &buff[0]; wchar_type* const pwend = &buff[len*2]; wchar_type* pwnext = pwbegin; dst.clear(); mbstate_t state(0); for(;;){ cvt_type::result result = cvt.in(state, pbegin, pend, pnext, pwbegin, pwend, pwnext); dst.append(pwbegin, pwnext - pwbegin); if(result == cvt_type::ok) { break; } assert(result == cvt_type::error); } delete[] buff; }
// A version of from_8_bit which does not use functional object, for // performance comparison. std::wstring from_8_bit_2(const std::string& s, const codecvt<wchar_t, char, mbstate_t>& cvt) { std::wstring result; std::mbstate_t state = std::mbstate_t(); const char* from = s.data(); const char* from_end = s.data() + s.size(); // The interace of cvt is not really iterator-like, and it's // not possible the tell the required output size without the conversion. // All we can is convert data by pieces. while(from != from_end) { // std::basic_string does not provide non-const pointers to the data, // so converting directly into string is not possible. wchar_t buffer[32]; wchar_t* to_next = buffer; // Try to convert remaining input. std::codecvt_base::result r = cvt.in(state, from, from_end, from, buffer, buffer + 32, to_next); if (r == std::codecvt_base::error) throw logic_error("character conversion failed"); // 'partial' is not an error, it just means not all source characters // we converted. However, we need to check that at least one new target // character was produced. If not, it means the source data is // incomplete, and since we don't have extra data to add to source, it's // error. if (to_next == buffer) throw logic_error("character conversion failed"); // Add converted characters result.append(buffer, to_next); } return result; }