]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/string.cpp
removed useless trailing semicolon
[wxWidgets.git] / src / common / string.cpp
index 3fdcf1e0de455fd04cd125877be0fb605ad5c668..ea40c4d4115c2ec1a44cfabbbc4fb074fd6a09de 100644 (file)
@@ -38,8 +38,6 @@
   #include "wx/thread.h"
 #endif
 
   #include "wx/thread.h"
 #endif
 
-#include "wx/regex.h"   // for wxString::Matches()
-
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
   #include <clib.h>
 #endif
 
   #include <clib.h>
 #endif
 
-#ifdef  WXSTRING_IS_WXOBJECT
-  IMPLEMENT_DYNAMIC_CLASS(wxString, wxObject)
-#endif  //WXSTRING_IS_WXOBJECT
-
 #if wxUSE_UNICODE
 #if wxUSE_UNICODE
-#undef wxUSE_EXPERIMENTAL_PRINTF
-#define wxUSE_EXPERIMENTAL_PRINTF 1
+    #undef wxUSE_EXPERIMENTAL_PRINTF
+    #define wxUSE_EXPERIMENTAL_PRINTF 1
 #endif
 
 // allocating extra space for each string consumes more memory but speeds up
 #endif
 
 // allocating extra space for each string consumes more memory but speeds up
@@ -135,7 +129,7 @@ extern const wxChar WXDLLEXPORT *wxEmptyString = &g_strEmpty.dummy;
     #endif //compiler
 #endif // no vsnprintf
 
     #endif //compiler
 #endif // no vsnprintf
 
-#ifdef _AIX
+#if defined(_AIX)
   // AIX has vsnprintf, but there's no prototype in the system headers.
   extern "C" int vsnprintf(char* str, size_t n, const char* format, va_list ap);
 #endif
   // AIX has vsnprintf, but there's no prototype in the system headers.
   extern "C" int vsnprintf(char* str, size_t n, const char* format, va_list ap);
 #endif
@@ -342,10 +336,17 @@ wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength)
 
 #if wxUSE_WCHAR_T
 // from wide string
 
 #if wxUSE_WCHAR_T
 // from wide string
-wxString::wxString(const wchar_t *pwz, wxMBConv& conv)
+wxString::wxString(const wchar_t *pwz, wxMBConv& conv, size_t nLength)
 {
   // first get necessary size
 {
   // first get necessary size
-  size_t nLen = pwz ? conv.WC2MB((char *) NULL, pwz, 0) : 0;
+  size_t nLen = 0;
+  if (pwz)
+  {
+    if (nLength == wxSTRING_MAXLEN)
+      nLen = conv.WC2MB((char *) NULL, pwz, 0);
+    else
+      nLen = nLength;
+  }
 
   // empty?
   if ( (nLen != 0) && (nLen != (size_t)-1) ) {
 
   // empty?
   if ( (nLen != 0) && (nLen != (size_t)-1) ) {
@@ -1096,6 +1097,7 @@ int wxString::Find(const wxChar *pszSub) const
 bool wxString::ToLong(long *val, int base) const
 {
     wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToLong") );
 bool wxString::ToLong(long *val, int base) const
 {
     wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToLong") );
+    wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
 
     const wxChar *start = c_str();
     wxChar *end;
 
     const wxChar *start = c_str();
     wxChar *end;
@@ -1109,6 +1111,7 @@ bool wxString::ToLong(long *val, int base) const
 bool wxString::ToULong(unsigned long *val, int base) const
 {
     wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToULong") );
 bool wxString::ToULong(unsigned long *val, int base) const
 {
     wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToULong") );
+    wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
 
     const wxChar *start = c_str();
     wxChar *end;
 
     const wxChar *start = c_str();
     wxChar *end;
@@ -1458,7 +1461,11 @@ int wxString::PrintfV(const wxChar* pszFormat, va_list argptr)
 // of them)
 bool wxString::Matches(const wxChar *pszMask) const
 {
 // of them)
 bool wxString::Matches(const wxChar *pszMask) const
 {
-#if wxUSE_REGEX
+    // I disable this code as it doesn't seem to be faster (in fact, it seems
+    // to be much slower) than the old, hand-written code below and using it
+    // here requires always linking with libregex even if the user code doesn't
+    // use it
+#if 0 // wxUSE_REGEX
     // first translate the shell-like mask into a regex
     wxString pattern;
     pattern.reserve(wxStrlen(pszMask));
     // first translate the shell-like mask into a regex
     wxString pattern;
     pattern.reserve(wxStrlen(pszMask));
@@ -1632,7 +1639,7 @@ void wxString::resize(size_t nSize, wxChar ch)
     }
     else if ( nSize > len )
     {
     }
     else if ( nSize > len )
     {
-        *this += wxString(ch, len - nSize);
+        *this += wxString(ch, nSize - len);
     }
     //else: we have exactly the specified length, nothing to do
 }
     }
     //else: we have exactly the specified length, nothing to do
 }
@@ -1644,7 +1651,7 @@ void wxString::swap(wxString& str)
     // ref count always stays positive
     wxString tmp = str;
     str = *this;
     // ref count always stays positive
     wxString tmp = str;
     str = *this;
-    *this = str;
+    *this = tmp;
 }
 
 wxString& wxString::insert(size_t nPos, const wxString& str)
 }
 
 wxString& wxString::insert(size_t nPos, const wxString& str)
@@ -1698,7 +1705,7 @@ size_t wxString::find(wxChar ch, size_t nStart) const
 size_t wxString::rfind(const wxString& str, size_t nStart) const
 {
   wxASSERT( str.GetStringData()->IsValid() );
 size_t wxString::rfind(const wxString& str, size_t nStart) const
 {
   wxASSERT( str.GetStringData()->IsValid() );
-  wxASSERT( nStart <= Len() );
+  wxASSERT( nStart == npos || nStart <= Len() );
 
   // TODO could be made much quicker than that
   const wxChar *p = c_str() + (nStart == npos ? Len() : nStart);
 
   // TODO could be made much quicker than that
   const wxChar *p = c_str() + (nStart == npos ? Len() : nStart);
@@ -1715,7 +1722,7 @@ size_t wxString::rfind(const wxString& str, size_t nStart) const
 #if !defined(__VISUALC__) || defined(__WIN32__)
 size_t wxString::rfind(const wxChar* sz, size_t nStart, size_t n) const
 {
 #if !defined(__VISUALC__) || defined(__WIN32__)
 size_t wxString::rfind(const wxChar* sz, size_t nStart, size_t n) const
 {
-    return rfind(wxString(sz, n == npos ? 0 : n), nStart);
+    return rfind(wxString(sz, n == npos ? wxSTRING_MAXLEN : n), nStart);
 }
 
 size_t wxString::rfind(wxChar ch, size_t nStart) const
 }
 
 size_t wxString::rfind(wxChar ch, size_t nStart) const
@@ -1892,16 +1899,17 @@ wxString& wxString::replace(size_t nStart, size_t nLen,
 // ArrayString
 // ============================================================================
 
 // ArrayString
 // ============================================================================
 
-// size increment = max(50% of current size, ARRAY_MAXSIZE_INCREMENT)
+// size increment = min(50% of current size, ARRAY_MAXSIZE_INCREMENT)
 #define   ARRAY_MAXSIZE_INCREMENT       4096
 #define   ARRAY_MAXSIZE_INCREMENT       4096
+
 #ifndef   ARRAY_DEFAULT_INITIAL_SIZE    // also defined in dynarray.h
 #ifndef   ARRAY_DEFAULT_INITIAL_SIZE    // also defined in dynarray.h
-  #define   ARRAY_DEFAULT_INITIAL_SIZE    (16)
+#define   ARRAY_DEFAULT_INITIAL_SIZE    (16)
 #endif
 
 #define   STRING(p)   ((wxString *)(&(p)))
 
 // ctor
 #endif
 
 #define   STRING(p)   ((wxString *)(&(p)))
 
 // ctor
-wxArrayString::wxArrayString(bool autoSort)
+void wxArrayString::Init(bool autoSort)
 {
   m_nSize  =
   m_nCount = 0;
 {
   m_nSize  =
   m_nCount = 0;
@@ -1912,10 +1920,7 @@ wxArrayString::wxArrayString(bool autoSort)
 // copy ctor
 wxArrayString::wxArrayString(const wxArrayString& src)
 {
 // copy ctor
 wxArrayString::wxArrayString(const wxArrayString& src)
 {
-  m_nSize  =
-  m_nCount = 0;
-  m_pItems = (wxChar **) NULL;
-  m_autoSort = src.m_autoSort;
+  Init(src.m_autoSort);
 
   *this = src;
 }
 
   *this = src;
 }
@@ -1943,7 +1948,7 @@ void wxArrayString::Copy(const wxArrayString& src)
 }
 
 // grow the array
 }
 
 // grow the array
-void wxArrayString::Grow()
+void wxArrayString::Grow(size_t nIncrement)
 {
   // only do it if no more place
   if ( m_nCount == m_nSize ) {
 {
   // only do it if no more place
   if ( m_nCount == m_nSize ) {
@@ -1962,10 +1967,12 @@ void wxArrayString::Grow()
       // otherwise when it's called for the first time, nIncrement would be 0
       // and the array would never be expanded
       // add 50% but not too much
       // otherwise when it's called for the first time, nIncrement would be 0
       // and the array would never be expanded
       // add 50% but not too much
-      size_t nIncrement = m_nSize < ARRAY_DEFAULT_INITIAL_SIZE
+      size_t ndefIncrement = m_nSize < ARRAY_DEFAULT_INITIAL_SIZE
                           ? ARRAY_DEFAULT_INITIAL_SIZE : m_nSize >> 1;
                           ? ARRAY_DEFAULT_INITIAL_SIZE : m_nSize >> 1;
-      if ( nIncrement > ARRAY_MAXSIZE_INCREMENT )
-        nIncrement = ARRAY_MAXSIZE_INCREMENT;
+      if ( ndefIncrement > ARRAY_MAXSIZE_INCREMENT )
+        ndefIncrement = ARRAY_MAXSIZE_INCREMENT;
+      if ( nIncrement < ndefIncrement )
+        nIncrement = ndefIncrement;
       m_nSize += nIncrement;
       wxChar **pNew = new wxChar *[m_nSize];
 
       m_nSize += nIncrement;
       wxChar **pNew = new wxChar *[m_nSize];
 
@@ -2017,8 +2024,6 @@ wxArrayString::~wxArrayString()
 // pre-allocates memory (frees the previous data!)
 void wxArrayString::Alloc(size_t nSize)
 {
 // pre-allocates memory (frees the previous data!)
 void wxArrayString::Alloc(size_t nSize)
 {
-  wxASSERT( nSize > 0 );
-
   // only if old buffer was not big enough
   if ( nSize > m_nSize ) {
     Free();
   // only if old buffer was not big enough
   if ( nSize > m_nSize ) {
     Free();
@@ -2045,6 +2050,21 @@ void wxArrayString::Shrink()
   }
 }
 
   }
 }
 
+// return a wxString[] as required for some control ctors.
+wxString* wxArrayString::GetStringArray() const
+{
+    wxString *array = 0;
+
+    if( m_nCount > 0 )
+    {
+        array = new wxString[m_nCount];
+        for( size_t i = 0; i < m_nCount; i++ )
+            array[i] = m_pItems[i];
+    }
+
+    return array;
+}
+
 // searches the array for an item (forward or backwards)
 int wxArrayString::Index(const wxChar *sz, bool bCase, bool bFromEnd) const
 {
 // searches the array for an item (forward or backwards)
 int wxArrayString::Index(const wxChar *sz, bool bCase, bool bFromEnd) const
 {
@@ -2095,7 +2115,7 @@ int wxArrayString::Index(const wxChar *sz, bool bCase, bool bFromEnd) const
 }
 
 // add item at the end
 }
 
 // add item at the end
-size_t wxArrayString::Add(const wxString& str)
+size_t wxArrayString::Add(const wxString& str, size_t nInsert)
 {
   if ( m_autoSort ) {
     // insert the string at the correct position to keep the array sorted
 {
   if ( m_autoSort ) {
     // insert the string at the correct position to keep the array sorted
@@ -2119,41 +2139,49 @@ size_t wxArrayString::Add(const wxString& str)
 
     wxASSERT_MSG( lo == hi, wxT("binary search broken") );
 
 
     wxASSERT_MSG( lo == hi, wxT("binary search broken") );
 
-    Insert(str, lo);
+    Insert(str, lo, nInsert);
 
     return (size_t)lo;
   }
   else {
     wxASSERT( str.GetStringData()->IsValid() );
 
 
     return (size_t)lo;
   }
   else {
     wxASSERT( str.GetStringData()->IsValid() );
 
-    Grow();
-
-    // the string data must not be deleted!
-    str.GetStringData()->Lock();
+    Grow(nInsert);
 
 
-    // just append
-    m_pItems[m_nCount] = (wxChar *)str.c_str(); // const_cast
+    for (size_t i = 0; i < nInsert; i++)
+    {   
+        // the string data must not be deleted!
+        str.GetStringData()->Lock();
 
 
-    return m_nCount++;
+        // just append
+        m_pItems[m_nCount + i] = (wxChar *)str.c_str(); // const_cast
+    }
+    size_t ret = m_nCount;
+    m_nCount += nInsert;
+    return ret;
   }
 }
 
 // add item at the given position
   }
 }
 
 // add item at the given position
-void wxArrayString::Insert(const wxString& str, size_t nIndex)
+void wxArrayString::Insert(const wxString& str, size_t nIndex, size_t nInsert)
 {
   wxASSERT( str.GetStringData()->IsValid() );
 
   wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArrayString::Insert") );
 {
   wxASSERT( str.GetStringData()->IsValid() );
 
   wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArrayString::Insert") );
+  wxCHECK_RET( m_nCount <= m_nCount + nInsert,
+               wxT("array size overflow in wxArrayString::Insert") );
 
 
-  Grow();
+  Grow(nInsert);
 
 
-  memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex],
+  memmove(&m_pItems[nIndex + nInsert], &m_pItems[nIndex],
           (m_nCount - nIndex)*sizeof(wxChar *));
 
           (m_nCount - nIndex)*sizeof(wxChar *));
 
-  str.GetStringData()->Lock();
-  m_pItems[nIndex] = (wxChar *)str.c_str();
-
-  m_nCount++;
+  for (size_t i = 0; i < nInsert; i++)
+  {
+      str.GetStringData()->Lock();
+      m_pItems[nIndex + i] = (wxChar *)str.c_str();
+  }
+  m_nCount += nInsert;
 }
 
 // expand the array
 }
 
 // expand the array
@@ -2167,16 +2195,19 @@ void wxArrayString::SetCount(size_t count)
 }
 
 // removes item from array (by index)
 }
 
 // removes item from array (by index)
-void wxArrayString::Remove(size_t nIndex)
+void wxArrayString::Remove(size_t nIndex, size_t nRemove)
 {
 {
-  wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArrayString::Remove") );
+  wxCHECK_RET( nIndex < m_nCount, wxT("bad index in wxArrayString::Remove") );
+  wxCHECK_RET( nIndex + nRemove <= m_nCount,
+               wxT("removing too many elements in wxArrayString::Remove") );
 
   // release our lock
 
   // release our lock
-  Item(nIndex).GetStringData()->Unlock();
+  for (size_t i = 0; i < nRemove; i++)
+      Item(nIndex + i).GetStringData()->Unlock();
 
 
-  memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1],
-          (m_nCount - nIndex - 1)*sizeof(wxChar *));
-  m_nCount--;
+  memmove(&m_pItems[nIndex], &m_pItems[nIndex + nRemove],
+          (m_nCount - nIndex - nRemove)*sizeof(wxChar *));
+  m_nCount -= nRemove;
 }
 
 // removes item from array (by value)
 }
 
 // removes item from array (by value)
@@ -2222,7 +2253,8 @@ static wxArrayString::CompareFunction gs_compareFunction = NULL;
 static bool gs_sortAscending = TRUE;
 
 // function which is called by quick sort
 static bool gs_sortAscending = TRUE;
 
 // function which is called by quick sort
-static int LINKAGEMODE wxStringCompareFunction(const void *first, const void *second)
+extern "C" int LINKAGEMODE
+wxStringCompareFunction(const void *first, const void *second)
 {
   wxString *strFirst = (wxString *)first;
   wxString *strSecond = (wxString *)second;
 {
   wxString *strFirst = (wxString *)first;
   wxString *strSecond = (wxString *)second;