mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-22 02:39:05 +02:00
Merge pull request #12747 from hrydgard/input-encoding-cleanup
Input encoding cleanup
This commit is contained in:
9 files changed
+186
-90
No files matched your search
@@ -117,6 +117,19 @@ void PointerWrap::Do(std::wstring &x) {
|
||||
(*ptr) += stringLen;
|
||||
}
|
||||
|
||||
void PointerWrap::Do(std::u16string &x) {
|
||||
int stringLen = sizeof(char16_t) * ((int)x.length() + 1);
|
||||
Do(stringLen);
|
||||
|
||||
switch (mode) {
|
||||
case MODE_READ: x = (char16_t*)*ptr; break;
|
||||
case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break;
|
||||
case MODE_MEASURE: break;
|
||||
case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (char16_t*)*ptr, "Savestate verification failure: (at %p).\n", x.c_str()); break;
|
||||
}
|
||||
(*ptr) += stringLen;
|
||||
}
|
||||
|
||||
struct standard_tm {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
|
||||
+2
-1
@@ -459,7 +459,8 @@ public:
|
||||
|
||||
// Store strings.
|
||||
void Do(std::string &x);
|
||||
void Do(std::wstring &x);
|
||||
void Do(std::wstring &x); // DEPRECATED, do not save wstrings
|
||||
void Do(std::u16string &x);
|
||||
|
||||
void Do(tm &t);
|
||||
|
||||
|
||||
+2
-2
@@ -122,7 +122,7 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char *
|
||||
#if MAX_LOGLEVEL >= DEBUG_LEVEL
|
||||
#define _dbg_assert_(_t_, _a_) \
|
||||
if (!(_a_)) {\
|
||||
ERROR_LOG(_t_, "Error...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \
|
||||
ERROR_LOG(_t_, #_a_ ## "\n\nError...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \
|
||||
__LINE__, __FILE__); \
|
||||
if (!PanicYesNo("*** Assertion ***\n")) { Crash(); } \
|
||||
}
|
||||
@@ -184,4 +184,4 @@ void AndroidAssertLog(const char *func, const char *file, int line, const char *
|
||||
Crash(); \
|
||||
}
|
||||
|
||||
#endif // __ANDROID__
|
||||
#endif // __ANDROID__
|
||||
@@ -71,73 +71,73 @@ const int kor_lconsCom[] = {18,0,2,21,3,4,26,3,5,0,7,8,15,7,9,16,7,10,18,7,11,24
|
||||
// Korean (Hangul) last consonant Separation key
|
||||
const int kor_lconsSpr[] = {2,1,9,4,4,12,5,4,18,8,8,0,9,8,6,10,8,7,11,8,9,12,8,16,13,8,17,14,8,18,17,17,9};
|
||||
|
||||
static const wchar_t oskKeys[OSK_KEYBOARD_COUNT][5][14] =
|
||||
static const char16_t oskKeys[OSK_KEYBOARD_COUNT][5][14] =
|
||||
{
|
||||
{
|
||||
// Latin Lowercase
|
||||
{L"1234567890-+"},
|
||||
{L"qwertyuiop[]"},
|
||||
{L"asdfghjkl;@~"},
|
||||
{L"zxcvbnm,./?\\"},
|
||||
{u"1234567890-+"},
|
||||
{u"qwertyuiop[]"},
|
||||
{u"asdfghjkl;@~"},
|
||||
{u"zxcvbnm,./?\\"},
|
||||
},
|
||||
{
|
||||
// Latin Uppercase
|
||||
{L"!@#$%^&*()_+"},
|
||||
{L"QWERTYUIOP{}"},
|
||||
{L"ASDFGHJKL:\"`"},
|
||||
{L"ZXCVBNM<>/?|"},
|
||||
{u"!@#$%^&*()_+"},
|
||||
{u"QWERTYUIOP{}"},
|
||||
{u"ASDFGHJKL:\"`"},
|
||||
{u"ZXCVBNM<>/?|"},
|
||||
},
|
||||
{
|
||||
// Hiragana
|
||||
{L"あかさたなはまやらわぁゃっ"},
|
||||
{L"いきしちにひみ り ぃ "},
|
||||
{L"うくすつぬふむゆるをぅゅ゛"},
|
||||
{L"えけせてねへめ れ ぇ ゜"},
|
||||
{L"おこそとのほもよろんぉょー"},
|
||||
{u"あかさたなはまやらわぁゃっ"},
|
||||
{u"いきしちにひみ り ぃ "},
|
||||
{u"うくすつぬふむゆるをぅゅ゛"},
|
||||
{u"えけせてねへめ れ ぇ ゜"},
|
||||
{u"おこそとのほもよろんぉょー"},
|
||||
},
|
||||
{
|
||||
// Katakana
|
||||
{L"アカサタナハマヤラワァャッ"},
|
||||
{L"イキシチニヒミ リ ィ "},
|
||||
{L"ウクスツヌフムユルヲゥュ゛"},
|
||||
{L"エケセテネヘメ レ ェ ゜"},
|
||||
{L"オコソトノホモヨロンォョー"},
|
||||
{u"アカサタナハマヤラワァャッ"},
|
||||
{u"イキシチニヒミ リ ィ "},
|
||||
{u"ウクスツヌフムユルヲゥュ゛"},
|
||||
{u"エケセテネヘメ レ ェ ゜"},
|
||||
{u"オコソトノホモヨロンォョー"},
|
||||
},
|
||||
{
|
||||
// Korean(Hangul)
|
||||
{L"1234567890-+"},
|
||||
{L"ㅃㅉㄸㄲㅆ!@#$%^&"},
|
||||
{L"ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔ[]"},
|
||||
{L"ㅁㄴㅇㄹㅎㅗㅓㅏㅣ;@~"},
|
||||
{L"ㅋㅌㅊㅍㅠㅜㅡ<>/?|"},
|
||||
{u"1234567890-+"},
|
||||
{u"ㅃㅉㄸㄲㅆ!@#$%^&"},
|
||||
{u"ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔ[]"},
|
||||
{u"ㅁㄴㅇㄹㅎㅗㅓㅏㅣ;@~"},
|
||||
{u"ㅋㅌㅊㅍㅠㅜㅡ<>/?|"},
|
||||
},
|
||||
{
|
||||
// Russian Lowercase
|
||||
{L"1234567890-+"},
|
||||
{L"йцукенгшщзхъ"},
|
||||
{L"фывапролджэё"},
|
||||
{L"ячсмитьбю/?|"},
|
||||
{u"1234567890-+"},
|
||||
{u"йцукенгшщзхъ"},
|
||||
{u"фывапролджэё"},
|
||||
{u"ячсмитьбю/?|"},
|
||||
},
|
||||
{
|
||||
// Russian Uppercase
|
||||
{L"!@#$%^&*()_+"},
|
||||
{L"ЙЦУКЕНГШЩЗХЪ"},
|
||||
{L"ФЫВАПРОЛДЖЭЁ"},
|
||||
{L"ЯЧСМИТЬБЮ/?|"},
|
||||
{u"!@#$%^&*()_+"},
|
||||
{u"ЙЦУКЕНГШЩЗХЪ"},
|
||||
{u"ФЫВАПРОЛДЖЭЁ"},
|
||||
{u"ЯЧСМИТЬБЮ/?|"},
|
||||
},
|
||||
{
|
||||
// Latin Full-width Lowercase
|
||||
{ L"1234567890-+" },
|
||||
{ L"qwertyuiop[]" },
|
||||
{ L"asdfghjkl;@~" },
|
||||
{ L"zxcvbnm,./?¥¥" },
|
||||
{ u"1234567890-+" },
|
||||
{ u"qwertyuiop[]" },
|
||||
{ u"asdfghjkl;@~" },
|
||||
{ u"zxcvbnm,./?¥¥" },
|
||||
},
|
||||
{
|
||||
// Latin Full-width Uppercase
|
||||
{ L"!@#$%^&*()_+" },
|
||||
{ L"QWERTYUIOP{}" },
|
||||
{ L"ASDFGHJKL:¥”‘" },
|
||||
{ L"ZXCVBNM<>/?|" },
|
||||
{ u"!@#$%^&*()_+" },
|
||||
{ u"QWERTYUIOP{}" },
|
||||
{ u"ASDFGHJKL:¥”‘" },
|
||||
{ u"ZXCVBNM<>/?|" },
|
||||
},
|
||||
};
|
||||
|
||||
@@ -167,7 +167,7 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_
|
||||
{
|
||||
if (!em_address.IsValid())
|
||||
{
|
||||
_string = "";
|
||||
_string.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -194,17 +194,17 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_
|
||||
_string = stringBuffer;
|
||||
}
|
||||
|
||||
void GetWideStringFromPSPPointer(std::wstring& _string, const PSPPointer<u16_le>& em_address)
|
||||
void GetWideStringFromPSPPointer(std::u16string& _string, const PSPPointer<u16_le>& em_address)
|
||||
{
|
||||
if (!em_address.IsValid())
|
||||
{
|
||||
_string = L"";
|
||||
_string.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t maxLength = 2047;
|
||||
wchar_t stringBuffer[maxLength + 1];
|
||||
wchar_t *string = stringBuffer;
|
||||
char16_t stringBuffer[maxLength + 1];
|
||||
char16_t *string = stringBuffer;
|
||||
|
||||
u16_le *input = &em_address[0];
|
||||
int c;
|
||||
@@ -214,7 +214,7 @@ void GetWideStringFromPSPPointer(std::wstring& _string, const PSPPointer<u16_le>
|
||||
_string = stringBuffer;
|
||||
}
|
||||
|
||||
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input)
|
||||
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const char16_t *input)
|
||||
{
|
||||
char stringBuffer[2048];
|
||||
char *string = stringBuffer;
|
||||
@@ -315,7 +315,7 @@ int PSPOskDialog::Init(u32 oskPtr) {
|
||||
|
||||
i_level = 0;
|
||||
|
||||
inputChars = L"";
|
||||
inputChars.clear();
|
||||
|
||||
if (oskParams->fields[0].intext.IsValid()) {
|
||||
auto src = oskParams->fields[0].intext;
|
||||
@@ -336,9 +336,9 @@ int PSPOskDialog::Init(u32 oskPtr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::wstring PSPOskDialog::CombinationKorean(bool isInput)
|
||||
std::u16string PSPOskDialog::CombinationKorean(bool isInput)
|
||||
{
|
||||
std::wstring string;
|
||||
std::u16string string;
|
||||
|
||||
isCombinated = true;
|
||||
|
||||
@@ -578,9 +578,9 @@ std::wstring PSPOskDialog::CombinationKorean(bool isInput)
|
||||
return string;
|
||||
}
|
||||
|
||||
std::wstring PSPOskDialog::CombinationString(bool isInput)
|
||||
std::u16string PSPOskDialog::CombinationString(bool isInput)
|
||||
{
|
||||
std::wstring string;
|
||||
std::u16string string;
|
||||
|
||||
isCombinated = false;
|
||||
|
||||
@@ -752,7 +752,7 @@ void PSPOskDialog::RenderKeyboard()
|
||||
int selectedRow = selectedChar / numKeyCols[currentKeyboard];
|
||||
int selectedCol = selectedChar % numKeyCols[currentKeyboard];
|
||||
|
||||
wchar_t temp[2];
|
||||
char16_t temp[2];
|
||||
temp[1] = '\0';
|
||||
|
||||
std::string buffer;
|
||||
@@ -769,7 +769,7 @@ void PSPOskDialog::RenderKeyboard()
|
||||
|
||||
PPGeDrawText(oskDesc.c_str(), title , 20, PPGE_ALIGN_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF));
|
||||
|
||||
std::wstring result;
|
||||
std::u16string result;
|
||||
|
||||
result = CombinationString(false);
|
||||
|
||||
@@ -855,16 +855,17 @@ int PSPOskDialog::NativeKeyboard() {
|
||||
}
|
||||
|
||||
if (beginInputBox) {
|
||||
std::wstring titleText;
|
||||
std::u16string titleText;
|
||||
GetWideStringFromPSPPointer(titleText, oskParams->fields[0].desc);
|
||||
|
||||
std::wstring defaultText;
|
||||
std::u16string defaultText;
|
||||
GetWideStringFromPSPPointer(defaultText, oskParams->fields[0].intext);
|
||||
|
||||
if (defaultText.empty())
|
||||
defaultText.assign(L"VALUE");
|
||||
defaultText.assign(u"VALUE");
|
||||
|
||||
System_InputBoxGetString(ConvertWStringToUTF8(titleText), ConvertWStringToUTF8(defaultText), [&](bool result, const std::string &value) {
|
||||
// There's already ConvertUCS2ToUTF8 in this file. Should we use that instead of the global ones?
|
||||
System_InputBoxGetString(::ConvertUCS2ToUTF8(titleText), ::ConvertUCS2ToUTF8(defaultText), [&](bool result, const std::string &value) {
|
||||
std::lock_guard<std::mutex> guard(nativeMutex_);
|
||||
if (nativeStatus_ != PSPOskNativeStatus::WAITING) {
|
||||
return;
|
||||
@@ -874,7 +875,7 @@ int PSPOskDialog::NativeKeyboard() {
|
||||
nativeStatus_ = result ? PSPOskNativeStatus::SUCCESS : PSPOskNativeStatus::FAILURE;
|
||||
});
|
||||
} else if (nativeStatus_ == PSPOskNativeStatus::SUCCESS) {
|
||||
inputChars = ConvertUTF8ToWString(nativeValue_);
|
||||
inputChars = ConvertUTF8ToUCS2(nativeValue_);
|
||||
nativeValue_.clear();
|
||||
|
||||
u32 maxLength = FieldMaxLength();
|
||||
@@ -1080,9 +1081,9 @@ int PSPOskDialog::Update(int animSpeed) {
|
||||
} else if (IsButtonPressed(CTRL_SQUARE) && inputChars.size() < FieldMaxLength()) {
|
||||
// Use a regular space if the current keyboard isn't Japanese nor full-width English
|
||||
if (currentKeyboardLanguage != OSK_LANGUAGE_JAPANESE && currentKeyboardLanguage != OSK_LANGUAGE_ENGLISH_FW)
|
||||
inputChars += L" ";
|
||||
inputChars += u" ";
|
||||
else
|
||||
inputChars += L" ";
|
||||
inputChars += u" ";
|
||||
}
|
||||
|
||||
EndDraw();
|
||||
@@ -1123,7 +1124,7 @@ void PSPOskDialog::DoState(PointerWrap &p)
|
||||
{
|
||||
PSPDialog::DoState(p);
|
||||
|
||||
auto s = p.Section("PSPOskDialog", 1);
|
||||
auto s = p.Section("PSPOskDialog", 2);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
@@ -1132,7 +1133,13 @@ void PSPOskDialog::DoState(PointerWrap &p)
|
||||
p.Do(oskIntext);
|
||||
p.Do(oskOuttext);
|
||||
p.Do(selectedChar);
|
||||
p.Do(inputChars);
|
||||
if (s >= 2) {
|
||||
p.Do(inputChars);
|
||||
} else {
|
||||
// Discard the wstring.
|
||||
std::wstring wstr;
|
||||
p.Do(wstr);
|
||||
}
|
||||
// Don't need to save state native status or value.
|
||||
}
|
||||
|
||||
|
||||
@@ -229,12 +229,12 @@ protected:
|
||||
|
||||
private:
|
||||
void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_le>& em_address);
|
||||
void ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input);
|
||||
void ConvertUCS2ToUTF8(std::string& _string, const char16_t *input);
|
||||
void RenderKeyboard();
|
||||
int NativeKeyboard();
|
||||
|
||||
std::wstring CombinationString(bool isInput); // for Japanese, Korean
|
||||
std::wstring CombinationKorean(bool isInput); // for Korea
|
||||
std::u16string CombinationString(bool isInput); // for Japanese, Korean
|
||||
std::u16string CombinationKorean(bool isInput); // for Korea
|
||||
void RemoveKorean(); // for Korean character removal
|
||||
|
||||
u32 FieldMaxLength();
|
||||
@@ -246,7 +246,7 @@ private:
|
||||
std::string oskOuttext;
|
||||
|
||||
int selectedChar;
|
||||
std::wstring inputChars;
|
||||
std::u16string inputChars;
|
||||
OskKeyboardDisplay currentKeyboard;
|
||||
OskKeyboardLanguage currentKeyboardLanguage;
|
||||
bool isCombinated;
|
||||
|
||||
+2
-2
@@ -28,9 +28,9 @@
|
||||
#include "Core/Reporting.h"
|
||||
|
||||
typedef PSPPointer<char> PSPCharPointer;
|
||||
typedef PSPPointer<u16> PSPWCharPointer;
|
||||
typedef PSPPointer<char16_t> PSPWCharPointer;
|
||||
typedef PSPPointer<const char> PSPConstCharPointer;
|
||||
typedef PSPPointer<const u16> PSPConstWCharPointer;
|
||||
typedef PSPPointer<const char16_t> PSPConstWCharPointer;
|
||||
|
||||
static u16 errorUTF8;
|
||||
static u16 errorUTF16;
|
||||
|
||||
@@ -17,12 +17,12 @@ uint16_t UTF16_Swap(uint16_t u) {
|
||||
template <bool is_little>
|
||||
struct UTF16_Type {
|
||||
public:
|
||||
static const uint32_t INVALID = (uint32_t)-1;
|
||||
static const char32_t INVALID = (char32_t)-1;
|
||||
|
||||
UTF16_Type(const uint16_t *c) : c_(c), index_(0) {}
|
||||
UTF16_Type(const char16_t *c) : c_(c), index_(0) {}
|
||||
|
||||
uint32_t next() {
|
||||
const uint32_t u = UTF16_Swap<is_little>(c_[index_++]);
|
||||
char32_t next() {
|
||||
const char32_t u = UTF16_Swap<is_little>(c_[index_++]);
|
||||
|
||||
// Surrogate pair. UTF-16 is so simple. We assume it's valid.
|
||||
if ((u & 0xF800) == 0xD800) {
|
||||
@@ -46,19 +46,29 @@ public:
|
||||
return index_;
|
||||
}
|
||||
|
||||
static int encode(uint16_t *dest, uint32_t u) {
|
||||
static int encode(char16_t *dest, char32_t u) {
|
||||
if (u >= 0x10000) {
|
||||
u -= 0x10000;
|
||||
*dest++ = UTF16_Swap<is_little>(0xD800 + ((u >> 10) & 0x3FF));
|
||||
*dest = UTF16_Swap<is_little>(0xDC00 + ((u >> 0) & 0x3FF));
|
||||
return 2;
|
||||
} else {
|
||||
*dest = UTF16_Swap<is_little>((uint16_t)u);
|
||||
*dest = UTF16_Swap<is_little>((char16_t)u);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int encodeUnits(uint32_t u) {
|
||||
// Rejects non-UCS2 codepoints.
|
||||
static int encodeUCS2(char16_t *dest, char32_t u) {
|
||||
if (u >= 0x10000 || (u >= 0xD800 && u <= 0xDFFF)) {
|
||||
return 0;
|
||||
} else {
|
||||
*dest = UTF16_Swap<is_little>((char16_t)u);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int encodeUnits(char32_t u) {
|
||||
if (u >= 0x10000) {
|
||||
return 2;
|
||||
} else {
|
||||
@@ -66,8 +76,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static int encodeUnitsUCS2(char32_t u) {
|
||||
if (u >= 0x10000 || (u >= 0xD800 && u <= 0xDFFF)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
private:
|
||||
const uint16_t *c_;
|
||||
const char16_t *c_;
|
||||
int index_;
|
||||
};
|
||||
|
||||
|
||||
@@ -461,7 +461,63 @@ std::wstring ConvertUTF8ToWString(const std::string &source) {
|
||||
return str;
|
||||
}
|
||||
|
||||
#else
|
||||
#endif
|
||||
|
||||
std::string ConvertUCS2ToUTF8(const std::u16string &wstr) {
|
||||
std::string s;
|
||||
// Worst case.
|
||||
s.resize(wstr.size() * 4);
|
||||
|
||||
size_t pos = 0;
|
||||
for (wchar_t c : wstr) {
|
||||
pos += UTF8::encode(&s[pos], c);
|
||||
}
|
||||
|
||||
s.resize(pos);
|
||||
return s;
|
||||
}
|
||||
|
||||
static size_t ConvertUTF8ToUCS2Internal(char16_t *dest, size_t destSize, const std::string &source) {
|
||||
const char16_t *const orig = dest;
|
||||
const char16_t *const destEnd = dest + destSize;
|
||||
|
||||
UTF8 utf(source.c_str());
|
||||
|
||||
char16_t *destw = (char16_t *)dest;
|
||||
const char16_t *const destwEnd = destw + destSize;
|
||||
|
||||
// Ignores characters outside the BMP.
|
||||
while (uint32_t c = utf.next()) {
|
||||
if (destw + UTF16LE::encodeUnitsUCS2(c) >= destwEnd) {
|
||||
break;
|
||||
}
|
||||
destw += UTF16LE::encodeUCS2(destw, c);
|
||||
}
|
||||
|
||||
// No ++ to not count the terminal in length.
|
||||
if (dest < destEnd) {
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
return dest - orig;
|
||||
}
|
||||
|
||||
void ConvertUTF8ToUCS2(char16_t *dest, size_t destSize, const std::string &source) {
|
||||
ConvertUTF8ToUCS2Internal(dest, destSize, source);
|
||||
}
|
||||
|
||||
std::u16string ConvertUTF8ToUCS2(const std::string &source) {
|
||||
std::u16string 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 = ConvertUTF8ToUCS2Internal(&dst[0], source.size() + 1, source);
|
||||
dst.resize(realLen);
|
||||
return dst;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
// Replacements for the Win32 wstring functions. Not to be used from emulation code!
|
||||
|
||||
std::string ConvertWStringToUTF8(const std::wstring &wstr) {
|
||||
std::string s;
|
||||
@@ -484,16 +540,16 @@ static size_t ConvertUTF8ToWStringInternal(wchar_t *dest, size_t destSize, const
|
||||
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()) {
|
||||
char16_t *destw = (char16_t *)dest;
|
||||
const char16_t *const destwEnd = destw + destSize;
|
||||
while (char32_t c = utf.next()) {
|
||||
if (destw + UTF16LE::encodeUnits(c) >= destwEnd) {
|
||||
break;
|
||||
}
|
||||
destw += UTF16LE::encode(destw, c);
|
||||
}
|
||||
} else {
|
||||
while (uint32_t c = utf.next()) {
|
||||
while (char32_t c = utf.next()) {
|
||||
if (dest + 1 >= destEnd) {
|
||||
break;
|
||||
}
|
||||
@@ -509,10 +565,6 @@ static size_t ConvertUTF8ToWStringInternal(wchar_t *dest, size_t destSize, const
|
||||
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.
|
||||
|
||||
@@ -82,13 +82,19 @@ 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);
|
||||
|
||||
#else
|
||||
|
||||
// Used by SymbolMap/assembler
|
||||
std::wstring ConvertUTF8ToWString(const std::string &source);
|
||||
std::string ConvertWStringToUTF8(const std::wstring &wstr);
|
||||
|
||||
#endif
|
||||
|
||||
std::string ConvertUCS2ToUTF8(const std::u16string &wstr);
|
||||
|
||||
// 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);
|
||||
void ConvertUTF8ToUCS2(char16_t *dest, size_t destSize, const std::string &source);
|
||||
std::u16string ConvertUTF8ToUCS2(const std::string &source);
|
||||
Reference in new issue
Block a user