X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d95fb7ebf8d9294fadd1da79839744a710e3ea44..dc0846f7450860a9f1fc24701ed754a95311f02f:/src/common/string.cpp diff --git a/src/common/string.cpp b/src/common/string.cpp index 4304d78ff7..779beaee43 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -131,8 +131,12 @@ wxSTD istream& operator>>(wxSTD istream& is, wxString& WXUNUSED(str)) 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 @@ -735,10 +739,22 @@ wxStringBase& wxStringBase::replace(size_t nStart, size_t nLen, 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; @@ -1512,55 +1528,46 @@ wxString wxString::AfterFirst(wxChar ch) const } // 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 @@ -1836,7 +1843,14 @@ int wxString::PrintfV(const wxChar* pszFormat, va_list argptr) // in which case we need to break out if ( (len >= 0 && len <= size) // No EOVERFLOW on Windows nor Palm 6.0 nor OpenVMS nor MacOS (not X) -#if !defined(__WXMSW__) && !defined(__WXPALMOS__) && !defined( __VMS ) && !(defined(__WXMAC__) && !defined(__WXMAC_OSX__)) + // not OS/2 (not Innotek libc). +#if !defined(__WXMSW__) && \ + !defined(__WXPALMOS__) && \ + !defined(__OpenBSD__) && \ + !defined(__DJGPP__) && \ + !defined( __VMS ) && \ + !(defined(__WXMAC__) && !defined(__WXMAC_OSX__)) && \ + !(defined(__EMX__) && !defined(__INNOTEK_LIBC__)) || errno != EOVERFLOW #endif )