X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fd3a4cb92d936976027b884fcd9db5b75fb4b8c7..66c2bf7b1d9326fb650acfaae22ec50528cfbf7c:/include/wx/string.h diff --git a/include/wx/string.h b/include/wx/string.h index c7f380b5ec..1aafbe15f6 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -4,7 +4,6 @@ // Author: Vadim Zeitlin // Modified by: // Created: 29/01/98 -// RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// @@ -24,7 +23,6 @@ #include "wx/defs.h" // everybody should include this -#ifndef __WXPALMOS5__ #if defined(__WXMAC__) || defined(__VISAGECPP__) #include #endif @@ -44,11 +42,6 @@ # include #endif -#ifdef HAVE_STRCASECMP_IN_STRINGS_H - #include // for strcasecmp() -#endif // HAVE_STRCASECMP_IN_STRINGS_H -#endif // ! __WXPALMOS5__ - #include "wx/wxcrtbase.h" // for wxChar, wxStrlen() etc. #include "wx/strvararg.h" #include "wx/buffer.h" // for wxCharBuffer @@ -71,7 +64,7 @@ // it would have to be re-tested and probably corrected // CS: under OSX release builds the string destructor/cache cleanup sometimes // crashes, disable until we find the true reason or a better workaround -#if wxUSE_UNICODE_UTF8 && !defined(__WXMSW__) && !defined(__WXOSX__) +#if wxUSE_UNICODE_UTF8 && !defined(__WINDOWS__) && !defined(__WXOSX__) #define wxUSE_STRING_POS_CACHE 1 #else #define wxUSE_STRING_POS_CACHE 0 @@ -147,59 +140,7 @@ inline size_t Strlen(const char *psz) // portable strcasecmp/_stricmp wxDEPRECATED( inline int Stricmp(const char *psz1, const char *psz2) ); inline int Stricmp(const char *psz1, const char *psz2) -{ -#if defined(__VISUALC__) && defined(__WXWINCE__) - register char c1, c2; - do { - c1 = tolower(*psz1++); - c2 = tolower(*psz2++); - } while ( c1 && (c1 == c2) ); - - return c1 - c2; -#elif defined(__VISUALC__) || ( defined(__MWERKS__) && defined(__INTEL__) ) - return _stricmp(psz1, psz2); -#elif defined(__SC__) - return _stricmp(psz1, psz2); -#elif defined(__BORLANDC__) - return stricmp(psz1, psz2); -#elif defined(__WATCOMC__) - return stricmp(psz1, psz2); -#elif defined(__DJGPP__) - return stricmp(psz1, psz2); -#elif defined(__EMX__) - return stricmp(psz1, psz2); -#elif defined(__WXPM__) - return stricmp(psz1, psz2); -#elif defined(__WXPALMOS__) || \ - defined(HAVE_STRCASECMP_IN_STRING_H) || \ - defined(HAVE_STRCASECMP_IN_STRINGS_H) || \ - defined(__GNUWIN32__) - return strcasecmp(psz1, psz2); -#elif defined(__MWERKS__) && !defined(__INTEL__) - register char c1, c2; - do { - c1 = tolower(*psz1++); - c2 = tolower(*psz2++); - } while ( c1 && (c1 == c2) ); - - return c1 - c2; -#else - // almost all compilers/libraries provide this function (unfortunately under - // different names), that's why we don't implement our own which will surely - // be more efficient than this code (uncomment to use): - /* - register char c1, c2; - do { - c1 = tolower(*psz1++); - c2 = tolower(*psz2++); - } while ( c1 && (c1 == c2) ); - - return c1 - c2; - */ - - #error "Please define string case-insensitive compare for your OS/compiler" -#endif // OS/compiler -} + { return wxCRT_StricmpA(psz1, psz2); } #endif // WXWIN_COMPATIBILITY_2_8 @@ -900,7 +841,7 @@ public: public: \ WX_DEFINE_ITERATOR_CATEGORY(WX_STR_ITERATOR_TAG) \ typedef wxUniChar value_type; \ - typedef int difference_type; \ + typedef ptrdiff_t difference_type; \ typedef reference_type reference; \ typedef pointer_type pointer; \ \ @@ -1153,6 +1094,25 @@ public: #undef WX_STR_ITERATOR_TAG #undef WX_STR_ITERATOR_IMPL + // This method is mostly used by wxWidgets itself and return the offset of + // the given iterator in bytes relative to the start of the buffer + // representing the current string contents in the current locale encoding. + // + // It is inefficient as it involves converting part of the string to this + // encoding (and also unsafe as it simply returns 0 if the conversion fails) + // and so should be avoided if possible, wx itself only uses it to implement + // backwards-compatible API. + ptrdiff_t IterOffsetInMBStr(const const_iterator& i) const + { + const wxString str(begin(), i); + + // This is logically equivalent to strlen(str.mb_str()) but avoids + // actually converting the string to multibyte and just computes the + // length that it would have after conversion. + size_t ofs = wxConvLibc.FromWChar(NULL, 0, str.wc_str(), str.length()); + return ofs == wxCONV_FAILED ? 0 : static_cast(ofs); + } + friend class iterator; friend class const_iterator; @@ -1345,12 +1305,13 @@ public: } #endif // wxUSE_STRING_POS_CACHE - // even if we're not built with wxUSE_STL == 1 it is very convenient to allow - // implicit conversions from std::string to wxString and vice verse as this - // allows to use the same strings in non-GUI and GUI code, however we don't - // want to unconditionally add this ctor as it would make wx lib dependent on - // libstdc++ on some Linux versions which is bad, so instead we ask the - // client code to define this wxUSE_STD_STRING symbol if they need it + // even if we're not built with wxUSE_STD_STRING_CONV_IN_WXSTRING == 1 it is + // very convenient to allow implicit conversions from std::string to wxString + // and vice verse as this allows to use the same strings in non-GUI and GUI + // code, however we don't want to unconditionally add this ctor as it would + // make wx lib dependent on libstdc++ on some Linux versions which is bad, so + // instead we ask the client code to define this wxUSE_STD_STRING symbol if + // they need it #if wxUSE_STD_STRING #if wxUSE_UNICODE_WCHAR wxString(const wxStdWideString& str) : m_impl(str) {} @@ -1368,10 +1329,8 @@ public: #endif #endif // wxUSE_STD_STRING - // Unlike ctor from std::string, we provide conversion to std::string only - // if wxUSE_STL and not merely wxUSE_STD_STRING (which is on by default), - // because it conflicts with operator const char/wchar_t* but we still - // provide explicit conversions to std::[w]string for convenience in any case + // Also always provide explicit conversions to std::[w]string in any case, + // see below for the implicit ones. #if wxUSE_STD_STRING // We can avoid a copy if we already use this string type internally, // otherwise we create a copy on the fly: @@ -1408,13 +1367,14 @@ public: } #endif -#if wxUSE_STL - // In wxUSE_STL case we also provide implicit conversions as there is no - // ambiguity with the const char/wchar_t* ones as they are disabled in this - // build (for consistency with std::basic_string<>) +#if wxUSE_STD_STRING_CONV_IN_WXSTRING + // Implicit conversions to std::[w]string are not provided by default as + // they conflict with the implicit conversions to "const char/wchar_t *" + // which we use for backwards compatibility but do provide them if + // explicitly requested. operator wxStringToStdStringRetType() const { return ToStdString(); } operator wxStringToStdWstringRetType() const { return ToStdWstring(); } -#endif // wxUSE_STL +#endif // wxUSE_STD_STRING_CONV_IN_WXSTRING #undef wxStringToStdStringRetType #undef wxStringToStdWstringRetType @@ -1654,11 +1614,12 @@ public: operator wxCStrData() const { return c_str(); } // the first two operators conflict with operators for conversion to - // std::string and they must be disabled in STL build; the next one only - // makes sense if conversions to char* are also defined and not defining it - // in STL build also helps us to get more clear error messages for the code - // which relies on implicit conversion to char* in STL build -#if !wxUSE_STL + // std::string and they must be disabled if those conversions are enabled; + // the next one only makes sense if conversions to char* are also defined + // and not defining it in STL build also helps us to get more clear error + // messages for the code which relies on implicit conversion to char* in + // STL build +#if !wxUSE_STD_STRING_CONV_IN_WXSTRING operator const char*() const { return c_str(); } operator const wchar_t*() const { return c_str(); } @@ -1666,7 +1627,7 @@ public: // wxWidgets versions: this is the same as conversion to const char * so it // may fail! operator const void*() const { return c_str(); } -#endif // wxUSE_STL +#endif // !wxUSE_STD_STRING_CONV_IN_WXSTRING // identical to c_str(), for MFC compatibility const wxCStrData GetData() const { return c_str(); } @@ -2615,9 +2576,21 @@ public: return *this; } + // This is a non-standard-compliant overload taking the first "len" + // characters of the source string. wxString& assign(const wxString& str, size_t len) { +#if wxUSE_STRING_POS_CACHE + // It is legal to pass len > str.length() to wxStringImpl::assign() but + // by restricting it here we save some work for that function so it's not + // really less efficient and, at the same time, ensure that we don't + // cache invalid length. + const size_t lenSrc = str.length(); + if ( len > lenSrc ) + len = lenSrc; + wxSTRING_SET_CACHED_LENGTH(len); +#endif // wxUSE_STRING_POS_CACHE m_impl.assign(str.m_impl, 0, str.LenToImpl(len)); @@ -2659,7 +2632,7 @@ public: wxString& assign(const char *sz, size_t n) { - wxSTRING_SET_CACHED_LENGTH(n); + wxSTRING_INVALIDATE_CACHE(); SubstrBufFromMB str(ImplStr(sz, n)); m_impl.assign(str.data, str.len); @@ -3475,7 +3448,7 @@ private: void DoUngetWriteBuf(size_t nLen) { - wxSTRING_SET_CACHED_LENGTH(nLen); + wxSTRING_INVALIDATE_CACHE(); m_impl.DoUngetWriteBuf(nLen); }