22 enum class charset_id : uint16_t {
39 template <
typename T_from,
typename T_to>
43 iconverter(_In_ charset_id from, _In_ charset_id to)
45 m_handle = iconv_open(to_encoding(to), to_encoding(from));
46 if (m_handle == (iconv_t)-1)
47 throw std::runtime_error(
"iconv_open failed");
52 iconv_close(m_handle);
55 void convert(_Inout_ std::basic_string<T_to> &dst, _In_reads_or_z_opt_(count)
const T_from* src, _In_
size_t count_src)
const
58 count_src = stdex::strnlen(src, count_src);
59 size_t src_size = stdex::mul(
sizeof(T_from), count_src);
61 T_to* output = &buf[0];
62 size_t output_size =
sizeof(buf);
64 iconv(m_handle, (
char**)&src, &src_size, (
char**)&output, &output_size);
66 throw std::runtime_error(
"iconv failed");
67 dst.insert(dst.end(), buf, (T_to*)((
char*)buf +
sizeof(buf) - output_size));
72 static const char* to_encoding(_In_ charset_id charset)
75 case charset_id::system:
76 case charset_id::utf8:
return "UTF-8";
77#if BYTE_ORDER == BIG_ENDIAN
78 case charset_id::utf16:
return "UTF-16BE";
79 case charset_id::utf32:
return "UTF-32BE";
81 case charset_id::utf16:
return "UTF-16LE";
82 case charset_id::utf32:
return "UTF-32LE";
84 default:
throw std::invalid_argument(
"unsupported charset");
102 _Inout_ std::wstring& dst,
103 _In_reads_or_z_opt_(count_src)
const char* src, _In_
size_t count_src,
104 _In_ charset_id charset = charset_id::system)
106 assert(src || !count_src);
108 assert(count_src < INT_MAX || count_src == SIZE_MAX);
109 constexpr DWORD dwFlags = MB_PRECOMPOSED;
112 WCHAR szStackBuffer[1024/
sizeof(WCHAR)];
113#pragma warning(suppress: 6387)
114 int cch = MultiByteToWideChar(
static_cast<UINT
>(charset), dwFlags, src,
static_cast<int>(count_src), szStackBuffer, _countof(szStackBuffer));
117 dst.append(szStackBuffer, count_src != SIZE_MAX ? wcsnlen(szStackBuffer, cch) : (size_t)cch - 1);
118 }
else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
120 cch = MultiByteToWideChar(
static_cast<UINT
>(charset), dwFlags, src,
static_cast<int>(count_src), NULL, 0);
121 std::unique_ptr<WCHAR[]> szBuffer(
new WCHAR[cch]);
122 cch = MultiByteToWideChar(
static_cast<UINT
>(charset), dwFlags, src,
static_cast<int>(count_src), szBuffer.get(), cch);
123 dst.append(szBuffer.get(), count_src != SIZE_MAX ? wcsnlen(szBuffer.get(), cch) : (size_t)cch - 1);
126 iconverter<char, wchar_t>(charset, charset_id::utf32).convert(dst, src, count_src);
130 _Deprecated_(
"Use stdex::strcat")
131 inline
void str2wstr(
132 _Inout_ std::wstring& dst,
133 _In_reads_or_z_opt_(count_src) const
char* src, _In_
size_t count_src,
134 _In_ charset_id charset = charset_id::system)
136 strcat(dst, src, count_src, charset);
147 _Inout_ std::wstring& dst,
148 _In_
const std::string& src,
149 _In_ charset_id charset = charset_id::system)
151 strcat(dst, src.data(), src.size(), charset);
154 _Deprecated_(
"Use stdex::strcat")
155 inline
void str2wstr(
156 _Inout_ std::wstring& dst,
157 _In_ const std::
string& src,
158 _In_ charset_id charset = charset_id::system)
160 strcat(dst, src, charset);
172 _Inout_ std::wstring& dst,
173 _In_reads_or_z_opt_(count_src)
const char* src, _In_
size_t count_src,
174 _In_ charset_id charset = charset_id::system)
177 strcat(dst, src, count_src, charset);
188 _Inout_ std::wstring& dst,
189 _In_
const std::string& src,
190 _In_ charset_id charset = charset_id::system)
192 strcpy(dst, src.data(), src.size(), charset);
203 inline std::wstring str2wstr(
204 _In_z_
const char* src,
205 _In_ charset_id charset = charset_id::system)
208 strcat(dst, src, SIZE_MAX, charset);
221 inline std::wstring str2wstr(
222 _In_reads_or_z_opt_(count_src)
const char* src, _In_
size_t count_src,
223 _In_ charset_id charset = charset_id::system)
226 strcat(dst, src, count_src, charset);
238 inline std::wstring str2wstr(
239 _In_
const std::string& src,
240 _In_ charset_id charset = charset_id::system)
242 return str2wstr(src.c_str(), src.size(), charset);
254 _Inout_ std::string& dst,
255 _In_reads_or_z_opt_(count_src)
const wchar_t* src, _In_
size_t count_src,
256 _In_ charset_id charset = charset_id::system)
258 assert(src || !count_src);
260 assert(count_src < INT_MAX || count_src == SIZE_MAX);
261 constexpr DWORD dwFlags = 0;
262 constexpr LPCCH lpDefaultChar = NULL;
265 CHAR szStackBuffer[1024/
sizeof(CHAR)];
266#pragma warning(suppress: 6387)
267 int cch = WideCharToMultiByte(
static_cast<UINT
>(charset), dwFlags, src,
static_cast<int>(count_src), szStackBuffer, _countof(szStackBuffer), lpDefaultChar, NULL);
270 dst.append(szStackBuffer, count_src != SIZE_MAX ? strnlen(szStackBuffer, cch) : (size_t)cch - 1);
271 }
else if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
273 cch = WideCharToMultiByte(
static_cast<UINT
>(charset), dwFlags, src,
static_cast<int>(count_src), NULL, 0, lpDefaultChar, NULL);
274 std::unique_ptr<CHAR[]> szBuffer(
new CHAR[cch]);
275 cch = WideCharToMultiByte(
static_cast<UINT
>(charset), dwFlags, src,
static_cast<int>(count_src), szBuffer.get(), cch, lpDefaultChar, NULL);
276 dst.append(szBuffer.get(), count_src != SIZE_MAX ? strnlen(szBuffer.get(), cch) : (size_t)cch - 1);
279 iconverter<wchar_t, char>(charset_id::utf32, charset).convert(dst, src, count_src);
283 _Deprecated_(
"Use stdex::strcat")
284 inline
void wstr2str(
285 _Inout_ std::
string& dst,
286 _In_reads_or_z_opt_(count_src) const
wchar_t* src, _In_
size_t count_src,
287 _In_ charset_id charset = charset_id::system)
289 strcat(dst, src, count_src, charset);
300 _Inout_ std::string& dst,
301 _In_
const std::wstring& src,
302 _In_ charset_id charset = charset_id::system)
304 strcat(dst, src.c_str(), src.size(), charset);
307 _Deprecated_(
"Use stdex::strcat")
308 inline
void wstr2str(
309 _Inout_ std::
string& dst,
310 _In_ const std::wstring& src,
311 _In_ charset_id charset = charset_id::system)
313 strcat(dst, src, charset);
325 _Inout_ std::string& dst,
326 _In_reads_or_z_opt_(count_src)
const wchar_t* src, _In_
size_t count_src,
327 _In_ charset_id charset = charset_id::system)
330 strcat(dst, src, count_src, charset);
341 _Inout_ std::string& dst,
342 _In_
const std::wstring& src,
343 _In_ charset_id charset = charset_id::system)
345 strcpy(dst, src.data(), src.size(), charset);
356 inline std::string wstr2str(
357 _In_z_
const wchar_t* src,
358 _In_ charset_id charset = charset_id::system)
361 strcat(dst, src, SIZE_MAX, charset);
374 inline std::string wstr2str(
375 _In_reads_or_z_opt_(count_src)
const wchar_t* src, _In_
size_t count_src,
376 _In_ charset_id charset = charset_id::system)
379 strcat(dst, src, count_src, charset);
391 inline std::string wstr2str(
392 _In_
const std::wstring& src,
393 _In_ charset_id charset = charset_id::system)
395 return wstr2str(src.c_str(), src.size(), charset);
Unicode converter context.
Definition unicode.hpp:41