openMSX
utf8_checked.cc
Go to the documentation of this file.
1#ifdef _WIN32
2
3#include "utf8_checked.hh"
4#include "MSXException.hh"
5#include <windows.h>
6
7namespace utf8 {
8
9static bool multiByteToUtf16(zstring_view multiByte, UINT cp, DWORD dwFlags, std::wstring& utf16)
10{
11 const char* multiByteA = multiByte.c_str();
12 if (int len = MultiByteToWideChar(cp, dwFlags, multiByteA, -1, nullptr, 0)) {
13 utf16.resize(len); // TODO use c++23 resize_and_overwrite()
14 int len2 = MultiByteToWideChar(cp, dwFlags, multiByteA, -1, utf16.data(), len);
15 utf16.resize(len - 1); // remove 0-terminator, std::wstring handles it internally
16 if (len2) return true;
17 }
18 return false;
19}
20
21static bool utf16ToMultiByte(const std::wstring& utf16, UINT cp, std::string& multiByte)
22{
23 const wchar_t* utf16W = utf16.c_str();
24 if (int len = WideCharToMultiByte(cp, 0, utf16W, -1, nullptr, 0, nullptr, nullptr)) {
25 multiByte.resize(len); // TODO use c++23 resize_and_overwrite()
26 int len2 = WideCharToMultiByte(cp, 0, utf16W, -1, multiByte.data(), len, nullptr, nullptr);
27 multiByte.resize(len - 1); // remove 0-terminator, std::string handles it internally
28 if (len2) return true;
29 }
30 return false;
31}
32
33std::string utf8ToAnsi(zstring_view utf8)
34{
35 std::wstring utf16;
36 if (!multiByteToUtf16(utf8, CP_UTF8, MB_ERR_INVALID_CHARS, utf16)) {
38 "MultiByteToWideChar failed: ", GetLastError());
39 }
40
41 std::string ansi;
42 if (!utf16ToMultiByte(utf16, CP_ACP, ansi)) {
44 "MultiByteToWideChar failed: ", GetLastError());
45 }
46 return ansi;
47}
48
49std::wstring utf8to16(zstring_view utf8)
50{
51 std::wstring utf16;
52 if (!multiByteToUtf16(utf8, CP_UTF8, MB_ERR_INVALID_CHARS, utf16))
53 {
55 "MultiByteToWideChar failed: ", GetLastError());
56 }
57 return utf16;
58}
59
60std::string utf16to8(const std::wstring& utf16)
61{
62 std::string utf8;
63 if (!utf16ToMultiByte(utf16, CP_UTF8, utf8))
64 {
66 "MultiByteToWideChar failed: ", GetLastError());
67 }
68 return utf8;
69}
70
71} // namespace utf8
72
73#endif // _WIN32
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
constexpr const char * c_str() const
u16bit_iterator utf8to16(octet_iterator start, octet_iterator end, u16bit_iterator result)
octet_iterator utf16to8(u16bit_iterator start, u16bit_iterator end, octet_iterator result)