aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2016-10-27 21:21:57 +1100
committerNeil <nyamatongwe@gmail.com>2016-10-27 21:21:57 +1100
commitc2b21668af643baedd2e90ad91f118e1442d7ac2 (patch)
tree11f35d4207634949e7ca8269c3160a28e1891ed7
parent9efd6f07a96d93e2c30d81a912814741acaa34ce (diff)
downloadscintilla-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.cxx8
-rw-r--r--src/CaseConvert.h3
-rw-r--r--win32/ScintillaWin.cxx100
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() {