]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/stringimpl.cpp
updated wxExecute checks in wxGTK to be same as in other Unix ports after recent...
[wxWidgets.git] / src / common / stringimpl.cpp
index 0f1380e708e43414f43b837cd3d854cdba183d3f..e182044be1eca6debda898501bf2127ba344e0cb 100644 (file)
@@ -30,6 +30,7 @@
 
 #ifndef WX_PRECOMP
     #include "wx/stringimpl.h"
+    #include "wx/wxcrt.h"
 #endif
 
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
 
-#ifdef __SALFORDC__
-    #include <clib.h>
-#endif
-
 // allocating extra space for each string consumes more memory but speeds up
 // the concatenation operations (nLen is the current string's length)
 // NB: EXTRA_ALLOC must be >= 0!
@@ -162,9 +159,9 @@ void wxStringImpl::InitWith(const wxStringCharType *psz,
 
   // if the length is not given, assume the string to be NUL terminated
   if ( nLength == npos ) {
-    wxASSERT_MSG( nPos <= Strsize(psz), _T("index out of bounds") );
+    wxASSERT_MSG( nPos <= wxStrlen(psz), _T("index out of bounds") );
 
-    nLength = Strsize(psz + nPos);
+    nLength = wxStrlen(psz + nPos);
   }
 
   STATISTICS_ADD(InitialLength, nLength);
@@ -183,7 +180,7 @@ wxStringImpl::wxStringImpl(const_iterator first, const_iterator last)
 {
   if ( last >= first )
   {
-    InitWith(first, 0, last - first);
+    InitWith(first.GetPtr(), 0, last - first);
   }
   else
   {
@@ -426,7 +423,7 @@ wxStringImpl& wxStringImpl::insert(size_t nPos,
 {
     wxASSERT( nPos <= length() );
 
-    if ( n == npos ) n = Strsize(sz);
+    if ( n == npos ) n = wxStrlen(sz);
     if ( n == 0 ) return *this;
 
     if ( !Alloc(length() + n) || !CopyBeforeWrite() ) {
@@ -575,54 +572,45 @@ size_t wxStringImpl::rfind(wxStringCharType ch, size_t nStart) const
 }
 
 wxStringImpl& wxStringImpl::replace(size_t nStart, size_t nLen,
-                                    const wxStringCharType *sz)
-{
-  wxASSERT_MSG( nStart <= length(),
-                _T("index out of bounds in wxStringImpl::replace") );
-  size_t strLen = length() - nStart;
-  nLen = strLen < nLen ? strLen : nLen;
-
-  wxStringImpl strTmp;
-  strTmp.reserve(length()); // micro optimisation to avoid multiple mem allocs
-
-  //This is kind of inefficient, but its pretty good considering...
-  //we don't want to use character access operators here because on STL
-  //it will freeze the reference count of strTmp, which means a deep copy
-  //at the end when swap is called
-  //
-  //Also, we can't use append with the full character pointer and must
-  //do it manually because this string can contain null characters
-  for(size_t i1 = 0; i1 < nStart; ++i1)
-      strTmp.append(1, this->c_str()[i1]);
-
-  //its safe to do the full version here because
-  //sz must be a normal c string
-  strTmp.append(sz);
-
-  for(size_t i2 = nStart + nLen; i2 < length(); ++i2)
-      strTmp.append(1, this->c_str()[i2]);
-
-  swap(strTmp);
-  return *this;
-}
-
-wxStringImpl& wxStringImpl::replace(size_t nStart, size_t nLen,
-                                    size_t nCount, wxStringCharType ch)
+                                    const wxStringCharType *sz, size_t nCount)
 {
-  return replace(nStart, nLen, wxStringImpl(nCount, ch).c_str());
-}
+    // check and adjust parameters
+    const size_t lenOld = length();
 
-wxStringImpl& wxStringImpl::replace(size_t nStart, size_t nLen,
-                                    const wxStringImpl& str,
-                                    size_t nStart2, size_t nLen2)
-{
-  return replace(nStart, nLen, str.substr(nStart2, nLen2));
-}
+    wxASSERT_MSG( nStart <= lenOld,
+                  _T("index out of bounds in wxStringImpl::replace") );
+    size_t nEnd = nStart + nLen;
+    if ( nLen > lenOld - nStart )
+    {
+        // nLen may be out of range, as it can be npos, just clump it down
+        nLen = lenOld - nStart;
+        nEnd = lenOld;
+    }
 
-wxStringImpl& wxStringImpl::replace(size_t nStart, size_t nLen,
-                                    const wxStringCharType* sz, size_t nCount)
-{
-  return replace(nStart, nLen, wxStringImpl(sz, nCount).c_str());
+    if ( nCount == npos )
+        nCount = wxStrlen(sz);
+
+    // build the new string from 3 pieces: part of this string before nStart,
+    // the new substring and the part of this string after nStart+nLen
+    wxStringImpl tmp;
+    const size_t lenNew = lenOld + nCount - nLen;
+    if ( lenNew )
+    {
+        tmp.AllocBuffer(lenOld + nCount - nLen);
+
+        wxStringCharType *dst = tmp.m_pchData;
+        memcpy(dst, m_pchData, nStart*sizeof(wxStringCharType));
+        dst += nStart;
+
+        memcpy(dst, sz, nCount*sizeof(wxStringCharType));
+        dst += nCount;
+
+        memcpy(dst, m_pchData + nEnd, (lenOld - nEnd)*sizeof(wxStringCharType));
+    }
+
+    // and replace this string contents with the new one
+    swap(tmp);
+    return *this;
 }
 
 wxStringImpl wxStringImpl::substr(size_t nStart, size_t nLen) const
@@ -666,7 +654,7 @@ wxStringImpl& wxStringImpl::operator=(wxStringCharType ch)
 // assigns C string
 wxStringImpl& wxStringImpl::operator=(const wxStringCharType *psz)
 {
-  if ( !AssignCopy(Strsize(psz), psz) ) {
+  if ( !AssignCopy(wxStrlen(psz), psz) ) {
     wxFAIL_MSG( _T("out of memory in wxStringImpl::operator=(const wxStringCharType *)") );
   }
   return *this;
@@ -708,6 +696,17 @@ bool wxStringImpl::ConcatSelf(size_t nSrcLen,
   if ( nSrcLen > 0 ) {
     wxStringData *pData = GetStringData();
     size_t nLen = pData->nDataLength;
+
+    // take special care when appending part of this string to itself: the code
+    // below reallocates our buffer and this invalidates pszSrcData pointer so
+    // we have to copy it in another temporary string in this case (but avoid
+    // doing this unnecessarily)
+    if ( pszSrcData >= m_pchData && pszSrcData < m_pchData + nLen )
+    {
+        wxStringImpl tmp(pszSrcData, nSrcLen);
+        return ConcatSelf(nSrcLen, tmp.m_pchData, nSrcLen);
+    }
+
     size_t nNewLen = nLen + nSrcLen;
 
     // alloc new buffer if current is too small
@@ -752,9 +751,8 @@ bool wxStringImpl::ConcatSelf(size_t nSrcLen,
   return true;
 }
 
-#if !wxUSE_UNICODE_UTF8
 // get the pointer to writable buffer of (at least) nLen bytes
-wxChar *wxStringImpl::DoGetWriteBuf(size_t nLen)
+wxStringCharType *wxStringImpl::DoGetWriteBuf(size_t nLen)
 {
   if ( !AllocBeforeWrite(nLen) ) {
     // allocation failure handled by caller
@@ -770,7 +768,7 @@ wxChar *wxStringImpl::DoGetWriteBuf(size_t nLen)
 // put string back in a reasonable state after GetWriteBuf
 void wxStringImpl::DoUngetWriteBuf()
 {
-  DoUngetWriteBuf(Strsize(m_pchData));
+  DoUngetWriteBuf(wxStrlen(m_pchData));
 }
 
 void wxStringImpl::DoUngetWriteBuf(size_t nLen)
@@ -784,6 +782,5 @@ void wxStringImpl::DoUngetWriteBuf(size_t nLen)
   pData->nDataLength = nLen;
   pData->Validate(true);
 }
-#endif // !wxUSE_UNICODE_UTF8
 
 #endif // !wxUSE_STL_BASED_WXSTRING