diff options
author | Neil <nyamatongwe@gmail.com> | 2016-10-27 21:21:57 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2016-10-27 21:21:57 +1100 |
commit | c2b21668af643baedd2e90ad91f118e1442d7ac2 (patch) | |
tree | 11f35d4207634949e7ca8269c3160a28e1891ed7 | |
parent | 9efd6f07a96d93e2c30d81a912814741acaa34ce (diff) | |
download | scintilla-mirror-c2b21668af643baedd2e90ad91f118e1442d7ac2.tar.gz |
Tidy CaseMapString by moving some mechanics into CaseConvert. Use StringEncode
and StringDecode more and make more likely to be optimized.
-rw-r--r-- | src/CaseConvert.cxx | 8 | ||||
-rw-r--r-- | src/CaseConvert.h | 3 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 100 |
3 files changed, 53 insertions, 58 deletions
diff --git a/src/CaseConvert.cxx b/src/CaseConvert.cxx index 63a27222b..e84fbdab4 100644 --- a/src/CaseConvert.cxx +++ b/src/CaseConvert.cxx @@ -630,6 +630,14 @@ size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixe return pCaseConv->CaseConvertString(converted, sizeConverted, mixed, lenMixed); } +std::string CaseConvertString(const std::string &s, enum CaseConversion conversion) { + std::string retMapped(s.length() * maxExpansionCaseConversion, 0); + size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), + conversion); + retMapped.resize(lenMapped); + return retMapped; +} + #ifdef SCI_NAMESPACE } #endif diff --git a/src/CaseConvert.h b/src/CaseConvert.h index 60de22799..7a0100300 100644 --- a/src/CaseConvert.h +++ b/src/CaseConvert.h @@ -40,6 +40,9 @@ const int maxExpansionCaseConversion=3; // If there is not enough space then 0 is returned. size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, enum CaseConversion conversion); +// Converts a mixed case string using a particular conversion. +std::string CaseConvertString(const std::string &s, enum CaseConversion conversion); + #ifdef SCI_NAMESPACE } #endif diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index 931ccd816..f96ec7e6e 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -710,6 +710,35 @@ static bool BoundsContains(PRectangle rcBounds, HRGN hRgnBounds, PRectangle rcCh return contains; } +static std::string StringEncode(const std::wstring &s, int codePage) { + const int cchMulti = s.length() ? ::WideCharToMultiByte(codePage, 0, s.c_str(), static_cast<int>(s.length()), NULL, 0, NULL, NULL) : 0; + std::string sMulti(cchMulti, 0); + if (cchMulti) { + ::WideCharToMultiByte(codePage, 0, s.c_str(), static_cast<int>(s.size()), &sMulti[0], cchMulti, NULL, NULL); + } + return sMulti; +} + +static std::wstring StringDecode(const std::string &s, int codePage) { + const int cchWide = s.length() ? ::MultiByteToWideChar(codePage, 0, s.c_str(), static_cast<int>(s.length()), NULL, 0) : 0; + std::wstring sWide(cchWide, 0); + if (cchWide) { + ::MultiByteToWideChar(codePage, 0, s.c_str(), static_cast<int>(s.length()), &sWide[0], cchWide); + } + return sWide; +} + +static std::wstring StringMapCase(const std::wstring &ws, DWORD mapFlags) { + const int charsConverted = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, mapFlags, + ws.c_str(), static_cast<int>(ws.length()), NULL, 0); + std::wstring wsConverted(charsConverted, 0); + if (charsConverted) { + ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, mapFlags, + ws.c_str(), static_cast<int>(ws.length()), &wsConverted[0], charsConverted); + } + return wsConverted; +} + // Returns the target converted to UTF8. // Return the length in bytes. int ScintillaWin::TargetAsUTF8(char *text) { @@ -720,14 +749,11 @@ int ScintillaWin::TargetAsUTF8(char *text) { } } else { // Need to convert - std::string s = RangeText(targetStart, targetEnd); - int charsLen = ::MultiByteToWideChar(CodePageOfDocument(), 0, &s[0], targetLength, NULL, 0); - std::wstring characters(charsLen, '\0'); - ::MultiByteToWideChar(CodePageOfDocument(), 0, &s[0], targetLength, &characters[0], charsLen); - - int utf8Len = ::WideCharToMultiByte(CP_UTF8, 0, &characters[0], charsLen, NULL, 0, 0, 0); + const std::string s = RangeText(targetStart, targetEnd); + const std::wstring characters = StringDecode(s, CodePageOfDocument()); + const int utf8Len = ::WideCharToMultiByte(CP_UTF8, 0, characters.c_str(), static_cast<int>(characters.length()), NULL, 0, 0, 0); if (text) { - ::WideCharToMultiByte(CP_UTF8, 0, &characters[0], charsLen, text, utf8Len, 0, 0); + ::WideCharToMultiByte(CP_UTF8, 0, characters.c_str(), static_cast<int>(characters.length()), text, utf8Len, 0, 0); text[utf8Len] = '\0'; } return utf8Len; @@ -911,28 +937,6 @@ void ScintillaWin::SetCandidateWindowPos() { } } -static std::string StringEncode(std::wstring s, int codePage) { - if (s.length()) { - int cchMulti = ::WideCharToMultiByte(codePage, 0, s.c_str(), static_cast<int>(s.length()), NULL, 0, NULL, NULL); - std::string sMulti(cchMulti, 0); - ::WideCharToMultiByte(codePage, 0, s.c_str(), static_cast<int>(s.size()), &sMulti[0], cchMulti, NULL, NULL); - return sMulti; - } else { - return std::string(); - } -} - -static std::wstring StringDecode(std::string s, int codePage) { - if (s.length()) { - int cchWide = ::MultiByteToWideChar(codePage, 0, s.c_str(), static_cast<int>(s.length()), NULL, 0); - std::wstring sWide(cchWide, 0); - ::MultiByteToWideChar(codePage, 0, s.c_str(), static_cast<int>(s.length()), &sWide[0], cchWide); - return sWide; - } else { - return std::wstring(); - } -} - void ScintillaWin::SelectionToHangul() { // Convert every hanja to hangul within the main range. const int selStart = sel.RangeMain().Start().Position(); @@ -2101,44 +2105,24 @@ std::string ScintillaWin::CaseMapString(const std::string &s, int caseMapping) { if ((s.size() == 0) || (caseMapping == cmSame)) return s; - UINT cpDoc = CodePageOfDocument(); + const UINT cpDoc = CodePageOfDocument(); if (cpDoc == SC_CP_UTF8) { - std::string retMapped(s.length() * maxExpansionCaseConversion, 0); - size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), - (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); - retMapped.resize(lenMapped); - return retMapped; + return CaseConvertString(s, (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); } - unsigned int lengthUTF16 = ::MultiByteToWideChar(cpDoc, 0, s.c_str(), - static_cast<int>(s.size()), NULL, 0); - if (lengthUTF16 == 0) // Failed to convert - return s; + // Change text to UTF-16 + const std::wstring wsText = StringDecode(s, cpDoc); - DWORD mapFlags = LCMAP_LINGUISTIC_CASING | + const DWORD mapFlags = LCMAP_LINGUISTIC_CASING | ((caseMapping == cmUpper) ? LCMAP_UPPERCASE : LCMAP_LOWERCASE); - // Change text to UTF-16 - std::vector<wchar_t> vwcText(lengthUTF16); - ::MultiByteToWideChar(cpDoc, 0, s.c_str(), static_cast<int>(s.size()), &vwcText[0], lengthUTF16); - // Change case - int charsConverted = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, mapFlags, - &vwcText[0], lengthUTF16, NULL, 0); - std::vector<wchar_t> vwcConverted(charsConverted); - ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, mapFlags, - &vwcText[0], lengthUTF16, &vwcConverted[0], charsConverted); + const std::wstring wsConverted = StringMapCase(wsText, mapFlags); // Change back to document encoding - unsigned int lengthConverted = ::WideCharToMultiByte(cpDoc, 0, - &vwcConverted[0], static_cast<int>(vwcConverted.size()), - NULL, 0, NULL, 0); - std::vector<char> vcConverted(lengthConverted); - ::WideCharToMultiByte(cpDoc, 0, - &vwcConverted[0], static_cast<int>(vwcConverted.size()), - &vcConverted[0], static_cast<int>(vcConverted.size()), NULL, 0); - - return std::string(&vcConverted[0], vcConverted.size()); + std::string sConverted = StringEncode(wsConverted, cpDoc); + + return sConverted; } void ScintillaWin::Copy() { |