From 386ab1b0fa5c4190d04ec637c343dfd6678a7324 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 14 May 2018 22:07:05 +0100 Subject: [PATCH] Add windows implementation for ToUpper --- src/openrct2/core/String.cpp | 53 ++++++++++++++++++++++++++++++++---- src/openrct2/core/String.hpp | 4 +-- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/openrct2/core/String.cpp b/src/openrct2/core/String.cpp index fd044b5590..0eacccdb85 100644 --- a/src/openrct2/core/String.cpp +++ b/src/openrct2/core/String.cpp @@ -79,10 +79,10 @@ namespace String return result; } - std::wstring ToUtf16(const std::string &s) + std::wstring ToUtf16(const std::string_view& s) { std::wstring result; - wchar_t * wcstr = utf8_to_widechar(s.c_str()); + wchar_t * wcstr = utf8_to_widechar(s.data()); if (wcstr != nullptr) { result = std::wstring(wcstr); @@ -647,12 +647,53 @@ namespace String #endif } - std::string ToUpper(const utf8 * src) + std::string ToUpper(const std::string_view& src) { #ifdef _WIN32 - // TODO: LCMapStringEx on Windows. - STUB(); - return String::ToStd(src); + auto srcW = ToUtf16(src); + auto dstW = std::wstring(); + + // Keep doubling the buffer size until transformed string fits (max 10 times) + size_t bufferLength = src.size(); + for (size_t i = 0; i < 10; i++) + { + // Double buffer size + bufferLength *= 2; + dstW.resize(bufferLength); + + // Transform the string + auto result = LCMapStringEx( + LOCALE_NAME_USER_DEFAULT, + LCMAP_UPPERCASE | LCMAP_LINGUISTIC_CASING, + srcW.c_str(), + (int)srcW.length(), + dstW.data(), + (int)dstW.capacity(), + nullptr, + nullptr, + 0); + if (result == 0) + { + // Check the error + auto error = GetLastError(); + if (error == ERROR_INSUFFICIENT_BUFFER) + { + continue; + } + else + { + log_warning("LCMapStringEx failed with %d", error); + return std::string(src); + } + } + else + { + dstW.resize(result); + return String::ToUtf8(dstW); + } + } + log_warning("LCMapStringEx loop exceeded"); + return std::string(src); #else icu::UnicodeString str = icu::UnicodeString::fromUTF8(src); str.toUpper(); diff --git a/src/openrct2/core/String.hpp b/src/openrct2/core/String.hpp index 1d0f463ede..8d910b6f4c 100644 --- a/src/openrct2/core/String.hpp +++ b/src/openrct2/core/String.hpp @@ -43,7 +43,7 @@ namespace String std::string StdFormat_VA(const utf8 * format, va_list args); std::string StdFormat(const utf8 * format, ...); std::string ToUtf8(const std::wstring &s); - std::wstring ToUtf16(const std::string &s); + std::wstring ToUtf16(const std::string_view& s); bool IsNullOrEmpty(const utf8 * str); sint32 Compare(const std::string &a, const std::string &b, bool ignoreCase = false); @@ -115,5 +115,5 @@ namespace String /** * Returns an uppercased version of a UTF-8 string. */ - std::string ToUpper(const utf8 * src); + std::string ToUpper(const std::string_view& src); }