]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/string.cpp
compilation fix after r60017
[wxWidgets.git] / src / common / string.cpp
index 960b6d2d35f2ea044e75c6c4dfe9eab0b88788cd..762410411db990b4051118c8b6c6921f85093f1b 100644 (file)
@@ -24,6 +24,7 @@
 #ifndef WX_PRECOMP
     #include "wx/string.h"
     #include "wx/wxcrtvararg.h"
+    #include "wx/log.h"
 #endif
 
 #include <ctype.h>
 #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
@@ -59,7 +64,7 @@
 namespace wxPrivate
 {
 
-static UntypedBufferData s_untypedNullData(NULL);
+static UntypedBufferData s_untypedNullData(NULL, 0);
 
 UntypedBufferData * const untypedNullDataPtr = &s_untypedNullData;
 
@@ -499,7 +504,8 @@ 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*
     }
@@ -549,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
                                 );
 }
@@ -567,24 +581,13 @@ const wxScopedWCharBuffer wxString::wc_str() const
 const wxScopedCharBuffer wxString::mb_str(const wxMBConv& conv) const
 {
     if ( conv.IsUTF8() )
-        return wxScopedCharBuffer::CreateNonOwned(m_impl.c_str());
-
-    // FIXME-UTF8: use wc_str() here once we have buffers with length
+        return wxScopedCharBuffer::CreateNonOwned(m_impl.c_str(), m_impl.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
@@ -593,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
@@ -1120,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();
@@ -1144,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
 }