X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/817270659e986de1b243586d8eb6ad3a76c87480..180b5b4827d08f1ac13bbb5eca03f775ab35a0b1:/src/common/stringimpl.cpp diff --git a/src/common/stringimpl.cpp b/src/common/stringimpl.cpp index 0f1380e708..c8799442c3 100644 --- a/src/common/stringimpl.cpp +++ b/src/common/stringimpl.cpp @@ -30,6 +30,7 @@ #ifndef WX_PRECOMP #include "wx/stringimpl.h" + #include "wx/wxcrt.h" #endif #include @@ -162,9 +163,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); @@ -426,7 +427,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 +576,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 +658,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 +700,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 +755,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 +772,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 +786,5 @@ void wxStringImpl::DoUngetWriteBuf(size_t nLen) pData->nDataLength = nLen; pData->Validate(true); } -#endif // !wxUSE_UNICODE_UTF8 #endif // !wxUSE_STL_BASED_WXSTRING