X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3168a13f907e99a97a835514ab1832f0151f040c..d1427b705318677afe28b1291867f6930c8823a7:/src/common/string.cpp diff --git a/src/common/string.cpp b/src/common/string.cpp index c2246e4991..1273610fb6 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -34,6 +34,7 @@ #ifndef WX_PRECOMP #include "wx/defs.h" #include "wx/string.h" +#include #endif #include @@ -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) -#define EXTRA_ALLOC 16 +// NB: EXTRA_ALLOC must be >= 0! +#define EXTRA_ALLOC (19 - nLen % 16) // --------------------------------------------------------------------------- // static class variables definition @@ -258,7 +260,7 @@ void wxString::CopyBeforeWrite() 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 @@ -282,13 +284,22 @@ void wxString::Alloc(uint 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 - uint nLen = pData->nDataLength; + uint nOldLen = pData->nDataLength; AllocBuffer(nLen); - memcpy(m_pchData, pData->data(), nLen*sizeof(char)); + memcpy(m_pchData, pData->data(), nOldLen*sizeof(char)); } else { nLen += EXTRA_ALLOC; @@ -314,8 +325,14 @@ void wxString::Alloc(uint nLen) 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! } @@ -1064,30 +1081,26 @@ wxArrayString::wxArrayString() // 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) { - 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 *)); @@ -1106,8 +1119,13 @@ void wxArrayString::Grow() 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 - 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; @@ -1117,7 +1135,7 @@ void wxArrayString::Grow() 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; } @@ -1147,8 +1165,7 @@ void wxArrayString::Clear() m_nSize = m_nCount = 0; - DELETEA(m_pItems); - m_pItems = NULL; + wxDELETEA(m_pItems); } // dtor @@ -1156,7 +1173,7 @@ wxArrayString::~wxArrayString() { Free(); - DELETEA(m_pItems); + wxDELETEA(m_pItems); } // 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(); - DELETEA(m_pItems); + wxDELETEA(m_pItems); 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() ); - wxCHECK_RET( nIndex <= m_nCount, "bad index in wxArrayString::Insert" ); + wxCHECK_RET( nIndex <= m_nCount, ("bad index in wxArrayString::Insert") ); 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) { - 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(); @@ -1247,14 +1264,14 @@ void wxArrayString::Remove(const char *sz) 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 -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);