]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/string.cpp
Fixes needed to get transient popup windows working, also implement SetFont for OS...
[wxWidgets.git] / src / common / string.cpp
index 04a606a3c563b308768b9678347732562de43ac4..e07b7eea8f74554e9350b0a402b5977528296c34 100644 (file)
@@ -36,6 +36,7 @@
 #include <stdlib.h>
 
 #include "wx/hashmap.h"
+#include "wx/vector.h"
 
 // string handling functions used by wxString:
 #if wxUSE_UNICODE_UTF8
     #define wxStringStrlen   wxStrlen
 #endif
 
+// ----------------------------------------------------------------------------
+// global variables
+// ----------------------------------------------------------------------------
+
+namespace wxPrivate
+{
+
+static UntypedBufferData s_untypedNullData(NULL);
+
+UntypedBufferData * const untypedNullDataPtr = &s_untypedNullData;
+
+} // namespace wxPrivate
 
 // ---------------------------------------------------------------------------
 // static class variables definition
@@ -1103,6 +1116,7 @@ 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
 
     const_iterator i1 = begin();
@@ -1126,6 +1140,9 @@ 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
 }
 
 
@@ -1381,30 +1398,62 @@ size_t wxString::Replace(const wxString& strOld,
                 break;
         }
     }
-    else // general case
+    else if ( !bReplaceAll)
+    {
+        size_t pos = m_impl.find(strOld, 0);
+        if ( pos != npos )
+        {
+            m_impl.replace(pos, strOld.m_impl.length(), strNew.m_impl);
+            uiCount = 1;
+        }
+    }
+    else // replace all occurrences
     {
         const size_t uiOldLen = strOld.m_impl.length();
         const size_t uiNewLen = strNew.m_impl.length();
 
-        for ( size_t pos = 0; ; )
+        // first scan the string to find all positions at which the replacement
+        // should be made
+        wxVector<size_t> replacePositions;
+
+        size_t pos;
+        for ( pos = m_impl.find(strOld.m_impl, 0);
+              pos != npos;
+              pos = m_impl.find(strOld.m_impl, pos + uiOldLen))
         {
-            pos = m_impl.find(strOld.m_impl, pos);
-            if ( pos == npos )
-                break;
+            replacePositions.push_back(pos);
+            ++uiCount;
+        }
 
-            // replace this occurrence of the old string with the new one
-            m_impl.replace(pos, uiOldLen, strNew.m_impl);
+        if ( !uiCount )
+            return 0;
 
-            // move up pos past the string that was replaced
-            pos += uiNewLen;
+        // allocate enough memory for the whole new string
+        wxString tmp;
+        tmp.m_impl.reserve(m_impl.length() + uiCount*(uiNewLen - uiOldLen));
 
-            // increase replace count
-            uiCount++;
+        // copy this string to tmp doing replacements on the fly
+        size_t replNum = 0;
+        for ( pos = 0; replNum < uiCount; replNum++ )
+        {
+            const size_t nextReplPos = replacePositions[replNum];
 
-            // stop after the first one?
-            if ( !bReplaceAll )
-                break;
+            if ( pos != nextReplPos )
+            {
+                tmp.m_impl.append(m_impl, pos, nextReplPos - pos);
+            }
+
+            tmp.m_impl.append(strNew.m_impl);
+            pos = nextReplPos + uiOldLen;
         }
+
+        if ( pos != m_impl.length() )
+        {
+            // append the rest of the string unchanged
+            tmp.m_impl.append(m_impl, pos, m_impl.length() - pos);
+        }
+
+        swap(tmp);
     }
 
     return uiCount;
@@ -2097,47 +2146,3 @@ int wxString::Freq(wxUniChar ch) const
     return count;
 }
 
-// ----------------------------------------------------------------------------
-// wxUTF8StringBuffer
-// ----------------------------------------------------------------------------
-
-#if wxUSE_UNICODE_WCHAR
-wxUTF8StringBuffer::~wxUTF8StringBuffer()
-{
-    wxMBConvStrictUTF8 conv;
-    size_t wlen = conv.ToWChar(NULL, 0, m_buf);
-    wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
-
-    wxStringInternalBuffer wbuf(m_str, wlen);
-    conv.ToWChar(wbuf, wlen, m_buf);
-}
-
-wxUTF8StringBufferLength::~wxUTF8StringBufferLength()
-{
-    wxCHECK_RET(m_lenSet, "length not set");
-
-    wxMBConvStrictUTF8 conv;
-    size_t wlen = conv.ToWChar(NULL, 0, m_buf, m_len);
-    wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" );
-
-    wxStringInternalBufferLength wbuf(m_str, wlen);
-    conv.ToWChar(wbuf, wlen, m_buf, m_len);
-    wbuf.SetLength(wlen);
-}
-#endif // wxUSE_UNICODE_WCHAR
-
-// ----------------------------------------------------------------------------
-// wxCharBufferType<T>
-// ----------------------------------------------------------------------------
-
-#ifndef __VMS_BROKEN_TEMPLATES
-template<>
-#endif
-wxCharTypeBuffer<char>::Data
-wxCharTypeBuffer<char>::NullData(NULL);
-
-#ifndef __VMS_BROKEN_TEMPLATES
-template<>
-#endif
-wxCharTypeBuffer<wchar_t>::Data
-wxCharTypeBuffer<wchar_t>::NullData(NULL);