OXYGENHUB
◆ main openmsx / src / utils / utf8_checked.cc
1.6 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifdef _WIN32
2
3
#include "utf8_checked.hh"
4
#include "MSXException.hh"
5
#include <windows.h>
6
7
namespace utf8 {
8
9
[[nodiscard]] static std::wstring multiByteToUtf16(std::string_view multiByte, UINT cp, DWORD dwFlags)
10
{
11
	if (multiByte.empty()) return {};
12
13
	// Get required size for UTF-16 buffer
14
	const char* in = multiByte.data();
15
	auto inSize = static_cast<int>(multiByte.size());
16
	int outSize = MultiByteToWideChar(cp, dwFlags, in, inSize, nullptr, 0);
17
	if (outSize == 0) {
18
		throw openmsx::FatalError(
19
			"MultiByteToWideChar failed: ", GetLastError());
20
	}
21
22
	std::wstring utf16;
23
	utf16.resize_and_overwrite(outSize, [&](wchar_t* out, size_t) -> size_t {
24
		return MultiByteToWideChar(cp, dwFlags, in, inSize, out, outSize);
25
	});
26
	return utf16;
27
}
28
29
30
[[nodiscard]] static std::string utf16ToMultiByte(std::wstring_view utf16, UINT cp)
31
{
32
	if (utf16.empty()) return {};
33
34
	// Get required size for multiByte buffer
35
	const wchar_t* in = utf16.data();
36
	auto inSize = static_cast<int>(utf16.size());
37
	int outSize = WideCharToMultiByte(cp, 0, in, inSize, nullptr, 0, nullptr, nullptr);
38
	if (outSize == 0) {
39
		throw openmsx::FatalError(
40
			"WideCharToMultiByte failed: ", GetLastError());
41
	}
42
43
	std::string multiByte;
44
	multiByte.resize_and_overwrite(outSize, [&](char* out, size_t) -> size_t {
45
		return WideCharToMultiByte(cp, 0, in, inSize, out, outSize, nullptr, nullptr);
46
	});
47
	return multiByte;
48
}
49
50
std::wstring utf8to16(std::string_view utf8)
51
{
52
	return multiByteToUtf16(utf8, CP_UTF8, MB_ERR_INVALID_CHARS);
53
}
54
55
std::string utf16to8(std::wstring_view utf16)
56
{
57
	return utf16ToMultiByte(utf16, CP_UTF8);
58
}
59
60
} // namespace utf8
61
62
#endif // _WIN32