wxASSERT( str.GetStringData()->IsValid() );
wxASSERT( nStart <= length() );
- const wxChar *p = wxStrstr(c_str() + nStart, str.c_str());
+ //anchor
+ const wxChar* p = (const wxChar*)wxMemchr(c_str() + nStart,
+ str.c_str()[0],
+ length() - nStart);
+
+ if(!p)
+ return npos;
+
+ while(p - c_str() + str.length() <= length() &&
+ wxMemcmp(p, str.c_str(), str.length()) )
+ {
+ //anchor again
+ p = (const wxChar*)wxMemchr(++p,
+ str.c_str()[0],
+ length() - (p - c_str()));
- return p == NULL ? npos : 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
{
wxASSERT( nStart <= length() );
- const wxChar *p = wxStrchr(c_str() + nStart, ch);
+ const wxChar *p = (const wxChar*)wxMemchr(c_str() + nStart, ch, length() - nStart);
return p == NULL ? npos : p - c_str();
}
const wxChar *cursor = c_str() + top;
do
{
- if ( memcmp(cursor, str.c_str(),
- str.length() * sizeof(wxChar)) == 0 )
+ if ( wxMemcmp(cursor, str.c_str(),
+ str.length()) == 0 )
{
return cursor - c_str();
}
size_t wxStringBase::find_first_of(const wxChar* sz, size_t nStart) const
{
- const wxChar *start = c_str() + nStart;
- const wxChar *firstOf = wxStrpbrk(start, sz);
- if ( firstOf )
- return firstOf - c_str();
- else
+ wxASSERT(nStart <= length());
+
+ size_t len = wxStrlen(sz);
+
+ size_t i;
+ for(i = nStart; i < this->length(); ++i)
+ {
+ if (wxMemchr(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,
_T("invalid index in find_last_of()") );
}
+ size_t len = wxStrlen(sz);
+
for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
{
- if ( wxStrchr(sz, *p) )
+ if ( wxMemchr(sz, *p, len) )
return p - c_str();
}
wxASSERT( nStart <= length() );
}
- size_t nAccept = wxStrspn(c_str() + nStart, sz);
- if ( nAccept >= length() - nStart )
- return npos;
- else
- return nStart + nAccept;
+ size_t len = wxStrlen(sz);
+
+ size_t i;
+ for(i = nStart; i < this->length(); ++i)
+ {
+ if (!wxMemchr(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,
wxASSERT( nStart <= length() );
}
+ size_t len = wxStrlen(sz);
+
for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
{
- if ( !wxStrchr(sz, *p) )
- return p - c_str();
+ if ( !wxMemchr(sz, *p,len) )
+ return p - c_str();
}
return npos;
const wxChar* s2, size_t l2)
{
if( l1 == l2 )
- return wxStrncmp(s1, s2, l1);
+ return wxMemcmp(s1, s2, l1);
else if( l1 < l2 )
{
- int ret = wxStrncmp(s1, s2, l1);
+ int ret = wxMemcmp(s1, s2, l1);
return ret == 0 ? -1 : ret;
}
else if( l1 > l2 )
{
- int ret = wxStrncmp(s1, s2, l2);
+ int ret = wxMemcmp(s1, s2, l2);
return ret == 0 ? +1 : ret;
}
return 0; // quiet compilers
}
-#if wxUSE_STL
-
int STRINGCLASS::compare(const wxStringBase& str) const
{
return ::wxDoCmp(data(), length(), str.data(), str.length());
}
-#endif
-
int STRINGCLASS::compare(size_t nStart, size_t nLen,
const wxStringBase& str) const
{
return ::wxDoCmp(data() + nStart, nLen, str.data() + nStart2, nLen2);
}
-#if wxUSE_STL
-
int STRINGCLASS::compare(const wxChar* sz) const
{
size_t nLen = wxStrlen(sz);
return ::wxDoCmp(data(), length(), sz, nLen);
}
-#endif
-
int STRINGCLASS::compare(size_t nStart, size_t nLen,
const wxChar* sz, size_t nCount) const
{
//else: the conversion failed -- leave the string empty (what else?)
}
}
+}
+
+const wxCharBuffer wxString::mb_str(wxMBConv& conv) const
+{
+ const wxChar* szEnd = (*this).c_str() + length() + 1;
+ const wxChar* szPos = (*this).c_str();
+ const wxChar* szStart = szPos;
+
+ wxCharBuffer buffer(length() + 1);
+
+ //Convert the string until the length() is reached, continuing the
+ //loop every time a null character is reached
+ while(szPos != szEnd)
+ {
+ size_t nLen = conv.WC2MB(NULL, szPos, 0);
+
+ wxASSERT(nLen != (size_t)-1); //should not be true! If it is system wctomb could be bad
+
+ if ( conv.WC2MB(&buffer.data()[szPos - szStart], szPos, nLen + 1) == (size_t)-1 )
+ {
+ //error - return empty buffer
+ wxFAIL_MSG(wxT("Error converting wide-character string to a multi-byte string"));
+ buffer.data()[0] = '\0';
+ return buffer;
+ }
+
+ szPos += nLen + 1;
+ }
+
+ return buffer;
}
#else // ANSI
// leave empty
}
+
+const wxWCharBuffer wxString::wc_str(wxMBConv& conv) const
+{
+ const wxChar* szEnd = (*this).c_str() + length() + 1;
+ const wxChar* szPos = (*this).c_str();
+ const wxChar* szStart = szPos;
+
+ wxWCharBuffer buffer(length() + 1);
+
+ //Convert the string until the length() is reached, continuing the
+ //loop every time a null character is reached
+ while(szPos != szEnd)
+ {
+ size_t nLen = conv.MB2WC(NULL, szPos, 0);
+
+ wxASSERT(nLen != (size_t)-1); //should not be true! If it is system mbtowc could be bad
+
+ if ( conv.MB2WC(&buffer.data()[szPos - szStart], szPos, nLen + 1) == (size_t)-1 )
+ {
+ //error - return empty buffer
+ wxFAIL_MSG(wxT("Error converting multi-byte string to a wide-character string"));
+ buffer.data()[0] = '\0';
+ return buffer;
+ }
+
+ szPos += nLen + 1;
+ }
+
+ return buffer;
+}
+
#endif // wxUSE_WCHAR_T
#endif // Unicode/ANSI
// other common string functions
// ===========================================================================
+int wxString::Cmp(const wxString& s) const
+{
+ return compare(s);
+}
+
+int wxString::Cmp(const wxChar* psz) const
+{
+ return compare(psz);
+}
+
+static inline int wxDoCmpNoCase(const wxChar* s1, size_t l1,
+ const wxChar* s2, size_t l2)
+{
+ size_t i;
+
+ if( l1 == l2 )
+ {
+ for(i = 0; i < l1; ++i)
+ {
+ if(wxTolower(s1[i]) != wxTolower(s2[i]))
+ break;
+ }
+ return i == l1 ? 0 : s1[i] < s2[i] ? -1 : 1;
+ }
+ else if( l1 < l2 )
+ {
+ for(i = 0; i < l1; ++i)
+ {
+ if(wxTolower(s1[i]) != wxTolower(s2[i]))
+ break;
+ }
+ return i == l1 ? -1 : s1[i] < s2[i] ? -1 : 1;
+ }
+ else if( l1 > l2 )
+ {
+ for(i = 0; i < l2; ++i)
+ {
+ if(wxTolower(s1[i]) != wxTolower(s2[i]))
+ break;
+ }
+ return i == l2 ? 1 : s1[i] < s2[i] ? -1 : 1;
+ }
+
+ wxFAIL; // must never get there
+ return 0; // quiet compilers
+}
+
+int wxString::CmpNoCase(const wxString& s) const
+{
+ return wxDoCmpNoCase(data(), length(), s.data(), s.length());
+}
+
+int wxString::CmpNoCase(const wxChar* psz) const
+{
+ int nLen = wxStrlen(psz);
+
+ return wxDoCmpNoCase(data(), length(), psz, nLen);
+}
+
+
#if wxUSE_UNICODE
+#ifdef __MWERKS__
+#ifndef __SCHAR_MAX__
+#define __SCHAR_MAX__ 127
+#endif
+#endif
+
wxString wxString::FromAscii(const char *ascii)
{
if (!ascii)
return -1;
}
- len = wxVsnprintf(buf, size, pszFormat, argptr);
+ // wxVsnprintf() may modify the original arg pointer, so pass it
+ // only a copy
+ va_list argptrcopy;
+ wxVaCopy(argptrcopy, argptr);
+ len = wxVsnprintf(buf, size, pszFormat, argptrcopy);
+ va_end(argptrcopy);
// some implementations of vsnprintf() don't NUL terminate
// the string if there is not enough space for it so
while ( lo < hi ) {
i = (lo + hi)/2;
- res = wxStrcmp(str, m_pItems[i]);
+ res = str.Cmp(m_pItems[i]);
if ( res < 0 )
hi = i;
else if ( res > 0 )
}
else {
// maybe we should use wxStrcoll
- int result = wxStrcmp(strFirst->c_str(), strSecond->c_str());
+ int result = strFirst->Cmp(*strSecond);
return gs_sortAscending ? result : -result;
}
int wxCMPFUNC_CONV wxStringSortAscending(wxString* s1, wxString* s2)
{
- return wxStrcmp(s1->c_str(), s2->c_str());
+ return s1->Cmp(*s2);
}
int wxCMPFUNC_CONV wxStringSortDescending(wxString* s1, wxString* s2)
{
- return -wxStrcmp(s1->c_str(), s2->c_str());
+ return -s1->Cmp(*s2);
}