diff options
-rw-r--r-- | win32/ScintillaWin.cxx | 122 |
1 files changed, 64 insertions, 58 deletions
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index c0b6fb3e2..909964797 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -721,20 +721,38 @@ bool BoundsContains(PRectangle rcBounds, HRGN hRgnBounds, PRectangle rcCheck) { return contains; } +// Simplify calling WideCharToMultiByte and MultiByteToWideChar by providing default parameters and using string view. + +int MultiByteFromWideChar(UINT codePage, std::wstring_view wsv, LPSTR lpMultiByteStr, ptrdiff_t cbMultiByte) { + return ::WideCharToMultiByte(codePage, 0, wsv.data(), static_cast<int>(wsv.length()), lpMultiByteStr, static_cast<int>(cbMultiByte), nullptr, nullptr); +} + +int MultiByteLenFromWideChar(UINT codePage, std::wstring_view wsv) { + return MultiByteFromWideChar(codePage, wsv, nullptr, 0); +} + +int WideCharFromMultiByte(UINT codePage, std::string_view sv, LPWSTR lpWideCharStr, ptrdiff_t cchWideChar) { + return ::MultiByteToWideChar(codePage, 0, sv.data(), static_cast<int>(sv.length()), lpWideCharStr, static_cast<int>(cchWideChar)); +} + +int WideCharLenFromMultiByte(UINT codePage, std::string_view sv) { + return WideCharFromMultiByte(codePage, sv, nullptr, 0); +} + 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; + const int cchMulti = s.length() ? MultiByteLenFromWideChar(codePage, s) : 0; std::string sMulti(cchMulti, 0); if (cchMulti) { - ::WideCharToMultiByte(codePage, 0, s.c_str(), static_cast<int>(s.size()), &sMulti[0], cchMulti, NULL, NULL); + MultiByteFromWideChar(codePage, s, &sMulti[0], cchMulti); } return sMulti; } 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; + const int cchWide = s.length() ? WideCharLenFromMultiByte(codePage, s) : 0; std::wstring sWide(cchWide, 0); if (cchWide) { - ::MultiByteToWideChar(codePage, 0, s.c_str(), static_cast<int>(s.length()), &sWide[0], cchWide); + WideCharFromMultiByte(codePage, s, &sWide[0], cchWide); } return sWide; } @@ -764,9 +782,9 @@ Sci::Position ScintillaWin::TargetAsUTF8(char *text) const { // Need to convert 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); + const int utf8Len = MultiByteLenFromWideChar(CP_UTF8, characters); if (text) { - ::WideCharToMultiByte(CP_UTF8, 0, characters.c_str(), static_cast<int>(characters.length()), text, utf8Len, 0, 0); + MultiByteFromWideChar(CP_UTF8, characters, text, utf8Len); text[utf8Len] = '\0'; } return utf8Len; @@ -785,14 +803,14 @@ Sci::Position ScintillaWin::EncodedFromUTF8(const char *utf8, char *encoded) con return inputLength; } else { // Need to convert - const int charsLen = ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast<int>(inputLength), NULL, 0); - std::wstring characters(charsLen, '\0'); - ::MultiByteToWideChar(CP_UTF8, 0, utf8, static_cast<int>(inputLength), &characters[0], charsLen); + std::string_view utf8Input(utf8, inputLength); + const int charsLen = WideCharLenFromMultiByte(CP_UTF8, utf8Input); + std::wstring characters(charsLen, L'\0'); + WideCharFromMultiByte(CP_UTF8, utf8Input, &characters[0], charsLen); - const int encodedLen = ::WideCharToMultiByte(CodePageOfDocument(), - 0, &characters[0], charsLen, NULL, 0, 0, 0); + const int encodedLen = MultiByteLenFromWideChar(CodePageOfDocument(), characters); if (encoded) { - ::WideCharToMultiByte(CodePageOfDocument(), 0, &characters[0], charsLen, encoded, encodedLen, 0, 0); + MultiByteFromWideChar(CodePageOfDocument(), characters, encoded, encodedLen); encoded[encodedLen] = '\0'; } return encodedLen; @@ -812,8 +830,8 @@ void ScintillaWin::AddCharUTF16(wchar_t const *wcs, unsigned int wclen) { } else { const UINT cpDest = CodePageOfDocument(); char inBufferCP[maxLenInputIME * 2]; - const int size = ::WideCharToMultiByte(cpDest, - 0, wcs, wclen, inBufferCP, sizeof(inBufferCP) - 1, 0, 0); + const int size = MultiByteFromWideChar(cpDest, + std::wstring_view(wcs, wclen), inBufferCP, sizeof(inBufferCP) - 1); for (int i=0; i<size; i++) { AddChar(inBufferCP[i]); } @@ -1205,13 +1223,12 @@ UINT ScintillaWin::CodePageOfDocument() const { sptr_t ScintillaWin::GetTextLength() { if (pdoc->Length() == 0) return 0; - std::vector<char> docBytes(pdoc->Length(), '\0'); + std::string docBytes(pdoc->Length(), '\0'); pdoc->GetCharRange(&docBytes[0], 0, pdoc->Length()); if (IsUnicodeMode()) { return UTF16Length(std::string_view(&docBytes[0], docBytes.size())); } else { - return ::MultiByteToWideChar(CodePageOfDocument(), 0, &docBytes[0], - static_cast<int>(docBytes.size()), NULL, 0); + return WideCharLenFromMultiByte(CodePageOfDocument(), docBytes); } } @@ -1221,7 +1238,7 @@ sptr_t ScintillaWin::GetText(uptr_t wParam, sptr_t lParam) { *ptr = L'\0'; return 0; } - std::vector<char> docBytes(pdoc->Length(), '\0'); + std::string docBytes(pdoc->Length(), '\0'); pdoc->GetCharRange(&docBytes[0], 0, pdoc->Length()); if (IsUnicodeMode()) { const std::string_view sv(&docBytes[0], docBytes.size()); @@ -1238,13 +1255,10 @@ sptr_t ScintillaWin::GetText(uptr_t wParam, sptr_t lParam) { // Not Unicode mode // Convert to Unicode using the current Scintilla code page const UINT cpSrc = CodePageOfDocument(); - int lengthUTF16 = ::MultiByteToWideChar(cpSrc, 0, &docBytes[0], - static_cast<int>(docBytes.size()), NULL, 0); + int lengthUTF16 = WideCharLenFromMultiByte(cpSrc, docBytes); if (lengthUTF16 >= static_cast<int>(wParam)) lengthUTF16 = static_cast<int>(wParam)-1; - ::MultiByteToWideChar(cpSrc, 0, &docBytes[0], - static_cast<int>(docBytes.size()), - ptr, lengthUTF16); + WideCharFromMultiByte(cpSrc, docBytes, ptr, lengthUTF16); ptr[lengthUTF16] = L'\0'; return lengthUTF16; } @@ -2034,10 +2048,10 @@ public: if (lenMixed > utf16Mixed.size()) { utf16Mixed.resize(lenMixed + 8); } - const size_t nUtf16Mixed = ::MultiByteToWideChar(cp, 0, mixed, - static_cast<int>(lenMixed), + const size_t nUtf16Mixed = WideCharFromMultiByte(cp, + std::string_view(mixed, lenMixed), &utf16Mixed[0], - static_cast<int>(utf16Mixed.size())); + utf16Mixed.size()); if (nUtf16Mixed == 0) { // Failed to convert -> bad input @@ -2054,7 +2068,7 @@ public: // Maximum length of a case conversion is 6 bytes, 3 characters wchar_t wFolded[20]; const size_t charsConverted = UTF16FromUTF8(std::string_view(foldedUTF8), - wFolded, ELEMENTS(wFolded)); + wFolded, std::size(wFolded)); for (size_t j=0; j<charsConverted; j++) utf16Folded[lenFlat++] = wFolded[j]; } else { @@ -2062,14 +2076,11 @@ public: } } - const size_t lenOut = ::WideCharToMultiByte(cp, 0, - &utf16Folded[0], lenFlat, - NULL, 0, NULL, 0); + const std::wstring_view wsvFolded(&utf16Folded[0], lenFlat); + const size_t lenOut = MultiByteLenFromWideChar(cp, wsvFolded); if (lenOut < sizeFolded) { - ::WideCharToMultiByte(cp, 0, - &utf16Folded[0], lenFlat, - folded, static_cast<int>(lenOut), NULL, 0); + MultiByteFromWideChar(cp, wsvFolded, folded, lenOut); return lenOut; } else { return 0; @@ -2091,19 +2102,19 @@ CaseFolder *ScintillaWin::CaseFolderForEncoding() { char sCharacter[2] = "A"; sCharacter[0] = static_cast<char>(i); wchar_t wCharacter[20]; - const unsigned int lengthUTF16 = ::MultiByteToWideChar(cpDest, 0, sCharacter, 1, - wCharacter, ELEMENTS(wCharacter)); + const unsigned int lengthUTF16 = WideCharFromMultiByte(cpDest, sCharacter, + wCharacter, std::size(wCharacter)); if (lengthUTF16 == 1) { const char *caseFolded = CaseConvert(wCharacter[0], CaseConversionFold); if (caseFolded) { wchar_t wLower[20]; const size_t charsConverted = UTF16FromUTF8(std::string_view(caseFolded), - wLower, ELEMENTS(wLower)); + wLower, std::size(wLower)); if (charsConverted == 1) { char sCharacterLowered[20]; - const unsigned int lengthConverted = ::WideCharToMultiByte(cpDest, 0, - wLower, static_cast<int>(charsConverted), - sCharacterLowered, ELEMENTS(sCharacterLowered), NULL, 0); + const unsigned int lengthConverted = MultiByteFromWideChar(cpDest, + std::wstring_view(wLower, charsConverted), + sCharacterLowered, std::size(sCharacterLowered)); if ((lengthConverted == 1) && (sCharacter[0] != sCharacterLowered[0])) { pcf->SetTranslation(sCharacter[0], sCharacterLowered[0]); } @@ -2270,11 +2281,9 @@ void ScintillaWin::Paste() { // CF_UNICODETEXT available, but not in Unicode mode // Convert from Unicode to current Scintilla code page const UINT cpDest = CodePageOfDocument(); - len = ::WideCharToMultiByte(cpDest, 0, uptr, -1, - NULL, 0, NULL, NULL) - 1; // subtract 0 terminator - putf.resize(len + 1); - ::WideCharToMultiByte(cpDest, 0, uptr, -1, - &putf[0], static_cast<int>(len) + 1, NULL, NULL); + len = MultiByteLenFromWideChar(cpDest, uptr); + putf.resize(len); + MultiByteFromWideChar(cpDest, uptr, &putf[0], len); } InsertPasteShape(&putf[0], len, pasteShape); @@ -2298,8 +2307,8 @@ void ScintillaWin::Paste() { std::vector<wchar_t> uptr(len+1); const int ilen = static_cast<int>(len); - const size_t ulen = ::MultiByteToWideChar(CP_ACP, 0, - ptr, ilen, &uptr[0], ilen +1); + const size_t ulen = WideCharFromMultiByte(CP_ACP, + std::string_view(ptr, ilen), &uptr[0], ilen +1); const std::wstring_view wsv(&uptr[0], ulen); const size_t mlen = UTF8Length(wsv); @@ -2810,12 +2819,11 @@ void ScintillaWin::CopyToClipboard(const SelectionText &selectedText) { // Convert to Unicode using the current Scintilla code page const UINT cpSrc = CodePageFromCharSet( selectedText.characterSet, selectedText.codePage); - const int uLen = ::MultiByteToWideChar(cpSrc, 0, selectedText.Data(), - static_cast<int>(selectedText.LengthWithTerminator()), 0, 0); + const std::string_view svSelected(selectedText.Data(), selectedText.LengthWithTerminator()); + const int uLen = WideCharLenFromMultiByte(cpSrc, svSelected); uniText.Allocate(2 * uLen); if (uniText) { - ::MultiByteToWideChar(cpSrc, 0, selectedText.Data(), - static_cast<int>(selectedText.LengthWithTerminator()), + WideCharFromMultiByte(cpSrc, svSelected, static_cast<wchar_t *>(uniText.ptr), uLen); } } @@ -3105,7 +3113,7 @@ STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, // Convert UTF-16 to UTF-8 const std::wstring_view wsv(udata, tlen / 2); const size_t dataLen = UTF8Length(wsv); - data.resize(dataLen+1); + data.resize(dataLen); UTF8FromUTF16(wsv, &data[0], dataLen); } else { // Convert UTF-16 to ANSI @@ -3114,11 +3122,9 @@ STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, // CF_UNICODETEXT available, but not in Unicode mode // Convert from Unicode to current Scintilla code page const UINT cpDest = CodePageOfDocument(); - const int tlen = ::WideCharToMultiByte(cpDest, 0, udata, -1, - NULL, 0, NULL, NULL) - 1; // subtract 0 terminator - data.resize(tlen + 1); - ::WideCharToMultiByte(cpDest, 0, udata, -1, - &data[0], tlen + 1, NULL, NULL); + const int tlen = MultiByteLenFromWideChar(cpDest, udata); + data.resize(tlen); + MultiByteFromWideChar(cpDest, udata, &data[0], tlen); } } memUDrop.Unlock(); @@ -3129,7 +3135,7 @@ STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, GlobalMemory memDrop(medium.hGlobal); const char *cdata = static_cast<const char *>(memDrop.ptr); if (cdata) - data.assign(cdata, cdata+strlen(cdata)+1); + data.assign(cdata, cdata+strlen(cdata)); memDrop.Unlock(); } } @@ -3146,7 +3152,7 @@ STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, ::ScreenToClient(MainHWND(), &rpt); const SelectionPosition movePos = SPositionFromLocation(PointFromPOINT(rpt), false, false, UserVirtualSpace()); - DropAt(movePos, &data[0], data.size() - 1, *pdwEffect == DROPEFFECT_MOVE, hrRectangular == S_OK); + DropAt(movePos, &data[0], data.size(), *pdwEffect == DROPEFFECT_MOVE, hrRectangular == S_OK); // Free data if (medium.pUnkForRelease != NULL) |