// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
- #pragma implementation "string.h"
-#endif
-
/*
* About ref counting:
* 1) all empty strings use g_strEmpty, nRefs = -1 (set in Init())
wxSTD ostream& operator<<(wxSTD ostream& os, const wxString& str)
{
- os << str.c_str();
- return os;
+#ifdef __BORLANDC__
+ os << str.mb_str();
+#else
+ os << str.c_str();
+#endif
+ return os;
}
#endif // wxUSE_STD_IOSTREAM
wxStringBase strTmp;
strTmp.reserve(length()); // micro optimisation to avoid multiple mem allocs
- if ( nStart != 0 )
- strTmp.append(c_str(), nStart);
+ //This is kind of inefficient, but its pretty good considering...
+ //we don't want to use character access operators here because on STL
+ //it will freeze the reference count of strTmp, which means a deep copy
+ //at the end when swap is called
+ //
+ //Also, we can't use append with the full character pointer and must
+ //do it manually because this string can contain null characters
+ for(size_t i1 = 0; i1 < nStart; ++i1)
+ strTmp.append(1, this->c_str()[i1]);
+
+ //its safe to do the full version here because
+ //sz must be a normal c string
strTmp.append(sz);
- strTmp.append(c_str() + nStart + nLen);
+
+ for(size_t i2 = nStart + nLen; i2 < length(); ++i2)
+ strTmp.append(1, this->c_str()[i2]);
swap(strTmp);
return *this;
}
// replace first (or all) occurences of some substring with another one
-size_t
-wxString::Replace(const wxChar *szOld, const wxChar *szNew, bool bReplaceAll)
+size_t wxString::Replace(const wxChar *szOld,
+ const wxChar *szNew, bool bReplaceAll)
{
// if we tried to replace an empty string we'd enter an infinite loop below
wxCHECK_MSG( szOld && *szOld && szNew, 0,
_T("wxString::Replace(): invalid parameter") );
- size_t uiCount = 0; // count of replacements made
+ size_t uiCount = 0; // count of replacements made
- size_t uiOldLen = wxStrlen(szOld);
+ size_t uiOldLen = wxStrlen(szOld);
+ size_t uiNewLen = wxStrlen(szNew);
- wxString strTemp;
- const wxChar *pCurrent = c_str();
- const wxChar *pSubstr;
- while ( *pCurrent != wxT('\0') ) {
- pSubstr = wxStrstr(pCurrent, szOld);
- if ( pSubstr == NULL ) {
- // strTemp is unused if no replacements were made, so avoid the copy
- if ( uiCount == 0 )
- return 0;
+ size_t dwPos = 0;
- strTemp += pCurrent; // copy the rest
- break; // exit the loop
- }
- else {
- // take chars before match
- size_type len = strTemp.length();
- strTemp.append(pCurrent, pSubstr - pCurrent);
- if ( strTemp.length() != (size_t)(len + pSubstr - pCurrent) ) {
- wxFAIL_MSG( _T("out of memory in wxString::Replace") );
- return 0;
- }
- strTemp += szNew;
- pCurrent = pSubstr + uiOldLen; // restart after match
+ while ( this->c_str()[dwPos] != wxT('\0') )
+ {
+ //DO NOT USE STRSTR HERE
+ //this string can contain embedded null characters,
+ //so strstr will function incorrectly
+ dwPos = find(szOld, dwPos);
+ if ( dwPos == npos )
+ break; // exit the loop
+ else
+ {
+ //replace this occurance of the old string with the new one
+ replace(dwPos, uiOldLen, szNew, uiNewLen);
- uiCount++;
+ //move up pos past the string that was replaced
+ dwPos += uiNewLen;
- // stop now?
- if ( !bReplaceAll ) {
- strTemp += pCurrent; // copy the rest
- break; // exit the loop
- }
- }
- }
+ //increase replace count
+ ++uiCount;
- // only done if there were replacements, otherwise would have returned above
- swap(strTemp);
+ // stop now?
+ if ( !bReplaceAll )
+ break; // exit the loop
+ }
+ }
- return uiCount;
+ return uiCount;
}
bool wxString::IsAscii() const
int wxString::Printf(const wxChar *pszFormat, ...)
{
- va_list argptr;
- va_start(argptr, pszFormat);
+ va_list argptr;
+ va_start(argptr, pszFormat);
- int iLen = PrintfV(pszFormat, argptr);
+ int iLen = PrintfV(pszFormat, argptr);
- va_end(argptr);
+ va_end(argptr);
- return iLen;
+ return iLen;
}
int wxString::PrintfV(const wxChar* pszFormat, va_list argptr)
{
int size = 1024;
- int len;
for ( ;; )
{
+ wxStringBuffer tmp(*this, size + 1);
+ wxChar* buf = tmp;
+
+ if ( !buf )
{
- wxStringBuffer tmp(*this, size + 1);
- wxChar* buf = tmp;
+ // out of memory
+ return -1;
+ }
- if ( !buf )
- {
- // out of memory
- return -1;
- }
+ // wxVsnprintf() may modify the original arg pointer, so pass it
+ // only a copy
+ va_list argptrcopy;
+ wxVaCopy(argptrcopy, argptr);
+ int len = wxVsnprintf(buf, size, pszFormat, argptrcopy);
+ va_end(argptrcopy);
- // 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
- // always do it manually
- buf[size] = _T('\0');
- }
+ // some implementations of vsnprintf() don't NUL terminate
+ // the string if there is not enough space for it so
+ // always do it manually
+ buf[size] = _T('\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
-#ifndef __WXMSW__
- || errno != EOVERFLOW
-#endif
- )
+ if ( len >= 0 && len <= size )
{
// ok, there was enough space
break;
}
+#ifdef EOVERFLOW
+ // if the error is not due to not having enough space (it could be e.g.
+ // EILSEQ), break too -- we'd just eat all available memory uselessly
+ if ( errno != EOVERFLOW )
+ {
+ // no sense in continuing
+ break;
+ }
+#endif // EOVERFLOW
+
// still not enough, double it again
size *= 2;
}
#include "wx/arrstr.h"
+wxArrayString::wxArrayString(size_t sz, const wxChar** a)
+{
+#if !wxUSE_STL
+ Init(false);
+#endif
+ for (size_t i=0; i < sz; i++)
+ Add(a[i]);
+}
+
+wxArrayString::wxArrayString(size_t sz, const wxString* a)
+{
+#if !wxUSE_STL
+ Init(false);
+#endif
+ for (size_t i=0; i < sz; i++)
+ Add(a[i]);
+}
+
#if !wxUSE_STL
// size increment = min(50% of current size, ARRAY_MAXSIZE_INCREMENT)