]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/string.cpp
fixed compilation problems under Windows
[wxWidgets.git] / src / common / string.cpp
index 3e5e41f2d6007604f6075f9fc0ed12800b2758d0..bb02779aee932d74d9adbe243a52801147348506 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     29/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
 // Created:     29/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
-// Licence:    wxWindows license
+// Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
@@ -61,8 +61,6 @@ static int g_strEmpty[] = { -1,     // ref count (locked)
                              0,     // current length
                              0,     // allocated memory
                              0 };   // string data
                              0,     // current length
                              0,     // allocated memory
                              0 };   // string data
-// empty string shares memory with g_strEmpty
-static wxStringData *g_strNul = (wxStringData*)&g_strEmpty;
 // empty C style string: points to 'string data' byte of g_strEmpty
 extern const char *g_szNul = (const char *)(&g_strEmpty[3]);
 
 // empty C style string: points to 'string data' byte of g_strEmpty
 extern const char *g_szNul = (const char *)(&g_strEmpty[3]);
 
@@ -101,7 +99,7 @@ NAMESPACE istream& operator>>(NAMESPACE istream& is, wxString& WXUNUSED(str))
         sb->sungetc();
         break;
       }
         sb->sungetc();
         break;
       }
-      
+
       str += ch;
       if ( --w == 1 )
         break;
       str += ch;
       if ( --w == 1 )
         break;
@@ -176,7 +174,7 @@ void wxString::InitWith(const char *psz, size_t nPos, size_t nLength)
     memcpy(m_pchData, psz + nPos, nLength*sizeof(char));
   }
 }
     memcpy(m_pchData, psz + nPos, nLength*sizeof(char));
   }
 }
-        
+
 // take first nLength characters of C string psz
 // (default value of STRING_MAXLEN means take all the string)
 wxString::wxString(const char *psz, size_t nLength)
 // take first nLength characters of C string psz
 // (default value of STRING_MAXLEN means take all the string)
 wxString::wxString(const char *psz, size_t nLength)
@@ -188,8 +186,8 @@ wxString::wxString(const char *psz, size_t nLength)
 wxString::wxString(const unsigned char* psz, size_t nLength)
 {
   InitWith((const char *)psz, 0, nLength);
 wxString::wxString(const unsigned char* psz, size_t nLength)
 {
   InitWith((const char *)psz, 0, nLength);
-} 
+}
+
 #ifdef  STD_STRING_COMPATIBILITY
 
 // ctor from a substring
 #ifdef  STD_STRING_COMPATIBILITY
 
 // ctor from a substring
@@ -203,7 +201,7 @@ wxString::wxString(const wxString& str, size_t nPos, size_t nLen)
 // poor man's iterators are "void *" pointers
 wxString::wxString(const void *pStart, const void *pEnd)
 {
 // poor man's iterators are "void *" pointers
 wxString::wxString(const void *pStart, const void *pEnd)
 {
-  InitWith((const char *)pStart, 0, 
+  InitWith((const char *)pStart, 0,
            (const char *)pEnd - (const char *)pStart);
 }
 
            (const char *)pEnd - (const char *)pStart);
 }
 
@@ -238,8 +236,8 @@ void wxString::AllocBuffer(size_t nLen)
   // allocate memory:
   // 1) one extra character for '\0' termination
   // 2) sizeof(wxStringData) for housekeeping info
   // allocate memory:
   // 1) one extra character for '\0' termination
   // 2) sizeof(wxStringData) for housekeeping info
-  wxStringData* pData = (wxStringData*)new char[sizeof(wxStringData) +
-                                                (nLen + 1)*sizeof(char)];
+  wxStringData* pData = (wxStringData*)malloc(sizeof(wxStringData) +
+                                              (nLen + 1)*sizeof(char));
   pData->nRefs        = 1;
   pData->data()[nLen] = '\0';
   pData->nDataLength  = nLen;
   pData->nRefs        = 1;
   pData->data()[nLen] = '\0';
   pData->nDataLength  = nLen;
@@ -247,23 +245,6 @@ void wxString::AllocBuffer(size_t nLen)
   m_pchData           = pData->data();  // data starts after wxStringData
 }
 
   m_pchData           = pData->data();  // data starts after wxStringData
 }
 
-// releases the string memory and reinits it
-void wxString::Reinit()
-{
-  GetStringData()->Unlock();
-  Init();
-}
-
-// wrapper around wxString::Reinit
-void wxString::Empty()
-{
-  if ( GetStringData()->nDataLength != 0 )
-    Reinit();
-
-  wxASSERT( GetStringData()->nDataLength == 0 );
-  wxASSERT( GetStringData()->nAllocLength == 0 );
-}
-
 // must be called before changing this string
 void wxString::CopyBeforeWrite()
 {
 // must be called before changing this string
 void wxString::CopyBeforeWrite()
 {
@@ -294,8 +275,44 @@ void wxString::AllocBeforeWrite(size_t nLen)
   wxASSERT( !GetStringData()->IsShared() );  // we must be the only owner
 }
 
   wxASSERT( !GetStringData()->IsShared() );  // we must be the only owner
 }
 
+// allocate enough memory for nLen characters
+void wxString::Alloc(uint nLen)
+{
+  wxStringData *pData = GetStringData();
+  if ( pData->nAllocLength <= nLen ) {
+    if ( pData->IsEmpty() )
+      AllocBuffer(nLen);
+    else {
+      wxStringData *p = (wxStringData *)
+        realloc(pData, sizeof(wxStringData) + (nLen + 1)*sizeof(char));
+      if ( p != NULL && p != pData ) {
+        // the call succeeded but the pointer changed
+        pData->Unlock();
+        free(pData);
+
+        p->nRefs = 1;
+        p->nAllocLength = nLen;
+        m_pchData = p->data();
+      }
+      //else: do nothing: either the call failed or the pointer is unchanged
+    }
+  }
+  //else: we've already got enough
+}
+
+// shrink to minimal size (releasing extra memory)
+void wxString::Shrink()
+{
+  wxStringData *pData = GetStringData();
+  void *p = realloc(pData, sizeof(wxStringData) +
+                    (pData->nDataLength + 1)*sizeof(char));
+  if ( p == NULL )  // huh? can't unallocate memory? unlikely but possible.
+    return;
+  wxASSERT( p == pData ); // we're decrementing the size - block shouldn't move!
+}
+
 // get the pointer to writable buffer of (at least) nLen bytes
 // get the pointer to writable buffer of (at least) nLen bytes
-char *wxString::GetWriteBuf(int nLen)
+char *wxString::GetWriteBuf(uint nLen)
 {
   AllocBeforeWrite(nLen);
 
 {
   AllocBeforeWrite(nLen);
 
@@ -328,7 +345,7 @@ wxString::~wxString()
 // assignment operators
 // ---------------------------------------------------------------------------
 
 // assignment operators
 // ---------------------------------------------------------------------------
 
-// helper function: does real copy 
+// helper function: does real copy
 void wxString::AssignCopy(size_t nSrcLen, const char *pszSrcData)
 {
   if ( nSrcLen == 0 ) {
 void wxString::AssignCopy(size_t nSrcLen, const char *pszSrcData)
 {
   if ( nSrcLen == 0 ) {
@@ -398,7 +415,7 @@ wxString& wxString::operator=(const wchar_t *pwz)
 // concatenate two sources
 // NB: assume that 'this' is a new wxString object
 void wxString::ConcatCopy(int nSrc1Len, const char *pszSrc1Data,
 // concatenate two sources
 // NB: assume that 'this' is a new wxString object
 void wxString::ConcatCopy(int nSrc1Len, const char *pszSrc1Data,
-                        int nSrc2Len, const char *pszSrc2Data)
+                          int nSrc2Len, const char *pszSrc2Data)
 {
   int nNewLen = nSrc1Len + nSrc2Len;
   if ( nNewLen != 0 )
 {
   int nNewLen = nSrc1Len + nSrc2Len;
   if ( nNewLen != 0 )
@@ -417,7 +434,7 @@ void wxString::ConcatSelf(int nSrcLen, const char *pszSrcData)
     register wxStringData *pData = GetStringData();
 
     // alloc new buffer if current is too small
     register wxStringData *pData = GetStringData();
 
     // alloc new buffer if current is too small
-    if ( pData->IsShared() || 
+    if ( pData->IsShared() ||
          pData->nDataLength + nSrcLen > pData->nAllocLength ) {
       // we have to grow the buffer, use the ConcatCopy routine
       // (which will allocate memory)
          pData->nDataLength + nSrcLen > pData->nAllocLength ) {
       // we have to grow the buffer, use the ConcatCopy routine
       // (which will allocate memory)
@@ -439,51 +456,6 @@ void wxString::ConcatSelf(int nSrcLen, const char *pszSrcData)
 }
 
 /*
 }
 
 /*
- * string may be concatenated with other string, C string or a character
- */
-
-void wxString::operator+=(const wxString& string)
-{
-  wxASSERT( string.GetStringData()->IsValid() );
-
-  ConcatSelf(string.Len(), string);
-}
-
-void wxString::operator+=(const char *psz)
-{
-  ConcatSelf(Strlen(psz), psz);
-}
-
-void wxString::operator+=(char ch)
-{
-  ConcatSelf(1, &ch);
-}
-
-/*
- * Same as above but return the result
- */  
-
-wxString& wxString::operator<<(const wxString& string)
-{
-  wxASSERT( string.GetStringData()->IsValid() );
-
-  ConcatSelf(string.Len(), string);
-  return *this;
-}
-
-wxString& wxString::operator<<(const char *psz)
-{
-  ConcatSelf(Strlen(psz), psz);
-  return *this;
-}
-
-wxString& wxString::operator<<(char ch)
-{
-  ConcatSelf(1, &ch);
-  return *this;
-}
-
-/* 
  * concatenation functions come in 5 flavours:
  *  string + string
  *  char   + string      and      string + char
  * concatenation functions come in 5 flavours:
  *  string + string
  *  char   + string      and      string + char
@@ -659,7 +631,7 @@ uint wxString::Replace(const char *szOld, const char *szNew, bool bReplaceAll)
 
   wxString strTemp;
   const char *pCurrent = m_pchData;
 
   wxString strTemp;
   const char *pCurrent = m_pchData;
-  const char *pSubstr;           
+  const char *pSubstr;
   while ( *pCurrent != '\0' ) {
     pSubstr = strstr(pCurrent, szOld);
     if ( pSubstr == NULL ) {
   while ( *pCurrent != '\0' ) {
     pSubstr = strstr(pCurrent, szOld);
     if ( pSubstr == NULL ) {
@@ -701,7 +673,7 @@ bool wxString::IsAscii() const
   }
   return(TRUE);
 }
   }
   return(TRUE);
 }
-  
+
 bool wxString::IsWord() const
 {
   const char *s = (const char*) *this;
 bool wxString::IsWord() const
 {
   const char *s = (const char*) *this;
@@ -711,7 +683,7 @@ bool wxString::IsWord() const
   }
   return(TRUE);
 }
   }
   return(TRUE);
 }
-  
+
 bool wxString::IsNumber() const
 {
   const char *s = (const char*) *this;
 bool wxString::IsNumber() const
 {
   const char *s = (const char*) *this;
@@ -722,10 +694,6 @@ bool wxString::IsNumber() const
   return(TRUE);
 }
 
   return(TRUE);
 }
 
-// kludge: we don't have declaraton of wxStringData here, so we add offsets
-//         manually to get to the "length" field of wxStringData structure
-bool   wxString::IsEmpty() const  { return Len() == 0;                        }
-
 wxString wxString::Strip(stripType w) const
 {
     wxString s = *this;
 wxString wxString::Strip(stripType w) const
 {
     wxString s = *this;
@@ -734,33 +702,6 @@ wxString wxString::Strip(stripType w) const
     return s;
 }
 
     return s;
 }
 
-/// case-insensitive strcmp() (platform independent)
-int Stricmp(const char *psz1, const char *psz2)
-{
-#if     defined(_MSC_VER)
-  return _stricmp(psz1, psz2);
-#elif defined(__BORLANDC__)
-  return stricmp(psz1, psz2);
-#elif   defined(__UNIX__) || defined(__GNUWIN32__)
-  return strcasecmp(psz1, psz2);
-#else
-  // almost all compilers/libraries provide this function (unfortunately under
-  // different names), that's why we don't implement our own which will surely
-  // be more efficient than this code (uncomment to use):
-  /*
-    register char c1, c2;
-    do {
-      c1 = tolower(*psz1++);
-      c2 = tolower(*psz2++);
-    } while ( c1 && (c1 == c2) );
-
-    return c1 - c2;
-  */
-  
-  #error  "Please define string case-insensitive compare for your OS/compiler"
-#endif  // OS/compiler
-}
-
 // ---------------------------------------------------------------------------
 // case conversion
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // case conversion
 // ---------------------------------------------------------------------------
@@ -778,7 +719,7 @@ wxString& wxString::MakeUpper()
 wxString& wxString::MakeLower()
 {
   CopyBeforeWrite();
 wxString& wxString::MakeLower()
 {
   CopyBeforeWrite();
-  
+
   for ( char *p = m_pchData; *p; p++ )
     *p = (char)tolower(*p);
 
   for ( char *p = m_pchData; *p; p++ )
     *p = (char)tolower(*p);
 
@@ -907,7 +848,7 @@ int wxString::Scanf(const char *pszFormat, ...) const
 
 int wxString::ScanfV(const char *pszFormat, va_list argptr) const
 {
 
 int wxString::ScanfV(const char *pszFormat, va_list argptr) const
 {
-#ifdef __WINDOWS__
+#ifdef __WXMSW__
   wxMessageBox("ScanfV not implemented");
   return 0;
 #else
   wxMessageBox("ScanfV not implemented");
   return 0;
 #else
@@ -993,9 +934,10 @@ wxString& wxString::insert(size_t nPos, const wxString& str)
   strncpy(pc, c_str(), nPos);
   strcpy(pc + nPos, str);
   strcpy(pc + nPos + str.Len(), c_str() + nPos);
   strncpy(pc, c_str(), nPos);
   strcpy(pc + nPos, str);
   strcpy(pc + nPos + str.Len(), c_str() + nPos);
+  strTmp.UngetWriteBuf();
   *this = strTmp;
   *this = strTmp;
-    
-  return *this; 
+
+  return *this;
 }
 
 size_t wxString::find(const wxString& str, size_t nStart) const
 }
 
 size_t wxString::find(const wxString& str, size_t nStart) const
@@ -1004,7 +946,7 @@ size_t wxString::find(const wxString& str, size_t nStart) const
   wxASSERT( nStart <= Len() );
 
   const char *p = strstr(c_str() + nStart, str);
   wxASSERT( nStart <= Len() );
 
   const char *p = strstr(c_str() + nStart, str);
-  
+
   return p == NULL ? npos : p - c_str();
 }
 
   return p == NULL ? npos : p - c_str();
 }
 
@@ -1015,13 +957,13 @@ size_t wxString::find(const char* sz, size_t nStart, size_t n) const
   return find(wxString(sz, n == npos ? 0 : n), nStart);
 }
 #endif
   return find(wxString(sz, n == npos ? 0 : n), nStart);
 }
 #endif
-        
+
 size_t wxString::find(char ch, size_t nStart) const
 {
   wxASSERT( nStart <= Len() );
 
   const char *p = strchr(c_str() + nStart, ch);
 size_t wxString::find(char ch, size_t nStart) const
 {
   wxASSERT( nStart <= Len() );
 
   const char *p = strchr(c_str() + nStart, ch);
-  
+
   return p == NULL ? npos : p - c_str();
 }
 
   return p == NULL ? npos : p - c_str();
 }
 
@@ -1037,10 +979,10 @@ size_t wxString::rfind(const wxString& str, size_t nStart) const
       return p - str.Len() - c_str();
     p--;
   }
       return p - str.Len() - c_str();
     p--;
   }
-  
+
   return npos;
 }
   return npos;
 }
-        
+
 // VC++ 1.5 can't cope with the default argument in the header.
 #if ! (defined(_MSC_VER) && !defined(__WIN32__))
 size_t wxString::rfind(const char* sz, size_t nStart, size_t n) const
 // VC++ 1.5 can't cope with the default argument in the header.
 #if ! (defined(_MSC_VER) && !defined(__WIN32__))
 size_t wxString::rfind(const char* sz, size_t nStart, size_t n) const
@@ -1053,7 +995,7 @@ size_t wxString::rfind(char ch, size_t nStart) const
   wxASSERT( nStart <= Len() );
 
   const char *p = strrchr(c_str() + nStart, ch);
   wxASSERT( nStart <= Len() );
 
   const char *p = strrchr(c_str() + nStart, ch);
-  
+
   return p == NULL ? npos : p - c_str();
 }
 #endif
   return p == NULL ? npos : p - c_str();
 }
 #endif
@@ -1091,7 +1033,7 @@ wxString& wxString::replace(size_t nStart, size_t nLen, const char *sz)
     strTmp.append(c_str(), nStart);
   strTmp += sz;
   strTmp.append(c_str() + nStart + nLen);
     strTmp.append(c_str(), nStart);
   strTmp += sz;
   strTmp.append(c_str() + nStart + nLen);
-  
+
   *this = strTmp;
   return *this;
 }
   *this = strTmp;
   return *this;
 }
@@ -1101,13 +1043,13 @@ wxString& wxString::replace(size_t nStart, size_t nLen, size_t nCount, char ch)
   return replace(nStart, nLen, wxString(ch, nCount));
 }
 
   return replace(nStart, nLen, wxString(ch, nCount));
 }
 
-wxString& wxString::replace(size_t nStart, size_t nLen, 
+wxString& wxString::replace(size_t nStart, size_t nLen,
                             const wxString& str, size_t nStart2, size_t nLen2)
 {
   return replace(nStart, nLen, str.substr(nStart2, nLen2));
 }
 
                             const wxString& str, size_t nStart2, size_t nLen2)
 {
   return replace(nStart, nLen, str.substr(nStart2, nLen2));
 }
 
-wxString& wxString::replace(size_t nStart, size_t nLen, 
+wxString& wxString::replace(size_t nStart, size_t nLen,
                         const char* sz, size_t nCount)
 {
   return replace(nStart, nLen, wxString(sz, nCount));
                         const char* sz, size_t nCount)
 {
   return replace(nStart, nLen, wxString(sz, nCount));
@@ -1159,7 +1101,7 @@ wxArrayString& wxArrayString::operator=(const wxArrayString& src)
   m_nCount = src.m_nCount;
 
   if ( m_nSize != 0 )
   m_nCount = src.m_nCount;
 
   if ( m_nSize != 0 )
-    m_pItems = new char *[m_nSize];
+    m_pItems = new char *[m_nCount];
   else
     m_pItems = NULL;
 
   else
     m_pItems = NULL;
 
@@ -1218,7 +1160,7 @@ void wxArrayString::Clear()
 {
   Free();
 
 {
   Free();
 
-  m_nSize  = 
+  m_nSize  =
   m_nCount = 0;
 
   DELETEA(m_pItems);
   m_nCount = 0;
 
   DELETEA(m_pItems);
@@ -1296,7 +1238,7 @@ void wxArrayString::Insert(const wxString& str, size_t nIndex)
 
   Grow();
 
 
   Grow();
 
-  memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex], 
+  memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex],
           (m_nCount - nIndex)*sizeof(char *));
 
   str.GetStringData()->Lock();
           (m_nCount - nIndex)*sizeof(char *));
 
   str.GetStringData()->Lock();
@@ -1313,7 +1255,7 @@ void wxArrayString::Remove(size_t nIndex)
   // release our lock
   Item(nIndex).GetStringData()->Unlock();
 
   // release our lock
   Item(nIndex).GetStringData()->Unlock();
 
-  memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1], 
+  memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1],
           (m_nCount - nIndex - 1)*sizeof(char *));
   m_nCount--;
 }
           (m_nCount - nIndex - 1)*sizeof(char *));
   m_nCount--;
 }