/////////////////////////////////////////////////////////////////////////////
// Name: string.cpp
// Purpose: wxString class
-// Author: Vadim Zeitlin
+// Author: Vadim Zeitlin, Ryan Norton
// Modified by:
// Created: 29/01/98
// RCS-ID: $Id$
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// (c) 2004 Ryan Norton <wxprojects@comcast.net>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdlib.h>
+#ifndef __WXMSW__
+#include <errno.h>
+#endif
+
#ifdef __SALFORDC__
#include <clib.h>
#endif
// static class variables definition
// ---------------------------------------------------------------------------
-#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
-// must define this static for VA or else you get multiply defined symbols
-// everywhere
-const unsigned int wxSTRING_MAXLEN = UINT_MAX - 100;
-#endif // Visual Age
-
#if !wxUSE_STL
- const size_t wxStringBase::npos = wxSTRING_MAXLEN;
+ //According to STL _must_ be a -1 size_t
+ const size_t wxStringBase::npos = (size_t) -1;
#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
// ===========================================================================
wxFAIL_MSG( _T("out of memory in wxStringBase::InitWith") );
return;
}
- memcpy(m_pchData, psz + nPos, nLength*sizeof(wxChar));
+ wxTmemcpy(m_pchData, psz + nPos, nLength);
}
}
if ( pData == NULL ) {
// allocation failures are handled by the caller
- return FALSE;
+ return false;
}
pData->nRefs = 1;
pData->nAllocLength = nLen + EXTRA_ALLOC;
m_pchData = pData->data(); // data starts after wxStringData
m_pchData[nLen] = wxT('\0');
- return TRUE;
+ return true;
}
// must be called before changing this string
size_t nLen = pData->nDataLength;
if ( !AllocBuffer(nLen) ) {
// allocation failures are handled by the caller
- return FALSE;
+ return false;
}
- memcpy(m_pchData, pData->data(), nLen*sizeof(wxChar));
+ wxTmemcpy(m_pchData, pData->data(), nLen);
}
wxASSERT( !GetStringData()->IsShared() ); // we must be the only owner
- return TRUE;
+ return true;
}
// must be called before replacing contents of this string
pData->Unlock();
if ( !AllocBuffer(nLen) ) {
// allocation failures are handled by the caller
- return FALSE;
+ return false;
}
}
else {
if ( pData == NULL ) {
// allocation failures are handled by the caller
// keep previous data since reallocation failed
- return FALSE;
+ return false;
}
pData->nAllocLength = nLen;
m_pchData = pData->data();
}
-
- // now we have enough space, just update the string length
- pData->nDataLength = nLen;
}
wxASSERT( !GetStringData()->IsShared() ); // we must be the only owner
- return TRUE;
+ // it doesn't really matter what the string length is as it's going to be
+ // overwritten later but, for extra safety, set it to 0 for now as we may
+ // have some junk in m_pchData
+ GetStringData()->nDataLength = 0;
+
+ return true;
}
wxStringBase& wxStringBase::append(size_t n, wxChar ch)
{
size_type len = length();
- if ( !CopyBeforeWrite() || !Alloc(len + n) ) {
+ if ( !Alloc(len + n) || !CopyBeforeWrite() ) {
wxFAIL_MSG( _T("out of memory in wxStringBase::append") );
}
GetStringData()->nDataLength = len + n;
if ( pData == NULL ) {
// allocation failure handled by caller
- return FALSE;
+ return false;
}
pData->nRefs = 1;
size_t nOldLen = pData->nDataLength;
if ( !AllocBuffer(nLen) ) {
// allocation failure handled by caller
- return FALSE;
+ return false;
}
- memcpy(m_pchData, pData->data(), nOldLen*sizeof(wxChar));
+ // +1 to copy the terminator, too
+ memcpy(m_pchData, pData->data(), (nOldLen+1)*sizeof(wxChar));
+ GetStringData()->nDataLength = nOldLen;
}
else {
nLen += EXTRA_ALLOC;
if ( pData == NULL ) {
// allocation failure handled by caller
// keep previous data since reallocation failed
- return FALSE;
+ return false;
}
// it's not important if the pointer changed or not (the check for this
}
}
//else: we've already got enough
- return TRUE;
+ return true;
+}
+
+wxStringBase::iterator wxStringBase::begin()
+{
+ if (length() > 0)
+ CopyBeforeWrite();
+ return m_pchData;
+}
+
+wxStringBase::iterator wxStringBase::end()
+{
+ if (length() > 0)
+ CopyBeforeWrite();
+ return m_pchData + length();
}
wxStringBase::iterator wxStringBase::erase(iterator it)
if ( n == npos ) n = wxStrlen(sz);
if ( n == 0 ) return *this;
- if ( !CopyBeforeWrite() || !Alloc(length() + n) ) {
+ if ( !Alloc(length() + n) || !CopyBeforeWrite() ) {
wxFAIL_MSG( _T("out of memory in wxStringBase::insert") );
}
wxASSERT( str.GetStringData()->IsValid() );
wxASSERT( nStart <= length() );
- const wxChar *p = wxStrstr(c_str() + nStart, str.c_str());
+ //anchor
+ const wxChar* p = (const wxChar*)wxTmemchr(c_str() + nStart,
+ str.c_str()[0],
+ length() - nStart);
- return p == NULL ? npos : p - c_str();
+ if(!p)
+ return npos;
+
+ while(p - c_str() + str.length() <= length() &&
+ wxTmemcmp(p, str.c_str(), str.length()) )
+ {
+ //Previosly passed as the first argument to wxTmemchr,
+ //but C/C++ standard does not specify evaluation order
+ //of arguments to functions -
+ //http://embedded.com/showArticle.jhtml?articleID=9900607
+ ++p;
+
+ //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
{
wxASSERT( nStart <= length() );
- const wxChar *p = wxStrchr(c_str() + nStart, ch);
+ 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() );
-
- // 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();
+
+ 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;
+ 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
{
- 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 (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();
+ nStart = length() - 1;
}
else
{
_T("invalid index in find_last_of()") );
}
- for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- )
+ size_t len = wxStrlen(sz);
+
+ for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
{
- if ( wxStrchr(sz, *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 )
wxASSERT( nStart <= length() );
}
- size_t nAccept = wxStrspn(c_str() + nStart, sz);
- if ( nAccept >= length() - nStart )
- return npos;
- else
- return nAccept;
+ 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
{
if ( nStart == npos )
{
- nStart = length();
+ nStart = length() - 1;
}
else
{
wxASSERT( nStart <= length() );
}
- for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- )
+ 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 ( !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();
+ 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();
wxStringBase& wxStringBase::replace(size_t nStart, size_t nLen,
size_t nCount, wxChar ch)
{
- return replace(nStart, nLen, wxStringBase(ch, nCount).c_str());
+ return replace(nStart, nLen, wxStringBase(nCount, ch).c_str());
}
wxStringBase& wxStringBase::replace(size_t nStart, size_t nLen,
else {
if ( !AllocBeforeWrite(nSrcLen) ) {
// allocation failure handled by caller
- return FALSE;
+ return false;
}
memcpy(m_pchData, pszSrcData, nSrcLen*sizeof(wxChar));
GetStringData()->nDataLength = nSrcLen;
m_pchData[nSrcLen] = wxT('\0');
}
- return TRUE;
+ return true;
}
// ---------------------------------------------------------------------------
wxStringData* pOldData = GetStringData();
if ( !AllocBuffer(nNewLen) ) {
// allocation failure handled by caller
- return FALSE;
+ return false;
}
memcpy(m_pchData, pOldData->data(), nLen*sizeof(wxChar));
pOldData->Unlock();
// we have to grow the buffer
if ( capacity() < nNewLen ) {
// allocation failure handled by caller
- return FALSE;
+ return false;
}
}
else {
GetStringData()->nDataLength = nNewLen; // and fix the length
}
//else: the string to append was empty
- return TRUE;
+ return true;
}
// ---------------------------------------------------------------------------
else {
if ( !dest.AllocBuffer(nCopyLen) ) {
// allocation failure handled by caller
- return FALSE;
+ return false;
}
memcpy(dest.m_pchData, m_pchData + nCopyIndex, nCopyLen*sizeof(wxChar));
}
- return TRUE;
+ return true;
}
#endif // !wxUSE_STL
const wxChar* s2, size_t l2)
{
if( l1 == l2 )
- return wxStrncmp(s1, s2, l1);
+ return wxTmemcmp(s1, s2, l1);
else if( l1 < l2 )
{
- int ret = wxStrncmp(s1, s2, l1);
+ int ret = wxTmemcmp(s1, s2, l1);
return ret == 0 ? -1 : ret;
}
- else if( l1 > l2 )
+ else
{
- int ret = wxStrncmp(s1, s2, l2);
+ int ret = wxTmemcmp(s1, s2, l2);
return ret == 0 ? +1 : ret;
}
-
- wxFAIL; // must never get there
- 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
{
// ===========================================================================
// ---------------------------------------------------------------------------
-// construction
+// construction and conversion
// ---------------------------------------------------------------------------
#if wxUSE_UNICODE
// from multibyte string
wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength)
{
+ // if nLength != npos, then we have to make a NULL-terminated copy
+ // of first nLength bytes of psz first because the input buffer to MB2WC
+ // must always be NULL-terminated:
+ wxCharBuffer inBuf((const char *)NULL);
+ if (nLength != npos)
+ {
+ wxASSERT( psz != NULL );
+ wxCharBuffer tmp(nLength);
+ memcpy(tmp.data(), psz, nLength);
+ tmp.data()[nLength] = '\0';
+ inBuf = tmp;
+ psz = inBuf.data();
+ }
+
// first get the size of the buffer we need
size_t nLen;
if ( psz )
{
// calculate the needed size ourselves or use the provided one
- nLen = nLength == npos ? conv.MB2WC(NULL, psz, 0) : nLength;
+ if (nLength == npos)
+ nLen = strlen(psz);
+ else
+ nLen = nLength;
}
else
{
nLen = 0;
}
+
// anything to do?
if ( (nLen != 0) && (nLen != (size_t)-1) )
{
- if ( !Alloc(nLen) )
- {
- wxFAIL_MSG( _T("out of memory in wxString::wxString") );
- }
- else
- {
- wxWCharBuffer buf(nLen + 1);
- // MB2WC wants the buffer size, not the string length hence +1
- nLen = conv.MB2WC(buf.data(), psz, nLen + 1);
+ //Convert string
+ size_t nRealSize;
+ wxWCharBuffer theBuffer = conv.cMB2WC(psz, nLen, &nRealSize);
- if ( nLen != (size_t)-1 )
- {
- // initialized ok, set the real length as nLength specified by
- // the caller could be greater than the real string length
- assign(buf.data(), nLen);
- return;
- }
- //else: the conversion failed -- leave the string empty (what else?)
- }
+ //Copy
+ if (nRealSize)
+ assign( theBuffer.data() , nRealSize - 1 );
}
}
+//Convert wxString in Unicode mode to a multi-byte string
+const wxCharBuffer wxString::mb_str(wxMBConv& conv) const
+{
+ size_t dwOutSize;
+ return conv.cWC2MB(c_str(), length(), &dwOutSize);
+}
+
#else // ANSI
#if wxUSE_WCHAR_T
// from wide string
wxString::wxString(const wchar_t *pwz, wxMBConv& conv, size_t nLength)
{
+ // if nLength != npos, then we have to make a NULL-terminated copy
+ // of first nLength chars of psz first because the input buffer to WC2MB
+ // must always be NULL-terminated:
+ wxWCharBuffer inBuf((const wchar_t *)NULL);
+ if (nLength != npos)
+ {
+ wxASSERT( pwz != NULL );
+ wxWCharBuffer tmp(nLength);
+ memcpy(tmp.data(), pwz, nLength * sizeof(wchar_t));
+ tmp.data()[nLength] = '\0';
+ inBuf = tmp;
+ pwz = inBuf.data();
+ }
+
// first get the size of the buffer we need
size_t nLen;
if ( pwz )
{
// calculate the needed size ourselves or use the provided one
- nLen = nLength == npos ? conv.WC2MB(NULL, pwz, 0) : nLength;
+ if (nLength == npos)
+ nLen = wxWcslen(pwz);
+ else
+ nLen = nLength;
}
else
{
// anything to do?
if ( (nLen != 0) && (nLen != (size_t)-1) )
{
- if ( !Alloc(nLen) )
- {
- wxFAIL_MSG( _T("out of memory in wxString::wxString") );
- }
- else
- {
- wxCharBuffer buf(nLen);
- // WC2MB wants the buffer size, not the string length
- if ( conv.WC2MB(buf.data(), pwz, nLen + 1) != (size_t)-1 )
- {
- // initialized ok
- assign(buf.data(), nLen);
- return;
- }
- //else: the conversion failed -- leave the string empty (what else?)
- }
+ //Convert string
+ size_t nRealSize;
+ wxCharBuffer theBuffer = conv.cWC2MB(pwz, nLen, &nRealSize);
+
+ //Copy
+ if (nRealSize)
+ assign( theBuffer.data() , nRealSize - 1 );
}
+}
- // leave empty
+//Converts this string to a wide character string if unicode
+//mode is not enabled and wxUSE_WCHAR_T is enabled
+const wxWCharBuffer wxString::wc_str(wxMBConv& conv) const
+{
+ size_t dwOutSize;
+ return conv.cMB2WC(c_str(), length(), &dwOutSize);
}
+
#endif // wxUSE_WCHAR_T
#endif // Unicode/ANSI
}
wxASSERT( GetStringData()->nRefs == 1 );
- GetStringData()->Validate(FALSE);
+ GetStringData()->Validate(false);
return m_pchData;
}
void wxString::UngetWriteBuf()
{
GetStringData()->nDataLength = wxStrlen(m_pchData);
- GetStringData()->Validate(TRUE);
+ GetStringData()->Validate(true);
}
void wxString::UngetWriteBuf(size_t nLen)
{
GetStringData()->nDataLength = nLen;
- GetStringData()->Validate(TRUE);
+ GetStringData()->Validate(true);
}
#endif
if ( !s.Alloc(wxStrlen(psz) + str.Len()) ) {
wxFAIL_MSG( _T("out of memory in wxString::operator+") );
}
- s = str;
+ s += str;
s += psz;
return s;
// 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 : wxTolower(s1[i]) < wxTolower(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 : wxTolower(s1[i]) < wxTolower(s2[i]) ? -1 : 1;
+ }
+ else
+ {
+ for(i = 0; i < l2; ++i)
+ {
+ if(wxTolower(s1[i]) != wxTolower(s2[i]))
+ break;
+ }
+ return i == l2 ? 1 : wxTolower(s1[i]) < wxTolower(s2[i]) ? -1 : 1;
+ }
+}
+
+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)
// this will allocate enough space for the terminating NUL too
wxCharBuffer buffer(length());
- signed char *dest = (signed char *)buffer.data();
+
+ char *dest = buffer.data();
const wchar_t *pwc = c_str();
for ( ;; )
{
- *dest++ = *pwc > SCHAR_MAX ? '_' : *pwc;
+ *dest++ = (char)(*pwc > SCHAR_MAX ? wxT('_') : *pwc);
// the output string can't have embedded NULs anyhow, so we can safely
// stop at first of them even if we do have any
}
// check that the string starts with prefix and return the rest of the string
-// in the provided pointer if it is not NULL, otherwise return FALSE
+// in the provided pointer if it is not NULL, otherwise return false
bool wxString::StartsWith(const wxChar *prefix, wxString *rest) const
{
wxASSERT_MSG( prefix, _T("invalid parameter in wxString::StartsWith") );
if ( *prefix++ != *p++ )
{
// no match
- return FALSE;
+ return false;
}
}
*rest = p;
}
- return TRUE;
+ return true;
}
// extract nCount last (rightmost) characters
wxString wxString::AfterLast(wxChar ch) const
{
wxString str;
- int iPos = Find(ch, TRUE);
+ int iPos = Find(ch, true);
if ( iPos == wxNOT_FOUND )
str = *this;
else
wxString wxString::BeforeLast(wxChar ch) const
{
wxString str;
- int iPos = Find(ch, TRUE);
+ int iPos = Find(ch, true);
if ( iPos != wxNOT_FOUND && iPos != 0 )
str = wxString(c_str(), iPos);
{
const wxChar *s = (const wxChar*) *this;
while(*s){
- if(!isascii(*s)) return(FALSE);
+ if(!isascii(*s)) return(false);
s++;
}
- return(TRUE);
+ return(true);
}
bool wxString::IsWord() const
{
const wxChar *s = (const wxChar*) *this;
while(*s){
- if(!wxIsalpha(*s)) return(FALSE);
+ if(!wxIsalpha(*s)) return(false);
s++;
}
- return(TRUE);
+ return(true);
}
bool wxString::IsNumber() const
{
const wxChar *s = (const wxChar*) *this;
if (wxStrlen(s))
- if ((s[0] == '-') || (s[0] == '+')) s++;
+ if ((s[0] == wxT('-')) || (s[0] == wxT('+'))) s++;
while(*s){
- if(!wxIsdigit(*s)) return(FALSE);
+ if(!wxIsdigit(*s)) return(false);
s++;
}
- return(TRUE);
+ return(true);
}
wxString wxString::Strip(stripType w) const
{
wxString s = *this;
- if ( w & leading ) s.Trim(FALSE);
- if ( w & trailing ) s.Trim(TRUE);
+ if ( w & leading ) s.Trim(false);
+ if ( w & trailing ) s.Trim(true);
return s;
}
// trimming and padding
// ---------------------------------------------------------------------------
-// some compilers (VC++ 6.0 not to name them) return TRUE for a call to
+// some compilers (VC++ 6.0 not to name them) return true for a call to
// isspace('ê') in the C locale which seems to be broken to me, but we have to
// live with this by checking that the character is a 7 bit one - even if this
// may fail to detect some spaces (I don't know if Unicode doesn't have
wxString& wxString::Trim(bool bFromRight)
{
// first check if we're going to modify the string at all
- if ( !IsEmpty() &&
+ if ( !empty() &&
(
(bFromRight && wxSafeIsspace(GetChar(Len() - 1))) ||
(!bFromRight && wxSafeIsspace(GetChar(0u)))
bool wxString::ToLong(long *val, int base) const
{
- wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToLong") );
+ wxCHECK_MSG( val, false, _T("NULL pointer in wxString::ToLong") );
wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
const wxChar *start = c_str();
wxChar *end;
*val = wxStrtol(start, &end, base);
- // return TRUE only if scan was stopped by the terminating NUL and if the
+ // return true only if scan was stopped by the terminating NUL and if the
// string was not empty to start with
return !*end && (end != start);
}
bool wxString::ToULong(unsigned long *val, int base) const
{
- wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToULong") );
+ wxCHECK_MSG( val, false, _T("NULL pointer in wxString::ToULong") );
wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
const wxChar *start = c_str();
wxChar *end;
*val = wxStrtoul(start, &end, base);
- // return TRUE only if scan was stopped by the terminating NUL and if the
+ // return true only if scan was stopped by the terminating NUL and if the
// string was not empty to start with
return !*end && (end != start);
}
bool wxString::ToDouble(double *val) const
{
- wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToDouble") );
+ wxCHECK_MSG( val, false, _T("NULL pointer in wxString::ToDouble") );
const wxChar *start = c_str();
wxChar *end;
*val = wxStrtod(start, &end);
- // return TRUE only if scan was stopped by the terminating NUL and if the
+ // return true only if scan was stopped by the terminating NUL and if the
// string was not empty to start with
return !*end && (end != start);
}
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
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
+ // also, it may return an errno may be something like EILSEQ,
+ // in which case we need to break out
+ if ( (len >= 0 && len <= size)
+ // No EOVERFLOW on Windows nor Palm 6.0 nor OpenVMS
+#if !defined(__WXMSW__) && !defined(__WXPALMOS__) && !defined( __VMS )
+ || errno != EOVERFLOW
+#endif
+ )
{
// ok, there was enough space
break;
// misc other operations
// ----------------------------------------------------------------------------
-// returns TRUE if the string matches the pattern which may contain '*' and
+// returns true if the string matches the pattern which may contain '*' and
// '?' metacharacters (as usual, '?' matches any character and '*' any number
// of them)
bool wxString::Matches(const wxChar *pszMask) const
switch ( *pszMask ) {
case wxT('?'):
if ( *pszTxt == wxT('\0') )
- return FALSE;
+ return false;
// pszTxt and pszMask will be incremented in the loop statement
// if there is nothing more, match
if ( *pszMask == wxT('\0') )
- return TRUE;
+ return true;
// are there any other metacharacters in the mask?
size_t uiLenMask;
wxString strToMatch(pszMask, uiLenMask);
const wxChar* pMatch = wxStrstr(pszTxt, strToMatch);
if ( pMatch == NULL )
- return FALSE;
+ return false;
// -1 to compensate "++" in the loop
pszTxt = pMatch + uiLenMask - 1;
default:
if ( *pszMask != *pszTxt )
- return FALSE;
+ return false;
break;
}
}
// match only if nothing left
if ( *pszTxt == wxT('\0') )
- return TRUE;
+ return true;
// if we failed to match, backtrack if we can
if ( pszLastStarInText ) {
goto match;
}
- return FALSE;
+ return false;
#endif // wxUSE_REGEX/!wxUSE_REGEX
}
wxDELETEA(m_pItems);
}
+void wxArrayString::reserve(size_t nSize)
+{
+ Alloc(nSize);
+}
+
// pre-allocates memory (frees the previous data!)
void wxArrayString::Alloc(size_t nSize)
{
return array;
}
+void wxArrayString::Remove(size_t nIndex, size_t nRemove)
+{
+ RemoveAt(nIndex, nRemove);
+}
+
#endif // WXWIN_COMPATIBILITY_2_4
// searches the array for an item (forward or backwards)
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 )
m_nCount += nInsert;
}
+// range insert (STL 23.2.4.3)
+void
+wxArrayString::insert(iterator it, const_iterator first, const_iterator last)
+{
+ const int idx = it - begin();
+
+ // grow it once
+ Grow(last - first);
+
+ // reset "it" since it can change inside Grow()
+ it = begin() + idx;
+
+ while ( first != last )
+ {
+ it = insert(it, *first);
+
+ // insert returns an iterator to the last element inserted but we need
+ // insert the next after this one, that is before the next one
+ ++it;
+
+ ++first;
+ }
+}
+
// expand the array
void wxArrayString::SetCount(size_t count)
{
RemoveAt(iIndex);
}
+void wxArrayString::assign(const_iterator first, const_iterator last)
+{
+ reserve(last - first);
+ for(; first != last; ++first)
+ push_back(*first);
+}
+
// ----------------------------------------------------------------------------
// sorting
// ----------------------------------------------------------------------------
// if we don't use the compare function, this flag tells us if we sort the
// array in ascending or descending order
-static bool gs_sortAscending = TRUE;
+static bool gs_sortAscending = true;
// function which is called by quick sort
extern "C" int wxC_CALLING_CONV // LINKAGEMODE
}
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;
}
bool wxArrayString::operator==(const wxArrayString& a) const
{
if ( m_nCount != a.m_nCount )
- return FALSE;
+ return false;
for ( size_t n = 0; n < m_nCount; n++ )
{
if ( Item(n) != a[n] )
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
#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());
+ return s1->Cmp(*s2);
}
-int wxStringSortDescending(wxString* s1, wxString* s2)
+int wxCMPFUNC_CONV wxStringSortDescending(wxString* s1, wxString* s2)
{
- return -wxStrcmp(s1->c_str(), s2->c_str());
+ return -s1->Cmp(*s2);
}