]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/string.cpp
Added headers that didn't get installed.
[wxWidgets.git] / src / common / string.cpp
index e2563e5c824bc1bfc8e07aafc5443a0fbb827964..c43bde8e7d3271f93efc7c7e4d2fecdc1d62b5df 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     29/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
@@ -79,7 +79,7 @@ static const struct
 } g_strEmpty = { {-1, 0, 0}, wxT('\0') };
 
 // empty C style string: points to 'string data' byte of g_strEmpty
-extern const wxChar WXDLLEXPORT *wxEmptyString = &g_strEmpty.dummy;
+extern const wxChar WXDLLIMPEXP_BASE *wxEmptyString = &g_strEmpty.dummy;
 
 // ----------------------------------------------------------------------------
 // global functions
@@ -160,6 +160,18 @@ wxSTD ostream& operator<<(wxSTD ostream& os, const wxString& str)
   #define STATISTICS_ADD(av, val)
 #endif // WXSTRING_STATISTICS
 
+// ===========================================================================
+// wxStringData class deallocation
+// ===========================================================================
+
+#if defined(__VISUALC__) && defined(_MT) && !defined(_DLL)
+#  pragma message (__FILE__ ": building with Multithreaded non DLL runtime has a performance impact on wxString!")
+void wxStringData::Free()
+{
+    free(this);
+}
+#endif
+
 // ===========================================================================
 // wxString class core
 // ===========================================================================
@@ -229,24 +241,44 @@ wxString::wxString(const void *pStart, const void *pEnd)
 // from multibyte string
 wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength)
 {
-  // first get necessary size
-  size_t nLen = psz ? conv.MB2WC((wchar_t *) NULL, psz, 0) : 0;
-
-  // nLength is number of *Unicode* characters here!
-  if ((nLen != (size_t)-1) && (nLen > nLength))
-    nLen = nLength;
+    // first get the size of the buffer we need
+    size_t nLen;
+    if ( psz )
+    {
+        // calculate the needed size ourselves or use the provided one
+        nLen = nLength == wxSTRING_MAXLEN ? conv.MB2WC(NULL, psz, 0) : nLength;
+    }
+    else
+    {
+        // nothing to convert
+        nLen = 0;
+    }
 
-  // empty?
-  if ( (nLen != 0) && (nLen != (size_t)-1) ) {
-    if ( !AllocBuffer(nLen) ) {
-      wxFAIL_MSG( _T("out of memory in wxString::wxString") );
-      return;
+    // anything to do?
+    if ( (nLen != 0) && (nLen != (size_t)-1) )
+    {
+        if ( !AllocBuffer(nLen) )
+        {
+            wxFAIL_MSG( _T("out of memory in wxString::wxString") );
+        }
+        else
+        {
+            // MB2WC wants the buffer size, not the string length hence +1
+            nLen = conv.MB2WC(m_pchData, psz, nLen + 1);
+
+            if ( nLen != (size_t)-1 )
+            {
+                // initialized ok, set the real length as nLength specified by
+                // the caller could be greater than the real string length
+                GetStringData()->nDataLength = nLen;
+                m_pchData[nLen] = 0;
+                return;
+            }
+            //else: the conversion failed -- leave the string empty (what else?)
+        }
     }
-    conv.MB2WC(m_pchData, psz, nLen);
-  }
-  else {
+
     Init();
-  }
 }
 
 #else // ANSI
@@ -255,27 +287,39 @@ wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength)
 // from wide string
 wxString::wxString(const wchar_t *pwz, wxMBConv& conv, size_t nLength)
 {
-  // first get necessary size
-  size_t nLen = 0;
-  if (pwz)
-  {
-    if (nLength == wxSTRING_MAXLEN)
-      nLen = conv.WC2MB((char *) NULL, pwz, 0);
+    // first get the size of the buffer we need
+    size_t nLen;
+    if ( pwz )
+    {
+        // calculate the needed size ourselves or use the provided one
+        nLen = nLength == wxSTRING_MAXLEN ? conv.WC2MB(NULL, pwz, 0) : nLength;
+    }
     else
-      nLen = nLength;
-  }
+    {
+        // nothing to convert
+        nLen = 0;
+    }
 
-  // empty?
-  if ( (nLen != 0) && (nLen != (size_t)-1) ) {
-    if ( !AllocBuffer(nLen) ) {
-      wxFAIL_MSG( _T("out of memory in wxString::wxString") );
-      return;
+    // anything to do?
+    if ( (nLen != 0) && (nLen != (size_t)-1) )
+    {
+        if ( !AllocBuffer(nLen) )
+        {
+            wxFAIL_MSG( _T("out of memory in wxString::wxString") );
+        }
+        else
+        {
+            // WC2MB wants the buffer size, not the string length
+            if ( conv.WC2MB(m_pchData, pwz, nLen + 1) != (size_t)-1 )
+            {
+                // initialized ok
+                return;
+            }
+            //else: the conversion failed -- leave the string empty (what else?)
+        }
     }
-    conv.WC2MB(m_pchData, pwz, nLen);
-  }
-  else {
+
     Init();
-  }
 }
 #endif // wxUSE_WCHAR_T
 
@@ -583,7 +627,7 @@ wxString& wxString::operator=(const wchar_t *pwz)
 // ---------------------------------------------------------------------------
 
 // add something to this string
-bool wxString::ConcatSelf(int nSrcLen, const wxChar *pszSrcData)
+bool wxString::ConcatSelf(size_t nSrcLen, const wxChar *pszSrcData)
 {
   STATISTICS_ADD(SummandLength, nSrcLen);
 
@@ -730,6 +774,16 @@ wxString wxString::FromAscii(const char *ascii)
     return res;
 }
 
+wxString wxString::FromAscii(const char ascii)
+{
+    // What do we do with '\0' ?
+
+    wxString res;
+    res += (wchar_t)(unsigned char) ascii;
+
+    return res;
+}
+
 const wxCharBuffer wxString::ToAscii() const
 {
     // this will allocate enough space for the terminating NUL too
@@ -910,8 +964,13 @@ wxString wxString::AfterFirst(wxChar ch) const
 }
 
 // replace first (or all) occurences of some substring with another one
-size_t wxString::Replace(const wxChar *szOld, const wxChar *szNew, bool bReplaceAll)
+size_t
+wxString::Replace(const wxChar *szOld, const wxChar *szNew, bool bReplaceAll)
 {
+    // if we tried to replace an empty string we'd enter an infinite loop below
+    wxCHECK_MSG( szOld && *szOld && szNew, 0,
+                 _T("wxString::Replace(): invalid parameter") );
+
   size_t uiCount = 0;   // count of replacements made
 
   size_t uiOldLen = wxStrlen(szOld);
@@ -1700,6 +1759,10 @@ wxString& wxString::replace(size_t nStart, size_t nLen,
 // ArrayString
 // ============================================================================
 
+#include "wx/arrstr.h"
+
+#if !wxUSE_STL
+
 // size increment = min(50% of current size, ARRAY_MAXSIZE_INCREMENT)
 #define   ARRAY_MAXSIZE_INCREMENT       4096
 
@@ -1752,7 +1815,7 @@ void wxArrayString::Copy(const wxArrayString& src)
 void wxArrayString::Grow(size_t nIncrement)
 {
   // only do it if no more place
-  if ( m_nCount == m_nSize ) {
+  if ( (m_nSize - m_nCount) < nIncrement ) {
     // if ARRAY_DEFAULT_INITIAL_SIZE were set to 0, the initially empty would
     // be never resized!
     #if ARRAY_DEFAULT_INITIAL_SIZE == 0
@@ -1762,6 +1825,8 @@ void wxArrayString::Grow(size_t nIncrement)
     if ( m_nSize == 0 ) {
       // was empty, alloc some memory
       m_nSize = ARRAY_DEFAULT_INITIAL_SIZE;
+      if (m_nSize < nIncrement)
+          m_nSize = nIncrement;
       m_pItems = new wxChar *[m_nSize];
     }
     else {
@@ -1851,6 +1916,8 @@ void wxArrayString::Shrink()
   }
 }
 
+#if WXWIN_COMPATIBILITY_2_4
+
 // return a wxString[] as required for some control ctors.
 wxString* wxArrayString::GetStringArray() const
 {
@@ -1866,6 +1933,8 @@ wxString* wxArrayString::GetStringArray() const
     return array;
 }
 
+#endif // WXWIN_COMPATIBILITY_2_4
+
 // searches the array for an item (forward or backwards)
 int wxArrayString::Index(const wxChar *sz, bool bCase, bool bFromEnd) const
 {
@@ -1996,7 +2065,7 @@ void wxArrayString::SetCount(size_t count)
 }
 
 // removes item from array (by index)
-void wxArrayString::Remove(size_t nIndex, size_t nRemove)
+void wxArrayString::RemoveAt(size_t nIndex, size_t nRemove)
 {
   wxCHECK_RET( nIndex < m_nCount, wxT("bad index in wxArrayString::Remove") );
   wxCHECK_RET( nIndex + nRemove <= m_nCount,
@@ -2019,7 +2088,7 @@ void wxArrayString::Remove(const wxChar *sz)
   wxCHECK_RET( iIndex != wxNOT_FOUND,
                wxT("removing inexistent element in wxArrayString::Remove") );
 
-  Remove(iIndex);
+  RemoveAt(iIndex);
 }
 
 // ----------------------------------------------------------------------------
@@ -2054,7 +2123,7 @@ static wxArrayString::CompareFunction gs_compareFunction = NULL;
 static bool gs_sortAscending = TRUE;
 
 // function which is called by quick sort
-extern "C" int LINKAGEMODE
+extern "C" int wxC_CALLING_CONV     // LINKAGEMODE
 wxStringCompareFunction(const void *first, const void *second)
 {
   wxString *strFirst = (wxString *)first;
@@ -2087,16 +2156,16 @@ void wxArrayString::Sort(CompareFunction compareFunction)
   END_SORT();
 }
 
-void wxArrayString::Sort(bool reverseOrder)
-{
-  START_SORT();
+typedef  int (wxC_CALLING_CONV * wxStringCompareFn)(const void *first, const void *second);
 
-  wxASSERT( !gs_compareFunction );  // must have been reset to NULL
-  gs_sortAscending = !reverseOrder;
-
-  DoSort();
+void wxArrayString::Sort(CompareFunction2 compareFunction)
+{
+  qsort(m_pItems, m_nCount, sizeof(wxChar *), (wxStringCompareFn)compareFunction);
+}
 
-  END_SORT();
+void wxArrayString::Sort(bool reverseOrder)
+{
+  Sort(reverseOrder ? wxStringSortDescending : wxStringSortAscending);
 }
 
 void wxArrayString::DoSort()
@@ -2122,3 +2191,14 @@ bool wxArrayString::operator==(const wxArrayString& a) const
     return TRUE;
 }
 
+#endif // !wxUSE_STL
+
+int wxStringSortAscending(wxString* s1, wxString* s2)
+{
+    return wxStrcmp(s1->c_str(), s2->c_str());
+}
+
+int wxStringSortDescending(wxString* s1, wxString* s2)
+{
+    return -wxStrcmp(s1->c_str(), s2->c_str());
+}