From 3fd75906b673d4a90b9851336d731902dba2d3e4 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 17 May 2018 20:00:39 +0200 Subject: [PATCH] Fix String::ToUtf8 and String::ToUtf16 on Linux. wchar_t typically uses UTF-32 codepoints on Linux, unlike Windows, which uses UTF-16. --- src/openrct2/core/String.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/openrct2/core/String.cpp b/src/openrct2/core/String.cpp index 93db9e39da..405f06b1cc 100644 --- a/src/openrct2/core/String.cpp +++ b/src/openrct2/core/String.cpp @@ -26,6 +26,7 @@ #ifndef _WIN32 #include #include +#include #endif #ifdef _WIN32 @@ -82,8 +83,17 @@ namespace String WideCharToMultiByte(CODE_PAGE::CP_UTF8, 0, src.data(), srcLen, result.data(), sizeReq, nullptr, nullptr); return result; #else +// Which constructor to use depends on the size of wchar_t... +// UTF-32 is the default on most POSIX systems; Windows uses UTF-16. +// Unfortunately, we'll have to help the compiler here. +#if U_SIZEOF_WCHAR_T==4 + icu::UnicodeString str = icu::UnicodeString::fromUTF32((const UChar32*) src.data(), src.length()); +#elif U_SIZEOF_WCHAR_T==2 std::wstring wstr = std::wstring(src); - icu::UnicodeString str = icu::UnicodeString((char16_t*) wstr.c_str()); + icu::UnicodeString str = icu::UnicodeString((const wchar_t*) wstr.c_str()); +#else +#error Unsupported U_SIZEOF_WCHAR_T size +#endif std::string result; str.toUTF8String(result); @@ -103,9 +113,24 @@ namespace String #else icu::UnicodeString str = icu::UnicodeString::fromUTF8(std::string(src)); +// Which constructor to use depends on the size of wchar_t... +// UTF-32 is the default on most POSIX systems; Windows uses UTF-16. +// Unfortunately, we'll have to help the compiler here. +#if U_SIZEOF_WCHAR_T==4 + size_t length = (size_t) str.length(); + std::wstring result(length, '\0'); + + UErrorCode status = U_ZERO_ERROR; + str.toUTF32((UChar32*) &result[0], str.length(), status); + +#elif U_SIZEOF_WCHAR_T==2 const char16_t* buffer = str.getBuffer(); std::wstring result = (wchar_t*) buffer; +#else +#error Unsupported U_SIZEOF_WCHAR_T size +#endif + return result; #endif }