X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6df09f32fd0bbc2324a6a96683109e6c6cc47db5..aa113d87d7267a16b2d898a10f6b62e7b29359df:/src/common/string.cpp diff --git a/src/common/string.cpp b/src/common/string.cpp index b66d5bbeb0..762410411d 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -24,6 +24,7 @@ #ifndef WX_PRECOMP #include "wx/string.h" #include "wx/wxcrtvararg.h" + #include "wx/log.h" #endif #include @@ -39,6 +40,10 @@ #include "wx/vector.h" #include "wx/xlocale.h" +#ifdef __WXMSW__ + #include "wx/msw/wrapwin.h" +#endif // __WXMSW__ + // string handling functions used by wxString: #if wxUSE_UNICODE_UTF8 #define wxStringMemcpy memcpy @@ -499,7 +504,7 @@ wxString::SubstrBufFromMB wxString::ConvertStr(const char *psz, size_t nLength, // we must pass the real string length to SubstrBufFromMB ctor if ( nLength == npos ) nLength = psz ? strlen(psz) : 0; - return SubstrBufFromMB(wxCharBuffer::CreateNonOwned(psz, nLength), + return SubstrBufFromMB(wxScopedCharBuffer::CreateNonOwned(psz, nLength), nLength); } // else: do the roundtrip through wchar_t* @@ -550,17 +555,25 @@ wxString::SubstrBufFromWC wxString::ConvertStr(const wchar_t *pwz, size_t nLengt //Convert wxString in Unicode mode to a multi-byte string const wxScopedCharBuffer wxString::mb_str(const wxMBConv& conv) const { - return conv.cWC2MB(wx_str(), length() + 1 /* size, not length */, NULL); + // NB: Length passed to cWC2MB() doesn't include terminating NUL, it's + // added by it automatically. If we passed length()+1 here, it would + // create a buffer with 2 trailing NULs of length one greater than + // expected. + return conv.cWC2MB(wx_str(), length(), NULL); } #elif wxUSE_UNICODE_UTF8 const wxScopedWCharBuffer wxString::wc_str() const { + // NB: Length passed to cMB2WC() doesn't include terminating NUL, it's + // added by it automatically. If we passed length()+1 here, it would + // create a buffer with 2 trailing NULs of length one greater than + // expected. return wxMBConvStrictUTF8().cMB2WC ( m_impl.c_str(), - m_impl.length() + 1, // size, not length + m_impl.length(), NULL ); } @@ -570,22 +583,11 @@ const wxScopedCharBuffer wxString::mb_str(const wxMBConv& conv) const if ( conv.IsUTF8() ) return wxScopedCharBuffer::CreateNonOwned(m_impl.c_str(), m_impl.length()); - // FIXME-UTF8: use wc_str() here once we have buffers with length - - size_t wcLen; - wxScopedWCharBuffer wcBuf - ( - wxMBConvStrictUTF8().cMB2WC - ( - m_impl.c_str(), - m_impl.length() + 1, // size - &wcLen - ) - ); - if ( !wcLen ) + wxScopedWCharBuffer wcBuf(wc_str()); + if ( !wcBuf.length() ) return wxCharBuffer(""); - return conv.cWC2MB(wcBuf, wcLen+1, NULL); + return conv.cWC2MB(wcBuf.data(), wcBuf.length(), NULL); } #else // ANSI @@ -594,7 +596,11 @@ const wxScopedCharBuffer wxString::mb_str(const wxMBConv& conv) const //mode is not enabled and wxUSE_WCHAR_T is enabled const wxScopedWCharBuffer wxString::wc_str(const wxMBConv& conv) const { - return conv.cMB2WC(wx_str(), length() + 1 /* size, not length */, NULL); + // NB: Length passed to cMB2WC() doesn't include terminating NUL, it's + // added by it automatically. If we passed length()+1 here, it would + // create a buffer with 2 trailing NULs of length one greater than + // expected. + return conv.cMB2WC(wx_str(), length(), NULL); } #endif // Unicode/ANSI @@ -1121,9 +1127,36 @@ size_t wxString::find_last_not_of(const wxOtherCharType* sz, size_t nStart, int wxString::CmpNoCase(const wxString& s) const { -#if wxUSE_UNICODE_UTF8 - // FIXME-UTF8: use wxUniChar::ToLower/ToUpper once added +#if defined(__WXMSW__) && !wxUSE_UNICODE_UTF8 + // prefer to use CompareString() if available as it's more efficient than + // doing it manual or even using wxStricmp() (see #10375) + switch ( ::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, + m_impl.c_str(), m_impl.length(), + s.m_impl.c_str(), s.m_impl.length()) ) + { + case CSTR_LESS_THAN: + return -1; + case CSTR_EQUAL: + return 0; + + case CSTR_GREATER_THAN: + return 1; + + default: + wxFAIL_MSG( "unexpected CompareString() return value" ); + // fall through + + case 0: + wxLogLastError("CompareString"); + // use generic code below + } +#endif // __WXMSW__ && !wxUSE_UNICODE_UTF8 + + // do the comparison manually: notice that we can't use wxStricmp() as it + // doesn't handle embedded NULs + + // FIXME-UTF8: use wxUniChar::ToLower/ToUpper once added const_iterator i1 = begin(); const_iterator end1 = end(); const_iterator i2 = s.begin(); @@ -1145,9 +1178,6 @@ int wxString::CmpNoCase(const wxString& s) const else if ( len1 > len2 ) return 1; return 0; -#else // wxUSE_UNICODE_WCHAR or ANSI - return wxStricmp(m_impl.c_str(), s.m_impl.c_str()); -#endif }