X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e87b78335291c67025c5a763c2acfb22343f9908..121680bff0940ec8614a6e296c605def31099239:/src/common/string.cpp?ds=sidebyside diff --git a/src/common/string.cpp b/src/common/string.cpp index 995433e317..9a0cff0e00 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -9,7 +9,7 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "string.h" #endif @@ -100,6 +100,8 @@ extern const wxChar WXDLLIMPEXP_BASE *wxEmptyString = &g_strEmpty.dummy; // // ATTN: you can _not_ use both of these in the same program! +#include + wxSTD istream& operator>>(wxSTD istream& is, wxString& WXUNUSED(str)) { #if 0 @@ -168,6 +170,8 @@ wxSTD ostream& operator<<(wxSTD ostream& os, const wxString& str) #define STATISTICS_ADD(av, val) #endif // WXSTRING_STATISTICS +#if !wxUSE_STL + // =========================================================================== // wxStringData class deallocation // =========================================================================== @@ -180,8 +184,6 @@ void wxStringData::Free() } #endif -#if !wxUSE_STL - // =========================================================================== // wxStringBase // =========================================================================== @@ -468,8 +470,6 @@ size_t wxStringBase::find(const wxChar* sz, size_t nStart, size_t n) const return find(wxStringBase(sz, n), nStart); } -// Gives a duplicate symbol (presumably a case-insensitivity problem) -#if !defined(__BORLANDC__) size_t wxStringBase::find(wxChar ch, size_t nStart) const { wxASSERT( nStart <= length() ); @@ -478,22 +478,38 @@ size_t wxStringBase::find(wxChar ch, size_t nStart) const return p == NULL ? npos : p - c_str(); } -#endif size_t wxStringBase::rfind(const wxStringBase& str, size_t nStart) const { - wxASSERT( str.GetStringData()->IsValid() ); - wxASSERT( nStart == npos || nStart <= length() ); - - // TODO could be made much quicker than that - const wxChar *p = c_str() + (nStart == npos ? length() : nStart); - while ( p >= c_str() + str.length() ) { - if ( wxStrncmp(p - str.length(), str.c_str(), str.length()) == 0 ) - return p - str.length() - c_str(); - p--; - } + 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(); - return npos; + if ( nStart == npos ) + nStart = length() - 1; + if ( nStart < top ) + top = nStart; + + const wxChar *cursor = c_str() + top; + do + { + if ( memcmp(cursor, str.c_str(), + str.length() * sizeof(wxChar)) == 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 @@ -512,13 +528,15 @@ size_t wxStringBase::rfind(wxChar ch, size_t nStart) const wxASSERT( nStart <= length() ); } - const wxChar *p = wxStrrchr(c_str(), ch); - - if ( p == NULL ) - return npos; + 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(); + } - size_t result = p - c_str(); - return ( result > nStart ) ? npos : result; + return npos; } size_t wxStringBase::find_first_of(const wxChar* sz, size_t nStart) const @@ -531,18 +549,25 @@ size_t wxStringBase::find_first_of(const wxChar* sz, size_t nStart) const return npos; } +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(); + nStart = length() - 1; } else { - wxASSERT( nStart <= length() ); + wxASSERT_MSG( nStart <= length(), + _T("invalid index in find_last_of()") ); } - for ( const wxChar *p = c_str() + length() - 1; p >= c_str(); p-- ) + for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p ) { if ( wxStrchr(sz, *p) ) return p - c_str(); @@ -551,6 +576,12 @@ size_t wxStringBase::find_last_of(const wxChar* sz, size_t nStart) const 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 ) @@ -566,7 +597,13 @@ size_t wxStringBase::find_first_not_of(const wxChar* sz, size_t nStart) const if ( nAccept >= length() - nStart ) return npos; else - return nAccept; + return nStart + nAccept; +} + +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 @@ -586,14 +623,14 @@ size_t wxStringBase::find_last_not_of(const wxChar* sz, size_t nStart) const { if ( nStart == npos ) { - nStart = length(); + nStart = length() - 1; } else { wxASSERT( nStart <= length() ); } - for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- ) + for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p ) { if ( !wxStrchr(sz, *p) ) return p - c_str(); @@ -602,18 +639,24 @@ size_t wxStringBase::find_last_not_of(const wxChar* sz, size_t nStart) const 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(); + nStart = length() - 1; } else { wxASSERT( nStart <= length() ); } - for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- ) + for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p ) { if ( *p != ch ) return p - c_str(); @@ -1644,7 +1687,10 @@ int wxString::PrintfV(const wxChar* pszFormat, va_list argptr) buf[size] = _T('\0'); } - if ( len >= 0 ) + // vsnprintf() may return either -1 (traditional Unix behaviour) or the + // total number of characters which would have been written if the + // buffer were large enough + if ( len >= 0 && len <= size ) { // ok, there was enough space break; @@ -1963,6 +2009,11 @@ wxArrayString::~wxArrayString() wxDELETEA(m_pItems); } +void wxArrayString::reserve(size_t nSize) +{ + Alloc(nSize); +} + // pre-allocates memory (frees the previous data!) void wxArrayString::Alloc(size_t nSize) { @@ -2167,6 +2218,13 @@ void wxArrayString::Remove(const wxChar *sz) RemoveAt(iIndex); } +void wxArrayString::assign(const_iterator first, const_iterator last) +{ + reserve(last - first); + for(; first != last; ++first) + push_back(*first); +} + // ---------------------------------------------------------------------------- // sorting // ---------------------------------------------------------------------------- @@ -2269,12 +2327,12 @@ bool wxArrayString::operator==(const wxArrayString& a) const #endif // !wxUSE_STL -int wxStringSortAscending(wxString* s1, wxString* s2) +int wxCMPFUNC_CONV wxStringSortAscending(wxString* s1, wxString* s2) { return wxStrcmp(s1->c_str(), s2->c_str()); } -int wxStringSortDescending(wxString* s1, wxString* s2) +int wxCMPFUNC_CONV wxStringSortDescending(wxString* s1, wxString* s2) { return -wxStrcmp(s1->c_str(), s2->c_str()); }