/////////////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////////////
// 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
// ----------------------------------------------------------------------------
wxFAIL_MSG( _T("out of memory in wxStringBase::InitWith") );
return;
}
- memcpy(m_pchData, psz + nPos, nLength*sizeof(wxChar));
+ wxTmemcpy(m_pchData, psz + nPos, nLength);
}
}
// allocation failures are handled by the caller
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
wxASSERT( nStart <= length() );
//anchor
- const wxChar* p = (const wxChar*)wxMemchr(c_str() + nStart,
- str.c_str()[0],
+ const wxChar* p = (const wxChar*)wxTmemchr(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()) )
+ wxTmemcmp(p, str.c_str(), str.length()) )
{
//anchor again
- p = (const wxChar*)wxMemchr(++p,
- str.c_str()[0],
+ 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;
}
{
wxASSERT( nStart <= length() );
- const wxChar *p = (const wxChar*)wxMemchr(c_str() + nStart, ch, length() - nStart);
+ const wxChar *p = (const wxChar*)wxTmemchr(c_str() + nStart, ch, length() - nStart);
return p == NULL ? npos : p - c_str();
}
const wxChar *cursor = c_str() + top;
do
{
- if ( wxMemcmp(cursor, str.c_str(),
+ if ( wxTmemcmp(cursor, str.c_str(),
str.length()) == 0 )
{
return cursor - c_str();
size_t i;
for(i = nStart; i < this->length(); ++i)
{
- if (wxMemchr(sz, *(c_str() + i), len))
+ if (wxTmemchr(sz, *(c_str() + i), len))
break;
}
}
size_t len = wxStrlen(sz);
-
+
for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
{
- if ( wxMemchr(sz, *p, len) )
+ if ( wxTmemchr(sz, *p, len) )
return p - c_str();
}
size_t i;
for(i = nStart; i < this->length(); ++i)
{
- if (!wxMemchr(sz, *(c_str() + i), len))
+ if (!wxTmemchr(sz, *(c_str() + i), len))
break;
}
for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
{
- if ( !wxMemchr(sz, *p,len) )
+ if ( !wxTmemchr(sz, *p,len) )
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,
const wxChar* s2, size_t l2)
{
if( l1 == l2 )
- return wxMemcmp(s1, s2, l1);
+ return wxTmemcmp(s1, s2, l1);
else if( l1 < l2 )
{
- int ret = wxMemcmp(s1, s2, l1);
+ int ret = wxTmemcmp(s1, s2, l1);
return ret == 0 ? -1 : ret;
}
- else if( l1 > l2 )
+ else
{
- int ret = wxMemcmp(s1, s2, l2);
+ int ret = wxTmemcmp(s1, s2, l2);
return ret == 0 ? +1 : ret;
}
-
- wxFAIL; // must never get there
- return 0; // quiet compilers
}
int STRINGCLASS::compare(const wxStringBase& str) const
// ===========================================================================
// ---------------------------------------------------------------------------
-// construction
+// construction and conversion
// ---------------------------------------------------------------------------
#if wxUSE_UNICODE
if ( psz )
{
// calculate the needed size ourselves or use the provided one
- nLen = conv.MB2WC(NULL, psz, 0);
+ 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);
- // 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
{
- 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;
+ size_t dwOutSize;
+ return conv.cWC2MB(c_str(), length(), &dwOutSize);
}
#else // ANSI
if ( pwz )
{
// calculate the needed size ourselves or use the provided one
- nLen = conv.WC2MB(NULL, pwz, 0);
+ 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);
- // leave empty
+ //Copy
+ if (nRealSize)
+ assign( theBuffer.data() , nRealSize - 1 );
+ }
}
+//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
{
- 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;
+ size_t dwOutSize;
+ return conv.cMB2WC(c_str(), length(), &dwOutSize);
}
-
+
#endif // wxUSE_WCHAR_T
#endif // Unicode/ANSI
if(wxTolower(s1[i]) != wxTolower(s2[i]))
break;
}
- return i == l1 ? 0 : s1[i] < s2[i] ? -1 : 1;
+ return i == l1 ? 0 : wxTolower(s1[i]) < wxTolower(s2[i]) ? -1 : 1;
}
else if( l1 < l2 )
{
if(wxTolower(s1[i]) != wxTolower(s2[i]))
break;
}
- return i == l1 ? -1 : s1[i] < s2[i] ? -1 : 1;
+ return i == l1 ? -1 : wxTolower(s1[i]) < wxTolower(s2[i]) ? -1 : 1;
}
- else if( l1 > l2 )
+ else
{
for(i = 0; i < l2; ++i)
{
if(wxTolower(s1[i]) != wxTolower(s2[i]))
break;
}
- return i == l2 ? 1 : s1[i] < s2[i] ? -1 : 1;
+ return i == l2 ? 1 : wxTolower(s1[i]) < wxTolower(s2[i]) ? -1 : 1;
}
-
- wxFAIL; // must never get there
- return 0; // quiet compilers
}
int wxString::CmpNoCase(const wxString& s) const
// 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
{
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);
s++;
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)))
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)