]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/string.cpp
static wxFile::Access() added
[wxWidgets.git] / src / common / string.cpp
index c2246e499151cd7ba6d47598d0a95dea457f9c10..1273610fb6c6b7b54f5196c620168225254a5825 100644 (file)
@@ -34,6 +34,7 @@
 #ifndef WX_PRECOMP
 #include "wx/defs.h"
 #include "wx/string.h"
 #ifndef WX_PRECOMP
 #include "wx/defs.h"
 #include "wx/string.h"
+#include <wx/intl.h>
 #endif
 
 #include <ctype.h>
 #endif
 
 #include <ctype.h>
@@ -46,7 +47,8 @@
 
 // allocating extra space for each string consumes more memory but speeds up
 // the concatenation operations (nLen is the current string's length)
 
 // allocating extra space for each string consumes more memory but speeds up
 // the concatenation operations (nLen is the current string's length)
-#define EXTRA_ALLOC       16
+// NB: EXTRA_ALLOC must be >= 0!
+#define EXTRA_ALLOC       (19 - nLen % 16)
 
 // ---------------------------------------------------------------------------
 // static class variables definition
 
 // ---------------------------------------------------------------------------
 // static class variables definition
@@ -258,7 +260,7 @@ void wxString::CopyBeforeWrite()
     memcpy(m_pchData, pData->data(), nLen*sizeof(char));
   }
 
     memcpy(m_pchData, pData->data(), nLen*sizeof(char));
   }
 
-  wxASSERT( !pData->IsShared() );  // we must be the only owner
+  wxASSERT( !GetStringData()->IsShared() );  // we must be the only owner
 }
 
 // must be called before replacing contents of this string
 }
 
 // must be called before replacing contents of this string
@@ -282,13 +284,22 @@ void wxString::Alloc(uint nLen)
 {
   wxStringData *pData = GetStringData();
   if ( pData->nAllocLength <= nLen ) {
 {
   wxStringData *pData = GetStringData();
   if ( pData->nAllocLength <= nLen ) {
-    if ( pData->IsEmpty() )
-      AllocBuffer(nLen);
+    if ( pData->IsEmpty() ) {
+      nLen += EXTRA_ALLOC;
+
+      wxStringData* pData = (wxStringData*)
+        malloc(sizeof(wxStringData) + (nLen + 1)*sizeof(char));
+      pData->nRefs = 1;
+      pData->nDataLength = 0;
+      pData->nAllocLength = nLen;
+      m_pchData = pData->data();  // data starts after wxStringData
+      m_pchData[0u] = '\0';
+    }
     else if ( pData->IsShared() ) {
       pData->Unlock();                // memory not freed because shared
     else if ( pData->IsShared() ) {
       pData->Unlock();                // memory not freed because shared
-      uint nLen = pData->nDataLength;
+      uint nOldLen = pData->nDataLength;
       AllocBuffer(nLen);
       AllocBuffer(nLen);
-      memcpy(m_pchData, pData->data(), nLen*sizeof(char));
+      memcpy(m_pchData, pData->data(), nOldLen*sizeof(char));
     }
     else {
       nLen += EXTRA_ALLOC;
     }
     else {
       nLen += EXTRA_ALLOC;
@@ -314,8 +325,14 @@ void wxString::Alloc(uint nLen)
 void wxString::Shrink()
 {
   wxStringData *pData = GetStringData();
 void wxString::Shrink()
 {
   wxStringData *pData = GetStringData();
-  void *p = realloc(pData, sizeof(wxStringData) +
-                    (pData->nDataLength + 1)*sizeof(char));
+
+  // this variable is unused in release build, so avoid the compiler warning by
+  // just not declaring it
+#ifdef __WXDEBUG__
+  void *p =
+#endif
+  realloc(pData, sizeof(wxStringData) + (pData->nDataLength + 1)*sizeof(char));
+
   wxASSERT( p != NULL );  // can't free memory?
   wxASSERT( p == pData ); // we're decrementing the size - block shouldn't move!
 }
   wxASSERT( p != NULL );  // can't free memory?
   wxASSERT( p == pData ); // we're decrementing the size - block shouldn't move!
 }
@@ -1064,30 +1081,26 @@ wxArrayString::wxArrayString()
 // copy ctor
 wxArrayString::wxArrayString(const wxArrayString& src)
 {
 // copy ctor
 wxArrayString::wxArrayString(const wxArrayString& src)
 {
-  m_nSize  = src.m_nSize;
-  m_nCount = src.m_nCount;
-
-  if ( m_nSize != 0 )
-    m_pItems = new char *[m_nSize];
-  else
-    m_pItems = NULL;
+  m_nSize  =
+  m_nCount = 0;
+  m_pItems = NULL;
 
 
-  if ( m_nCount != 0 )
-    memcpy(m_pItems, src.m_pItems, m_nCount*sizeof(char *));
+  *this = src;
 }
 
 }
 
-// copy operator
+// assignment operator
 wxArrayString& wxArrayString::operator=(const wxArrayString& src)
 {
 wxArrayString& wxArrayString::operator=(const wxArrayString& src)
 {
-  DELETEA(m_pItems);
+  if ( m_nSize > 0 )
+    Clear();
 
 
-  m_nSize  = src.m_nSize;
-  m_nCount = src.m_nCount;
+  if ( src.m_nCount > ARRAY_DEFAULT_INITIAL_SIZE )
+    Alloc(src.m_nCount);
 
 
-  if ( m_nSize != 0 )
-    m_pItems = new char *[m_nCount];
-  else
-    m_pItems = NULL;
+  // we can't just copy the pointers here because otherwise we would share
+  // the strings with another array
+  for ( uint n = 0; n < src.m_nCount; n++ )
+    Add(src[n]);
 
   if ( m_nCount != 0 )
     memcpy(m_pItems, src.m_pItems, m_nCount*sizeof(char *));
 
   if ( m_nCount != 0 )
     memcpy(m_pItems, src.m_pItems, m_nCount*sizeof(char *));
@@ -1106,8 +1119,13 @@ void wxArrayString::Grow()
       m_pItems = new char *[m_nSize];
     }
     else {
       m_pItems = new char *[m_nSize];
     }
     else {
+      // otherwise when it's called for the first time, nIncrement would be 0
+      // and the array would never be expanded
+      wxASSERT( ARRAY_DEFAULT_INITIAL_SIZE != 0 );
+
       // add 50% but not too much
       // add 50% but not too much
-      size_t nIncrement = m_nSize >> 1;
+      size_t nIncrement = m_nSize < ARRAY_DEFAULT_INITIAL_SIZE
+                          ? ARRAY_DEFAULT_INITIAL_SIZE : m_nSize >> 1;
       if ( nIncrement > ARRAY_MAXSIZE_INCREMENT )
         nIncrement = ARRAY_MAXSIZE_INCREMENT;
       m_nSize += nIncrement;
       if ( nIncrement > ARRAY_MAXSIZE_INCREMENT )
         nIncrement = ARRAY_MAXSIZE_INCREMENT;
       m_nSize += nIncrement;
@@ -1117,7 +1135,7 @@ void wxArrayString::Grow()
       memcpy(pNew, m_pItems, m_nCount*sizeof(char *));
 
       // delete old memory (but do not release the strings!)
       memcpy(pNew, m_pItems, m_nCount*sizeof(char *));
 
       // delete old memory (but do not release the strings!)
-      DELETEA(m_pItems);
+      wxDELETEA(m_pItems);
 
       m_pItems = pNew;
     }
 
       m_pItems = pNew;
     }
@@ -1147,8 +1165,7 @@ void wxArrayString::Clear()
   m_nSize  =
   m_nCount = 0;
 
   m_nSize  =
   m_nCount = 0;
 
-  DELETEA(m_pItems);
-  m_pItems = NULL;
+  wxDELETEA(m_pItems);
 }
 
 // dtor
 }
 
 // dtor
@@ -1156,7 +1173,7 @@ wxArrayString::~wxArrayString()
 {
   Free();
 
 {
   Free();
 
-  DELETEA(m_pItems);
+  wxDELETEA(m_pItems);
 }
 
 // pre-allocates memory (frees the previous data!)
 }
 
 // pre-allocates memory (frees the previous data!)
@@ -1167,7 +1184,7 @@ void wxArrayString::Alloc(size_t nSize)
   // 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();
-    DELETEA(m_pItems);
+    wxDELETEA(m_pItems);
     m_pItems = new char *[nSize];
     m_nSize  = nSize;
   }
     m_pItems = new char *[nSize];
     m_nSize  = nSize;
   }
@@ -1215,7 +1232,7 @@ void wxArrayString::Insert(const wxString& str, size_t nIndex)
 {
   wxASSERT( str.GetStringData()->IsValid() );
 
 {
   wxASSERT( str.GetStringData()->IsValid() );
 
-  wxCHECK_RET( nIndex <= m_nCount, "bad index in wxArrayString::Insert" );
+  wxCHECK_RET( nIndex <= m_nCount, ("bad index in wxArrayString::Insert") );
 
   Grow();
 
 
   Grow();
 
@@ -1231,7 +1248,7 @@ void wxArrayString::Insert(const wxString& str, size_t nIndex)
 // removes item from array (by index)
 void wxArrayString::Remove(size_t nIndex)
 {
 // removes item from array (by index)
 void wxArrayString::Remove(size_t nIndex)
 {
-  wxCHECK_RET( nIndex <= m_nCount, "bad index in wxArrayString::Remove" );
+  wxCHECK_RET( nIndex <= m_nCount, _("bad index in wxArrayString::Remove") );
 
   // release our lock
   Item(nIndex).GetStringData()->Unlock();
 
   // release our lock
   Item(nIndex).GetStringData()->Unlock();
@@ -1247,14 +1264,14 @@ void wxArrayString::Remove(const char *sz)
   int iIndex = Index(sz);
 
   wxCHECK_RET( iIndex != NOT_FOUND,
   int iIndex = Index(sz);
 
   wxCHECK_RET( iIndex != NOT_FOUND,
-               "removing inexistent element in wxArrayString::Remove" );
+               _("removing inexistent element in wxArrayString::Remove") );
 
   Remove((size_t)iIndex);
 }
 
 // sort array elements using passed comparaison function
 
 
   Remove((size_t)iIndex);
 }
 
 // sort array elements using passed comparaison function
 
-void wxArrayString::Sort(bool bCase, bool bReverse)
+void wxArrayString::Sort(bool WXUNUSED(bCase), bool WXUNUSED(bReverse) )
 {
   //@@@@ TO DO
   //qsort(m_pItems, m_nCount, sizeof(char *), fCmp);
 {
   //@@@@ TO DO
   //qsort(m_pItems, m_nCount, sizeof(char *), fCmp);