-int wxString::sprintf(const wxChar *pszFormat, ...)
- {
- va_list argptr;
- va_start(argptr, pszFormat);
- int iLen = PrintfV(pszFormat, argptr);
- va_end(argptr);
- return iLen;
- }
-
-// ---------------------------------------------------------------------------
-// standard C++ library string functions
-// ---------------------------------------------------------------------------
-
-#ifdef wxSTD_STRING_COMPATIBILITY
-
-void wxString::resize(size_t nSize, wxChar ch)
-{
- size_t len = length();
-
- if ( nSize < len )
- {
- Truncate(nSize);
- }
- else if ( nSize > len )
- {
- *this += wxString(ch, nSize - len);
- }
- //else: we have exactly the specified length, nothing to do
-}
-
-void wxString::swap(wxString& str)
-{
- // this is slightly less efficient than fiddling with m_pchData directly,
- // but it is still quite efficient as we don't copy the string here because
- // ref count always stays positive
- wxString tmp = str;
- str = *this;
- *this = tmp;
-}
-
-wxString& wxString::insert(size_t nPos, const wxString& str)
-{
- wxASSERT( str.GetStringData()->IsValid() );
- wxASSERT( nPos <= Len() );
-
- if ( !str.IsEmpty() ) {
- wxString strTmp;
- wxChar *pc = strTmp.GetWriteBuf(Len() + str.Len());
- wxStrncpy(pc, c_str(), nPos);
- wxStrcpy(pc + nPos, str);
- wxStrcpy(pc + nPos + str.Len(), c_str() + nPos);
- strTmp.UngetWriteBuf();
- *this = strTmp;
- }
-
- return *this;
-}
-
-size_t wxString::find(const wxString& str, size_t nStart) const
-{
- wxASSERT( str.GetStringData()->IsValid() );
- wxASSERT( nStart <= Len() );
-
- const wxChar *p = wxStrstr(c_str() + nStart, str);
-
- return p == NULL ? npos : p - c_str();
-}
-
-// VC++ 1.5 can't cope with the default argument in the header.
-#if !defined(__VISUALC__) || defined(__WIN32__)
-size_t wxString::find(const wxChar* sz, size_t nStart, size_t n) const
-{
- return find(wxString(sz, n), nStart);
-}
-#endif // VC++ 1.5
-
-// Gives a duplicate symbol (presumably a case-insensitivity problem)
-#if !defined(__BORLANDC__)
-size_t wxString::find(wxChar ch, size_t nStart) const
-{
- wxASSERT( nStart <= Len() );
-
- const wxChar *p = wxStrchr(c_str() + nStart, ch);
-
- return p == NULL ? npos : p - c_str();
-}
-#endif
-
-size_t wxString::rfind(const wxString& str, size_t nStart) const
-{
- wxASSERT( str.GetStringData()->IsValid() );
- wxASSERT( nStart == npos || nStart <= Len() );
-
- // TODO could be made much quicker than that
- const wxChar *p = c_str() + (nStart == npos ? Len() : nStart);
- while ( p >= c_str() + str.Len() ) {
- if ( wxStrncmp(p - str.Len(), str, str.Len()) == 0 )
- return p - str.Len() - c_str();
- p--;
- }
-
- return npos;
-}
-
-// VC++ 1.5 can't cope with the default argument in the header.
-#if !defined(__VISUALC__) || defined(__WIN32__)
-size_t wxString::rfind(const wxChar* sz, size_t nStart, size_t n) const
-{
- return rfind(wxString(sz, n == npos ? wxSTRING_MAXLEN : n), nStart);
-}
-
-size_t wxString::rfind(wxChar ch, size_t nStart) const
-{
- if ( nStart == npos )
- {
- nStart = Len();
- }
- else
- {
- wxASSERT( nStart <= Len() );
- }
-
- const wxChar *p = wxStrrchr(c_str(), ch);
-
- if ( p == NULL )
- return npos;
-
- size_t result = p - c_str();
- return ( result > nStart ) ? npos : result;
-}
-#endif // VC++ 1.5
-
-size_t wxString::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
- return npos;
-}
-
-size_t wxString::find_last_of(const wxChar* sz, size_t nStart) const
-{
- if ( nStart == npos )
- {
- nStart = Len();
- }
- else
- {
- wxASSERT( nStart <= Len() );
- }
-
- for ( const wxChar *p = c_str() + length() - 1; p >= c_str(); p-- )
- {
- if ( wxStrchr(sz, *p) )
- return p - c_str();
- }
-
- return npos;
-}
-
-size_t wxString::find_first_not_of(const wxChar* sz, size_t nStart) const
-{
- if ( nStart == npos )
- {
- nStart = Len();
- }
- else
- {
- wxASSERT( nStart <= Len() );
- }
-
- size_t nAccept = wxStrspn(c_str() + nStart, sz);
- if ( nAccept >= length() - nStart )
- return npos;
- else
- return nAccept;
-}
-
-size_t wxString::find_first_not_of(wxChar ch, size_t nStart) const
-{
- wxASSERT( nStart <= Len() );
-
- for ( const wxChar *p = c_str() + nStart; *p; p++ )
- {
- if ( *p != ch )
- return p - c_str();
- }
-
- return npos;
-}
-
-size_t wxString::find_last_not_of(const wxChar* sz, size_t nStart) const
-{
- if ( nStart == npos )
- {
- nStart = Len();
- }
- else
- {
- wxASSERT( nStart <= Len() );
- }
-
- for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- )
- {
- if ( !wxStrchr(sz, *p) )
- return p - c_str();
- }
-
- return npos;
-}
-
-size_t wxString::find_last_not_of(wxChar ch, size_t nStart) const
-{
- if ( nStart == npos )
- {
- nStart = Len();
- }
- else
- {
- wxASSERT( nStart <= Len() );
- }
-
- for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- )
- {
- if ( *p != ch )
- return p - c_str();
- }
-
- return npos;
-}
-
-wxString& wxString::erase(size_t nStart, size_t nLen)
-{
- wxString strTmp(c_str(), nStart);
- if ( nLen != npos ) {
- wxASSERT( nStart + nLen <= Len() );
-
- strTmp.append(c_str() + nStart + nLen);
- }
-
- *this = strTmp;
- return *this;
-}
-
-wxString& wxString::replace(size_t nStart, size_t nLen, const wxChar *sz)
-{
- wxASSERT_MSG( nStart + nLen <= Len(),
- _T("index out of bounds in wxString::replace") );
-
- wxString strTmp;
- strTmp.Alloc(Len()); // micro optimisation to avoid multiple mem allocs
-
- if ( nStart != 0 )
- strTmp.append(c_str(), nStart);
- strTmp << sz << c_str() + nStart + nLen;
-
- *this = strTmp;
- return *this;
-}
-
-wxString& wxString::replace(size_t nStart, size_t nLen, size_t nCount, wxChar ch)
-{
- return replace(nStart, nLen, wxString(ch, nCount));
-}
-
-wxString& wxString::replace(size_t nStart, size_t nLen,
- const wxString& str, size_t nStart2, size_t nLen2)
-{
- return replace(nStart, nLen, str.substr(nStart2, nLen2));
-}
-
-wxString& wxString::replace(size_t nStart, size_t nLen,
- const wxChar* sz, size_t nCount)
-{
- return replace(nStart, nLen, wxString(sz, nCount));
-}
-
-#endif //std::string compatibility
-
-// ============================================================================
-// ArrayString
-// ============================================================================
-
-// size increment = min(50% of current size, ARRAY_MAXSIZE_INCREMENT)
-#define ARRAY_MAXSIZE_INCREMENT 4096
-
-#ifndef ARRAY_DEFAULT_INITIAL_SIZE // also defined in dynarray.h
-#define ARRAY_DEFAULT_INITIAL_SIZE (16)
-#endif
-
-#define STRING(p) ((wxString *)(&(p)))
-
-// ctor
-void wxArrayString::Init(bool autoSort)
-{
- m_nSize =
- m_nCount = 0;
- m_pItems = (wxChar **) NULL;
- m_autoSort = autoSort;
-}
-
-// copy ctor
-wxArrayString::wxArrayString(const wxArrayString& src)
-{
- Init(src.m_autoSort);
-
- *this = src;
-}
-
-// assignment operator
-wxArrayString& wxArrayString::operator=(const wxArrayString& src)
-{
- if ( m_nSize > 0 )
- Clear();
-
- Copy(src);
-
- m_autoSort = src.m_autoSort;
-
- return *this;
-}
-
-void wxArrayString::Copy(const wxArrayString& src)
-{
- if ( src.m_nCount > ARRAY_DEFAULT_INITIAL_SIZE )
- Alloc(src.m_nCount);
-
- for ( size_t n = 0; n < src.m_nCount; n++ )
- Add(src[n]);
-}
-
-// grow the array
-void wxArrayString::Grow(size_t nIncrement)
-{
- // only do it if no more place
- if ( (m_nSize - m_nCount) < nIncrement ) {
- // if ARRAY_DEFAULT_INITIAL_SIZE were set to 0, the initially empty would
- // be never resized!
- #if ARRAY_DEFAULT_INITIAL_SIZE == 0
- #error "ARRAY_DEFAULT_INITIAL_SIZE must be > 0!"
- #endif
-
- if ( m_nSize == 0 ) {
- // was empty, alloc some memory
- m_nSize = ARRAY_DEFAULT_INITIAL_SIZE;
- if (m_nSize < nIncrement)
- m_nSize = nIncrement;
- m_pItems = new wxChar *[m_nSize];
- }
- else {
- // otherwise when it's called for the first time, nIncrement would be 0
- // and the array would never be expanded
- // add 50% but not too much
- size_t ndefIncrement = m_nSize < ARRAY_DEFAULT_INITIAL_SIZE
- ? ARRAY_DEFAULT_INITIAL_SIZE : m_nSize >> 1;
- if ( ndefIncrement > ARRAY_MAXSIZE_INCREMENT )
- ndefIncrement = ARRAY_MAXSIZE_INCREMENT;
- if ( nIncrement < ndefIncrement )
- nIncrement = ndefIncrement;
- m_nSize += nIncrement;
- wxChar **pNew = new wxChar *[m_nSize];
-
- // copy data to new location
- memcpy(pNew, m_pItems, m_nCount*sizeof(wxChar *));
-
- // delete old memory (but do not release the strings!)
- wxDELETEA(m_pItems);
-
- m_pItems = pNew;
- }
- }
-}
-
-void wxArrayString::Free()
-{
- for ( size_t n = 0; n < m_nCount; n++ ) {
- STRING(m_pItems[n])->GetStringData()->Unlock();
- }
-}
-
-// deletes all the strings from the list
-void wxArrayString::Empty()
-{
- Free();
-
- m_nCount = 0;
-}
-
-// as Empty, but also frees memory
-void wxArrayString::Clear()
-{
- Free();
-
- m_nSize =
- m_nCount = 0;
-
- wxDELETEA(m_pItems);
-}
-
-// dtor
-wxArrayString::~wxArrayString()
-{
- Free();
-
- wxDELETEA(m_pItems);
-}
-
-// pre-allocates memory (frees the previous data!)
-void wxArrayString::Alloc(size_t nSize)
-{
- // only if old buffer was not big enough
- if ( nSize > m_nSize ) {
- Free();
- wxDELETEA(m_pItems);
- m_pItems = new wxChar *[nSize];
- m_nSize = nSize;
- }
-
- m_nCount = 0;
-}
-
-// minimizes the memory usage by freeing unused memory
-void wxArrayString::Shrink()
-{
- // only do it if we have some memory to free
- if( m_nCount < m_nSize ) {
- // allocates exactly as much memory as we need
- wxChar **pNew = new wxChar *[m_nCount];
-
- // copy data to new location
- memcpy(pNew, m_pItems, m_nCount*sizeof(wxChar *));
- delete [] m_pItems;
- m_pItems = pNew;
- }
-}
-
-// return a wxString[] as required for some control ctors.
-wxString* wxArrayString::GetStringArray() const
-{
- wxString *array = 0;
-
- if( m_nCount > 0 )
- {
- array = new wxString[m_nCount];
- for( size_t i = 0; i < m_nCount; i++ )
- array[i] = m_pItems[i];
- }
-
- return array;
-}
-
-// searches the array for an item (forward or backwards)
-int wxArrayString::Index(const wxChar *sz, bool bCase, bool bFromEnd) const
-{
- if ( m_autoSort ) {
- // use binary search in the sorted array
- wxASSERT_MSG( bCase && !bFromEnd,
- wxT("search parameters ignored for auto sorted array") );
-
- size_t i,
- lo = 0,
- hi = m_nCount;
- int res;
- while ( lo < hi ) {
- i = (lo + hi)/2;
-
- res = wxStrcmp(sz, m_pItems[i]);
- if ( res < 0 )
- hi = i;
- else if ( res > 0 )
- lo = i + 1;
- else
- return i;
- }
-
- return wxNOT_FOUND;
- }
- else {
- // use linear search in unsorted array
- if ( bFromEnd ) {
- if ( m_nCount > 0 ) {
- size_t ui = m_nCount;
- do {
- if ( STRING(m_pItems[--ui])->IsSameAs(sz, bCase) )
- return ui;
- }
- while ( ui != 0 );
- }
- }
- else {
- for( size_t ui = 0; ui < m_nCount; ui++ ) {
- if( STRING(m_pItems[ui])->IsSameAs(sz, bCase) )
- return ui;
- }
- }
- }
-
- return wxNOT_FOUND;
-}
-
-// add item at the end
-size_t wxArrayString::Add(const wxString& str, size_t nInsert)
-{
- if ( m_autoSort ) {
- // insert the string at the correct position to keep the array sorted
- size_t i,
- lo = 0,
- hi = m_nCount;
- int res;
- while ( lo < hi ) {
- i = (lo + hi)/2;
-
- res = wxStrcmp(str, m_pItems[i]);
- if ( res < 0 )
- hi = i;
- else if ( res > 0 )
- lo = i + 1;
- else {
- lo = hi = i;
- break;
- }
- }
-
- wxASSERT_MSG( lo == hi, wxT("binary search broken") );
-
- Insert(str, lo, nInsert);
-
- return (size_t)lo;
- }
- else {
- wxASSERT( str.GetStringData()->IsValid() );
-
- Grow(nInsert);
-
- for (size_t i = 0; i < nInsert; i++)
- {
- // the string data must not be deleted!
- str.GetStringData()->Lock();
-
- // just append
- m_pItems[m_nCount + i] = (wxChar *)str.c_str(); // const_cast
- }
- size_t ret = m_nCount;
- m_nCount += nInsert;
- return ret;
- }
-}
-
-// add item at the given position
-void wxArrayString::Insert(const wxString& str, size_t nIndex, size_t nInsert)
-{
- wxASSERT( str.GetStringData()->IsValid() );
-
- wxCHECK_RET( nIndex <= m_nCount, wxT("bad index in wxArrayString::Insert") );
- wxCHECK_RET( m_nCount <= m_nCount + nInsert,
- wxT("array size overflow in wxArrayString::Insert") );
-
- Grow(nInsert);
-
- memmove(&m_pItems[nIndex + nInsert], &m_pItems[nIndex],
- (m_nCount - nIndex)*sizeof(wxChar *));
-
- for (size_t i = 0; i < nInsert; i++)
- {
- str.GetStringData()->Lock();
- m_pItems[nIndex + i] = (wxChar *)str.c_str();
- }
- m_nCount += nInsert;
-}
-
-// expand the array
-void wxArrayString::SetCount(size_t count)
-{
- Alloc(count);
-
- wxString s;
- while ( m_nCount < count )
- m_pItems[m_nCount++] = (wxChar *)s.c_str();
-}
-
-// removes item from array (by index)
-void wxArrayString::Remove(size_t nIndex, size_t nRemove)
-{
- wxCHECK_RET( nIndex < m_nCount, wxT("bad index in wxArrayString::Remove") );
- wxCHECK_RET( nIndex + nRemove <= m_nCount,
- wxT("removing too many elements in wxArrayString::Remove") );
-
- // release our lock
- for (size_t i = 0; i < nRemove; i++)
- Item(nIndex + i).GetStringData()->Unlock();
-
- memmove(&m_pItems[nIndex], &m_pItems[nIndex + nRemove],
- (m_nCount - nIndex - nRemove)*sizeof(wxChar *));
- m_nCount -= nRemove;
-}
-
-// removes item from array (by value)
-void wxArrayString::Remove(const wxChar *sz)
-{
- int iIndex = Index(sz);
-
- wxCHECK_RET( iIndex != wxNOT_FOUND,
- wxT("removing inexistent element in wxArrayString::Remove") );
-
- Remove(iIndex);
-}
-