+ if(!p)
+ return npos;
+
+ while(p - c_str() + str.length() <= length() &&
+ wxTmemcmp(p, str.c_str(), str.length()) )
+ {
+ //anchor again
+ p = (const wxChar*)wxTmemchr(++p,
+ str.c_str()[0],
+ length() - (p - c_str()));
+
+ if(!p)
+ return npos;
+ }
+
+ return (p - c_str() + str.length() <= length()) ? p - c_str() : npos;
+}
+
+size_t wxStringBase::find(const wxChar* sz, size_t nStart, size_t n) const
+{
+ return find(wxStringBase(sz, n), nStart);
+}
+
+size_t wxStringBase::find(wxChar ch, size_t nStart) const
+{
+ wxASSERT( nStart <= length() );
+
+ const wxChar *p = (const wxChar*)wxTmemchr(c_str() + nStart, ch, length() - nStart);
+
+ return p == NULL ? npos : p - c_str();
+}
+
+size_t wxStringBase::rfind(const wxStringBase& str, size_t nStart) const
+{
+ wxASSERT( str.GetStringData()->IsValid() );
+ wxASSERT( nStart == npos || nStart <= length() );
+
+ if ( length() >= str.length() )
+ {
+ // avoids a corner case later
+ if ( length() == 0 && str.length() == 0 )
+ return 0;
+
+ // "top" is the point where search starts from
+ size_t top = length() - str.length();
+
+ if ( nStart == npos )
+ nStart = length() - 1;
+ if ( nStart < top )
+ top = nStart;
+
+ const wxChar *cursor = c_str() + top;
+ do
+ {
+ if ( wxTmemcmp(cursor, str.c_str(),
+ str.length()) == 0 )
+ {
+ return cursor - c_str();
+ }
+ } while ( cursor-- > c_str() );
+ }
+
+ return npos;
+}
+
+size_t wxStringBase::rfind(const wxChar* sz, size_t nStart, size_t n) const
+{
+ return rfind(wxStringBase(sz, n), nStart);
+}
+
+size_t wxStringBase::rfind(wxChar ch, size_t nStart) const
+{
+ if ( nStart == npos )
+ {
+ nStart = length();
+ }
+ else
+ {
+ wxASSERT( nStart <= length() );
+ }
+
+ const wxChar *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;
+}
+
+size_t wxStringBase::find_first_of(const wxChar* sz, size_t nStart) const
+{
+ wxASSERT(nStart <= length());
+
+ size_t len = wxStrlen(sz);
+
+ size_t i;
+ for(i = nStart; i < this->length(); ++i)
+ {
+ if (wxTmemchr(sz, *(c_str() + i), len))
+ break;
+ }
+
+ if(i == this->length())
+ return npos;
+ else
+ return i;
+}
+
+size_t wxStringBase::find_first_of(const wxChar* sz, size_t nStart,
+ size_t n) const
+{
+ return find_first_of(wxStringBase(sz, n), nStart);
+}
+
+size_t wxStringBase::find_last_of(const wxChar* sz, size_t nStart) const
+{
+ if ( nStart == npos )
+ {
+ nStart = length() - 1;
+ }
+ else
+ {
+ wxASSERT_MSG( nStart <= length(),
+ _T("invalid index in find_last_of()") );
+ }
+
+ size_t len = wxStrlen(sz);
+
+ for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
+ {
+ if ( wxTmemchr(sz, *p, len) )
+ return p - c_str();
+ }
+
+ return npos;
+}
+
+size_t wxStringBase::find_last_of(const wxChar* sz, size_t nStart,
+ size_t n) const
+{
+ return find_last_of(wxStringBase(sz, n), nStart);
+}
+
+size_t wxStringBase::find_first_not_of(const wxChar* sz, size_t nStart) const
+{
+ if ( nStart == npos )
+ {
+ nStart = length();
+ }
+ else
+ {
+ wxASSERT( nStart <= length() );
+ }
+
+ size_t len = wxStrlen(sz);
+
+ size_t i;
+ for(i = nStart; i < this->length(); ++i)
+ {
+ if (!wxTmemchr(sz, *(c_str() + i), len))
+ break;
+ }
+
+ if(i == this->length())
+ return npos;
+ else
+ return i;
+}
+
+size_t wxStringBase::find_first_not_of(const wxChar* sz, size_t nStart,
+ size_t n) const
+{
+ return find_first_not_of(wxStringBase(sz, n), nStart);
+}
+
+size_t wxStringBase::find_first_not_of(wxChar ch, size_t nStart) const
+{
+ wxASSERT( nStart <= length() );
+
+ for ( const wxChar *p = c_str() + nStart; *p; p++ )
+ {
+ if ( *p != ch )
+ return p - c_str();
+ }
+
+ return npos;
+}
+
+size_t wxStringBase::find_last_not_of(const wxChar* sz, size_t nStart) const
+{
+ if ( nStart == npos )
+ {
+ nStart = length() - 1;
+ }
+ else
+ {
+ wxASSERT( nStart <= length() );
+ }
+
+ size_t len = wxStrlen(sz);
+
+ for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
+ {
+ if ( !wxTmemchr(sz, *p,len) )
+ return p - c_str();
+ }
+
+ return npos;
+}
+
+size_t wxStringBase::find_last_not_of(const wxChar* sz, size_t nStart,
+ size_t n) const
+{
+ return find_last_not_of(wxStringBase(sz, n), nStart);
+}
+
+size_t wxStringBase::find_last_not_of(wxChar ch, size_t nStart) const
+{
+ if ( nStart == npos )
+ {
+ nStart = length() - 1;
+ }
+ else
+ {
+ wxASSERT( nStart <= length() );
+ }
+
+ for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
+ {
+ if ( *p != ch )
+ return p - c_str();
+ }
+
+ return npos;
+}
+
+wxStringBase& wxStringBase::replace(size_t nStart, size_t nLen,
+ const wxChar *sz)
+{
+ wxASSERT_MSG( nStart <= length(),
+ _T("index out of bounds in wxStringBase::replace") );
+ size_t strLen = length() - nStart;
+ nLen = strLen < nLen ? strLen : nLen;
+
+ wxStringBase strTmp;
+ strTmp.reserve(length()); // micro optimisation to avoid multiple mem allocs
+
+ if ( nStart != 0 )
+ strTmp.append(c_str(), nStart);
+ strTmp.append(sz);
+ strTmp.append(c_str() + nStart + nLen);
+
+ swap(strTmp);
+ return *this;
+}
+
+wxStringBase& wxStringBase::replace(size_t nStart, size_t nLen,
+ size_t nCount, wxChar ch)
+{
+ return replace(nStart, nLen, wxStringBase(nCount, ch).c_str());
+}
+
+wxStringBase& wxStringBase::replace(size_t nStart, size_t nLen,
+ const wxStringBase& str,
+ size_t nStart2, size_t nLen2)
+{
+ return replace(nStart, nLen, str.substr(nStart2, nLen2));
+}
+
+wxStringBase& wxStringBase::replace(size_t nStart, size_t nLen,
+ const wxChar* sz, size_t nCount)
+{
+ return replace(nStart, nLen, wxStringBase(sz, nCount).c_str());
+}
+
+wxStringBase wxStringBase::substr(size_t nStart, size_t nLen) const
+{
+ if ( nLen == npos )
+ nLen = length() - nStart;
+ return wxStringBase(*this, nStart, nLen);
+}
+
+// assigns one string to another
+wxStringBase& wxStringBase::operator=(const wxStringBase& 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
+wxStringBase& wxStringBase::operator=(wxChar ch)
+{
+ if ( !AssignCopy(1, &ch) ) {
+ wxFAIL_MSG( _T("out of memory in wxStringBase::operator=(wxChar)") );
+ }
+ return *this;
+}
+
+// assigns C string
+wxStringBase& wxStringBase::operator=(const wxChar *psz)
+{
+ if ( !AssignCopy(wxStrlen(psz), psz) ) {
+ wxFAIL_MSG( _T("out of memory in wxStringBase::operator=(const wxChar *)") );
+ }
+ return *this;
+}