openMSX
utf8_checked.cc
Go to the documentation of this file.
1#ifdef _WIN32
2
3#include "utf8_checked.hh"
4#include "vla.hh"
5#include "MSXException.hh"
6#include <Windows.h>
7
8namespace utf8 {
9
10static bool multiByteToUtf16(zstring_view multiByte, UINT cp, DWORD dwFlags, std::wstring& utf16)
11{
12 const char* multiByteA = multiByte.c_str();
13 if (int len = MultiByteToWideChar(cp, dwFlags, multiByteA, -1, nullptr, 0)) {
14 VLA(wchar_t, utf16W, len);
15 len = MultiByteToWideChar(cp, dwFlags, multiByteA, -1, utf16W.data(), len);
16 if (len) {
17 utf16 = utf16W.data();
18 return true;
19 }
20 }
21 return false;
22}
23
24static bool utf16ToMultiByte(const std::wstring& utf16, UINT cp, std::string& multiByte)
25{
26 const wchar_t* utf16W = utf16.c_str();
27 if (int len = WideCharToMultiByte(cp, 0, utf16W, -1, nullptr, 0, nullptr, nullptr)) {
28 VLA(char, multiByteA, len);
29 len = WideCharToMultiByte(cp, 0, utf16W, -1, multiByteA.data(), len, nullptr, nullptr);
30 if (len) {
31 multiByte = multiByteA.data();
32 return true;
33 }
34 }
35 return false;
36}
37
38std::string utf8ToAnsi(zstring_view utf8)
39{
40 std::wstring utf16;
41 if (!multiByteToUtf16(utf8, CP_UTF8, MB_ERR_INVALID_CHARS, utf16)) {
43 "MultiByteToWideChar failed: ", GetLastError());
44 }
45
46 std::string ansi;
47 if (!utf16ToMultiByte(utf16, CP_ACP, ansi)) {
49 "MultiByteToWideChar failed: ", GetLastError());
50 }
51 return ansi;
52}
53
54std::wstring utf8to16(zstring_view utf8)
55{
56 std::wstring utf16;
57 if (!multiByteToUtf16(utf8, CP_UTF8, MB_ERR_INVALID_CHARS, utf16))
58 {
60 "MultiByteToWideChar failed: ", GetLastError());
61 }
62 return utf16;
63}
64
65std::string utf16to8(const std::wstring& utf16)
66{
67 std::string utf8;
68 if (!utf16ToMultiByte(utf16, CP_UTF8, utf8))
69 {
71 "MultiByteToWideChar failed: ", GetLastError());
72 }
73 return utf8;
74}
75
76} // namespace utf8
77
78#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)
#define VLA(TYPE, NAME, LENGTH)
Definition vla.hh:12