- const wxStringCharType *actual;
- for ( actual = c_str() + ( nStart == npos ? length() : nStart + 1 );
- actual > c_str(); --actual )
- {
- if ( *(actual - 1) == ch )
- return (actual - 1) - c_str();
- }
-
- return npos;
-}
-
-wxStringImpl& wxStringImpl::replace(size_t nStart, size_t nLen,
- const wxChar *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)
-{
- return replace(nStart, nLen, wxStringImpl(nCount, ch).c_str());
-}
-
-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));
-}
-
-wxStringImpl& wxStringImpl::replace(size_t nStart, size_t nLen,
- const wxChar* sz, size_t nCount)
-{
- return replace(nStart, nLen, wxStringImpl(sz, nCount).c_str());
-}
-
-wxStringImpl wxStringImpl::substr(size_t nStart, size_t nLen) const
-{
- if ( nLen == npos )
- nLen = length() - nStart;
- return wxStringImpl(*this, nStart, nLen);
-}
-
-// assigns one string to another
-wxStringImpl& wxStringImpl::operator=(const wxStringImpl& stringSrc)
-{
- wxASSERT( stringSrc.GetStringData()->IsValid() );
-
- // don't copy string over itself
- if ( m_pchData != stringSrc.m_pchData ) {
- if ( stringSrc.GetStringData()->IsEmpty() ) {
- Reinit();
- }
- else {
- // adjust references
- GetStringData()->Unlock();
- m_pchData = stringSrc.m_pchData;
- GetStringData()->Lock();
- }
- }
-
- return *this;
-}
-
-// assigns a single character
-wxStringImpl& wxStringImpl::operator=(wxStringCharType ch)
-{
- wxChar c(ch);
- if ( !AssignCopy(1, &c) ) {
- wxFAIL_MSG( _T("out of memory in wxStringImpl::operator=(wxChar)") );
- }
- return *this;
-}
-
-// assigns C string
-wxStringImpl& wxStringImpl::operator=(const wxChar *psz)
-{
- if ( !AssignCopy(wxStrlen(psz), psz) ) {
- wxFAIL_MSG( _T("out of memory in wxStringImpl::operator=(const wxChar *)") );
- }
- return *this;
-}
-
-// helper function: does real copy
-bool wxStringImpl::AssignCopy(size_t nSrcLen, const wxChar *pszSrcData)
-{
- if ( nSrcLen == 0 ) {
- Reinit();
- }
- else {
- if ( !AllocBeforeWrite(nSrcLen) ) {
- // allocation failure handled by caller
- return false;
- }
- memcpy(m_pchData, pszSrcData, nSrcLen*sizeof(wxChar));
- GetStringData()->nDataLength = nSrcLen;
- m_pchData[nSrcLen] = wxT('\0');
- }
- return true;
-}
-
-// ---------------------------------------------------------------------------
-// string concatenation
-// ---------------------------------------------------------------------------
-
-// add something to this string
-bool wxStringImpl::ConcatSelf(size_t nSrcLen, const wxChar *pszSrcData,
- size_t nMaxLen)
-{
- STATISTICS_ADD(SummandLength, nSrcLen);
-
- nSrcLen = nSrcLen < nMaxLen ? nSrcLen : nMaxLen;
-
- // concatenating an empty string is a NOP
- if ( nSrcLen > 0 ) {
- wxStringData *pData = GetStringData();
- size_t nLen = pData->nDataLength;
- size_t nNewLen = nLen + nSrcLen;
-
- // alloc new buffer if current is too small
- if ( pData->IsShared() ) {
- STATISTICS_ADD(ConcatHit, 0);
-
- // we have to allocate another buffer
- wxStringData* pOldData = GetStringData();
- if ( !AllocBuffer(nNewLen) ) {
- // allocation failure handled by caller
- return false;
- }
- memcpy(m_pchData, pOldData->data(), nLen*sizeof(wxChar));
- pOldData->Unlock();
- }
- else if ( nNewLen > pData->nAllocLength ) {
- STATISTICS_ADD(ConcatHit, 0);
-
- reserve(nNewLen);
- // we have to grow the buffer
- if ( capacity() < nNewLen ) {
- // allocation failure handled by caller
- return false;
- }
- }
- else {
- STATISTICS_ADD(ConcatHit, 1);
-
- // the buffer is already big enough
- }
-
- // should be enough space
- wxASSERT( nNewLen <= GetStringData()->nAllocLength );
-
- // fast concatenation - all is done in our buffer
- memcpy(m_pchData + nLen, pszSrcData, nSrcLen*sizeof(wxChar));
-
- m_pchData[nNewLen] = wxT('\0'); // put terminating '\0'
- GetStringData()->nDataLength = nNewLen; // and fix the length
- }
- //else: the string to append was empty
- return true;
-}
-
-#endif // !wxUSE_STL_BASED_WXSTRING
-
-#ifdef HAVE_STD_STRING_COMPARE
-
-// NB: Comparison code (both if HAVE_STD_STRING_COMPARE and if not) works with
-// UTF-8 encoded strings too, thanks to UTF-8's design which allows us to
-// sort strings in characters code point order by sorting the byte sequence
-// in byte values order (i.e. what strcmp() and memcmp() do).
-
-int wxString::compare(const wxString& str) const
-{
- return m_impl.compare(str.m_impl);
-}
-
-int wxString::compare(size_t nStart, size_t nLen,
- const wxString& str) const
-{
- size_t pos, len;
- PosLenToImpl(nStart, nLen, &pos, &len);
- return m_impl.compare(pos, len, str.m_impl);
-}
-
-int wxString::compare(size_t nStart, size_t nLen,
- const wxString& str,
- size_t nStart2, size_t nLen2) const
-{
- size_t pos, len;
- PosLenToImpl(nStart, nLen, &pos, &len);
-
- size_t pos2, len2;
- str.PosLenToImpl(nStart2, nLen2, &pos2, &len2);
-
- return m_impl.compare(pos, len, str.m_impl, pos2, len2);
-}
-
-int wxString::compare(const char* sz) const
-{
- return m_impl.compare(ImplStr(sz));