X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/18666b42ca62c24cb3097c32b5108f57bbb7eec6..e5cfb314ae1cadac46cc50d37d9f6d15d8260a29:/include/wx/string.h?ds=sidebyside diff --git a/include/wx/string.h b/include/wx/string.h index 44e0d7d2ae..b6cb7836b3 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -69,7 +69,9 @@ // use in DLL build under pre-Vista Windows so we disable this code for now, if // anybody really needs to use UTF-8 build under Windows with this optimization // it would have to be re-tested and probably corrected -#if wxUSE_UNICODE_UTF8 && !defined(__WXMSW__) +// 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__) #define wxUSE_STRING_POS_CACHE 1 #else #define wxUSE_STRING_POS_CACHE 0 @@ -424,7 +426,7 @@ private: // the node belongs to a particular iterator instance, it's not copied // when a copy of the iterator is made - DECLARE_NO_COPY_CLASS(wxStringIteratorNode) + wxDECLARE_NO_COPY_CLASS(wxStringIteratorNode); }; #endif // wxUSE_UNICODE_UTF8 @@ -613,7 +615,7 @@ private: return wxTLS_VALUE(s_cache); } - + // this helper struct is used to ensure that GetCache() is called during // static initialization time, i.e. before any threads creation, as otherwise // the static s_cache construction inside GetCache() wouldn't be MT-safe @@ -673,7 +675,7 @@ private: // a lot of misses in this function...) Cache::Element * const cacheBegin = GetCacheBegin(); #ifndef wxHAS_COMPILER_TLS - // during destruction tls calls may return NULL, in this case return NULL + // during destruction tls calls may return NULL, in this case return NULL // immediately without accessing anything else if ( cacheBegin == NULL ) return NULL; @@ -987,7 +989,7 @@ public: iterator(wxString *str, underlying_iterator ptr) : m_cur(ptr), m_node(str, &m_cur) {} - wxString* str() const { return wx_const_cast(wxString*, m_node.m_str); } + wxString* str() const { return const_cast(m_node.m_str); } wxStringIteratorNode m_node; @@ -1808,7 +1810,7 @@ public: const wchar_t* t_str() const { return wx_str(); } #else const char* t_str() const { return wx_str(); } -#endif +#endif // overloaded assignment @@ -2117,16 +2119,16 @@ public: wxString Left(size_t nCount) const; // get last nCount characters wxString Right(size_t nCount) const; - // get all characters before the first occurance of ch + // get all characters before the first occurrence of ch // (returns the whole string if ch not found) wxString BeforeFirst(wxUniChar ch) const; - // get all characters before the last occurence of ch + // get all characters before the last occurrence of ch // (returns empty string if ch not found) wxString BeforeLast(wxUniChar ch) const; - // get all characters after the first occurence of ch + // get all characters after the first occurrence of ch // (returns empty string if ch not found) wxString AfterFirst(wxUniChar ch) const; - // get all characters after the last occurence of ch + // get all characters after the last occurrence of ch // (returns the whole string if ch not found) wxString AfterLast(wxUniChar ch) const; @@ -2191,7 +2193,7 @@ public: int Find(const wxWCharBuffer& sub) const { return Find(sub.data()); } - // replace first (or all of bReplaceAll) occurences of substring with + // replace first (or all of bReplaceAll) occurrences of substring with // another string, returns the number of replacements made size_t Replace(const wxString& strOld, const wxString& strNew, @@ -3014,7 +3016,7 @@ public: size_t find(const wxCStrData& s, size_t nStart = 0, size_t n = npos) const { return find(s.AsWChar(), nStart, n); } - // find the first occurence of character ch after nStart + // find the first occurrence of character ch after nStart size_t find(wxUniChar ch, size_t nStart = 0) const { #if wxUSE_UNICODE_UTF8 @@ -3080,7 +3082,7 @@ public: size_t rfind(wchar_t ch, size_t nStart = npos) const { return rfind(wxUniChar(ch), nStart); } - // find first/last occurence of any character (not) in the set: + // find first/last occurrence of any character (not) in the set: #if wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8 // FIXME-UTF8: this is not entirely correct, because it doesn't work if // sizeof(wchar_t)==2 and surrogates are present in the string; @@ -3171,7 +3173,7 @@ public: size_t find_last_of(wxUniChar c, size_t nStart = npos) const { return rfind(c, nStart); } - // find first/last occurence of any character not in the set + // find first/last occurrence of any character not in the set // as strspn() (starting from nStart), returns npos on failure size_t find_first_not_of(const wxString& str, size_t nStart = 0) const @@ -3426,7 +3428,7 @@ private: // copying is disallowed as it would result in more than one pointer into // the same linked list - DECLARE_NO_COPY_CLASS(wxStringIteratorNodeHead) + wxDECLARE_NO_COPY_CLASS(wxStringIteratorNodeHead); }; wxStringIteratorNodeHead m_iterators; @@ -3569,7 +3571,7 @@ private: wxString& m_str; wxStringCharType *m_buf; - DECLARE_NO_COPY_CLASS(wxStringInternalBuffer) + wxDECLARE_NO_COPY_CLASS(wxStringInternalBuffer); }; class wxStringInternalBufferLength @@ -3599,13 +3601,13 @@ private: size_t m_len; bool m_lenSet; - DECLARE_NO_COPY_CLASS(wxStringInternalBufferLength) + wxDECLARE_NO_COPY_CLASS(wxStringInternalBufferLength); }; #endif // !wxUSE_STL_BASED_WXSTRING template -class WXDLLIMPEXP_BASE wxStringTypeBufferBase +class wxStringTypeBufferBase { public: typedef T CharType; @@ -3645,8 +3647,7 @@ protected: }; template -class WXDLLIMPEXP_BASE wxStringTypeBufferLengthBase - : public wxStringTypeBufferBase +class wxStringTypeBufferLengthBase : public wxStringTypeBufferBase { public: wxStringTypeBufferLengthBase(wxString& str, size_t lenWanted = 1024) @@ -3680,7 +3681,7 @@ public: this->m_str.assign(this->m_buf.data()); } - DECLARE_NO_COPY_CLASS(wxStringTypeBuffer) + wxDECLARE_NO_COPY_CLASS(wxStringTypeBuffer); }; template @@ -3696,7 +3697,7 @@ public: this->m_str.assign(this->m_buf.data(), this->m_len); } - DECLARE_NO_COPY_CLASS(wxStringTypeBufferLength) + wxDECLARE_NO_COPY_CLASS(wxStringTypeBufferLength); }; #if wxUSE_STL_BASED_WXSTRING @@ -3711,7 +3712,7 @@ public: ~wxStringInternalBuffer() { m_str.m_impl.assign(m_buf.data()); } - DECLARE_NO_COPY_CLASS(wxStringInternalBuffer) + wxDECLARE_NO_COPY_CLASS(wxStringInternalBuffer); }; WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( @@ -3729,7 +3730,7 @@ public: m_str.m_impl.assign(m_buf.data(), m_len); } - DECLARE_NO_COPY_CLASS(wxStringInternalBufferLength) + wxDECLARE_NO_COPY_CLASS(wxStringInternalBufferLength); }; #endif // wxUSE_STL_BASED_WXSTRING @@ -3750,27 +3751,59 @@ typedef wxStringInternalBufferLength wxUTF8StringBufferLength; WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxStringTypeBufferBase ) -class WXDLLIMPEXP_BASE wxUTF8StringBuffer : public wxStringTypeBufferBase +// Note about inlined dtors in the classes below: this is done not for +// performance reasons but just to avoid linking errors in the MSVC DLL build +// under Windows: if a class has non-inline methods it must be declared as +// being DLL-exported but, due to an extremely interesting feature of MSVC 7 +// and later, any template class which is used as a base of a DLL-exported +// class is implicitly made DLL-exported too, as explained at the bottom of +// http://msdn.microsoft.com/en-us/library/twa2aw10.aspx (just to confirm: yes, +// _inheriting_ from a class can change whether it is being exported from DLL) +// +// But this results in link errors because the base template class is not DLL- +// exported, whether it is declared with WXDLLIMPEXP_BASE or not, because it +// does have only inline functions. So the simplest fix is to just make all the +// functions of these classes inline too. + +class wxUTF8StringBuffer : public wxStringTypeBufferBase { public: wxUTF8StringBuffer(wxString& str, size_t lenWanted = 1024) : wxStringTypeBufferBase(str, lenWanted) {} - ~wxUTF8StringBuffer(); + ~wxUTF8StringBuffer() + { + wxMBConvStrictUTF8 conv; + size_t wlen = conv.ToWChar(NULL, 0, m_buf); + wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" ); - DECLARE_NO_COPY_CLASS(wxUTF8StringBuffer) + wxStringInternalBuffer wbuf(m_str, wlen); + conv.ToWChar(wbuf, wlen, m_buf); + } + + wxDECLARE_NO_COPY_CLASS(wxUTF8StringBuffer); }; WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxStringTypeBufferLengthBase ) -class WXDLLIMPEXP_BASE wxUTF8StringBufferLength - : public wxStringTypeBufferLengthBase +class wxUTF8StringBufferLength : public wxStringTypeBufferLengthBase { public: wxUTF8StringBufferLength(wxString& str, size_t lenWanted = 1024) : wxStringTypeBufferLengthBase(str, lenWanted) {} - ~wxUTF8StringBufferLength(); + ~wxUTF8StringBufferLength() + { + wxCHECK_RET(m_lenSet, "length not set"); + + wxMBConvStrictUTF8 conv; + size_t wlen = conv.ToWChar(NULL, 0, m_buf, m_len); + wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" ); - DECLARE_NO_COPY_CLASS(wxUTF8StringBufferLength) + wxStringInternalBufferLength wbuf(m_str, wlen); + conv.ToWChar(wbuf, wlen, m_buf, m_len); + wbuf.SetLength(wlen); + } + + wxDECLARE_NO_COPY_CLASS(wxUTF8StringBufferLength); }; #endif // wxUSE_UNICODE_UTF8/wxUSE_UNICODE_WCHAR @@ -3924,7 +3957,7 @@ inline wxCStrData::wxCStrData(const wxCStrData& data) inline wxCStrData::~wxCStrData() { if ( m_owned ) - delete wx_const_cast(wxString*, m_str); // cast to silence warnings + delete const_cast(m_str); // cast to silence warnings } // simple cases for AsChar() and AsWChar(), the complicated ones are @@ -4047,7 +4080,7 @@ void wxStringIteratorNode::DoSet(const wxString *str, if ( str ) { m_next = str->m_iterators.ptr; - wx_const_cast(wxString*, m_str)->m_iterators.ptr = this; + const_cast(m_str)->m_iterators.ptr = this; if ( m_next ) m_next->m_prev = this; } @@ -4064,7 +4097,7 @@ void wxStringIteratorNode::clear() if ( m_prev ) m_prev->m_next = m_next; else if ( m_str ) // first in the list - wx_const_cast(wxString*, m_str)->m_iterators.ptr = m_next; + const_cast(m_str)->m_iterators.ptr = m_next; m_next = m_prev = NULL; m_citer = NULL; @@ -4081,4 +4114,19 @@ void wxStringIteratorNode::clear() #include "wx/crt.h" #endif +// ---------------------------------------------------------------------------- +// Checks on wxString characters +// ---------------------------------------------------------------------------- + +template + inline bool wxStringCheck(const wxString& val) + { + for ( wxString::const_iterator i = val.begin(); + i != val.end(); + ++i ) + if (T(*i) == 0) + return false; + return true; + } + #endif // _WX_WXSTRING_H_