From c178af7b8b00fa48dc9be25c833823de19fccc03 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Dec 2014 15:22:52 -0800 Subject: [PATCH] Add wchar conversion on non-Windows. --- util/text/utf8.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++ util/text/utf8.h | 6 ++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/util/text/utf8.cpp b/util/text/utf8.cpp index 5d5292e689..33e780d663 100644 --- a/util/text/utf8.cpp +++ b/util/text/utf8.cpp @@ -28,6 +28,7 @@ #include "base/basictypes.h" #include "utf8.h" +#include "utf16.h" // is start of UTF sequence inline bool isutf(char c) { @@ -460,4 +461,51 @@ std::wstring ConvertUTF8ToWString(const std::string &source) { return str; } +#else + +static size_t ConvertUTF8ToWStringInternal(wchar_t *dest, size_t destSize, const std::string &source) { + const wchar_t *const orig = dest; + const wchar_t *const destEnd = dest + destSize; + + UTF8 utf(source.c_str()); + + if (sizeof(wchar_t) == 2) { + uint16_t *destw = (uint16_t *)dest; + const uint16_t *const destwEnd = destw + destSize; + while (uint32_t c = utf.next()) { + if (destw + UTF16LE::encodeUnits(c) >= destwEnd) { + break; + } + destw += UTF16LE::encode(destw, c); + } + } else { + while (uint32_t c = utf.next()) { + if (dest + 1 >= destEnd) { + break; + } + *dest++ = c; + } + } + + // No ++ to not count the terminal in length. + if (dest < destEnd) { + *dest = 0; + } + + return dest - orig; +} + +void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source) { + ConvertUTF8ToWStringInternal(dest, destSize, source); +} + +std::wstring ConvertUTF8ToWString(const std::string &source) { + std::wstring dst; + // utf-8 won't be less bytes than there are characters. But need +1 for terminator. + dst.resize(source.size() + 1, 0); + size_t realLen = ConvertUTF8ToWStringInternal(&dst[0], source.size() + 1, source); + dst.resize(realLen); + return dst; +} + #endif diff --git a/util/text/utf8.h b/util/text/utf8.h index 83af37ee58..70dbf80b07 100644 --- a/util/text/utf8.h +++ b/util/text/utf8.h @@ -82,7 +82,9 @@ bool UTF8StringHasNonASCII(const char *utf8string); std::string ConvertWStringToUTF8(const std::wstring &wstr); std::string ConvertWStringToUTF8(const wchar_t *wstr); -void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source); -std::wstring ConvertUTF8ToWString(const std::string &source); #endif + +// Dest size in units, not bytes. +void ConvertUTF8ToWString(wchar_t *dest, size_t destSize, const std::string &source); +std::wstring ConvertUTF8ToWString(const std::string &source);