// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "string.h"
#endif
//
// ATTN: you can _not_ use both of these in the same program!
+#include <iostream>
+
wxSTD istream& operator>>(wxSTD istream& is, wxString& WXUNUSED(str))
{
#if 0
#define STATISTICS_ADD(av, val)
#endif // WXSTRING_STATISTICS
+#if !wxUSE_STL
+
// ===========================================================================
// wxStringData class deallocation
// ===========================================================================
}
#endif
-#if !wxUSE_STL
-
// ===========================================================================
// wxStringBase
// ===========================================================================
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
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
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
{
_T("invalid index in find_last_of()") );
}
- 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();
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 )
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
{
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();
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();
}
else
{
- wxWCharBuffer buf(nLen + 1);
+ // the input buffer to MB2WC must always be NUL-terminated
+ wxCharBuffer inBuf(nLen);
+ memcpy(inBuf.data(), psz, nLen);
+ inBuf.data()[nLen] = '\0';
+
+ wxWCharBuffer buf(nLen);
// MB2WC wants the buffer size, not the string length hence +1
- nLen = conv.MB2WC(buf.data(), psz, nLen + 1);
+ nLen = conv.MB2WC(buf.data(), inBuf.data(), nLen + 1);
if ( nLen != (size_t)-1 )
{
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;
wxDELETEA(m_pItems);
}
+void wxArrayString::reserve(size_t nSize)
+{
+ Alloc(nSize);
+}
+
// pre-allocates memory (frees the previous data!)
void wxArrayString::Alloc(size_t nSize)
{
RemoveAt(iIndex);
}
+void wxArrayString::assign(const_iterator first, const_iterator last)
+{
+ reserve(last - first);
+ for(; first != last; ++first)
+ push_back(*first);
+}
+
// ----------------------------------------------------------------------------
// sorting
// ----------------------------------------------------------------------------
#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());
}