// 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
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
// 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;
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<wxString*>(m_node.m_str); }
wxStringIteratorNode m_node;
const wchar_t* t_str() const { return wx_str(); }
#else
const char* t_str() const { return wx_str(); }
-#endif
+#endif
// overloaded assignment
#endif // !wxUSE_STL_BASED_WXSTRING
template<typename T>
-class WXDLLIMPEXP_BASE wxStringTypeBufferBase
+class wxStringTypeBufferBase
{
public:
typedef T CharType;
};
template<typename T>
-class WXDLLIMPEXP_BASE wxStringTypeBufferLengthBase
- : public wxStringTypeBufferBase<T>
+class wxStringTypeBufferLengthBase : public wxStringTypeBufferBase<T>
{
public:
wxStringTypeBufferLengthBase(wxString& str, size_t lenWanted = 1024)
WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxStringTypeBufferBase<char> )
-class WXDLLIMPEXP_BASE wxUTF8StringBuffer : public wxStringTypeBufferBase<char>
+// 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<char>
{
public:
wxUTF8StringBuffer(wxString& str, size_t lenWanted = 1024)
: wxStringTypeBufferBase<char>(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?" );
+
+ wxStringInternalBuffer wbuf(m_str, wlen);
+ conv.ToWChar(wbuf, wlen, m_buf);
+ }
DECLARE_NO_COPY_CLASS(wxUTF8StringBuffer)
};
WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxStringTypeBufferLengthBase<char> )
-class WXDLLIMPEXP_BASE wxUTF8StringBufferLength
- : public wxStringTypeBufferLengthBase<char>
+class wxUTF8StringBufferLength : public wxStringTypeBufferLengthBase<char>
{
public:
wxUTF8StringBufferLength(wxString& str, size_t lenWanted = 1024)
: wxStringTypeBufferLengthBase<char>(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?" );
+
+ wxStringInternalBufferLength wbuf(m_str, wlen);
+ conv.ToWChar(wbuf, wlen, m_buf, m_len);
+ wbuf.SetLength(wlen);
+ }
DECLARE_NO_COPY_CLASS(wxUTF8StringBufferLength)
};
inline wxCStrData::~wxCStrData()
{
if ( m_owned )
- delete wx_const_cast(wxString*, m_str); // cast to silence warnings
+ delete const_cast<wxString*>(m_str); // cast to silence warnings
}
// simple cases for AsChar() and AsWChar(), the complicated ones are
if ( str )
{
m_next = str->m_iterators.ptr;
- wx_const_cast(wxString*, m_str)->m_iterators.ptr = this;
+ const_cast<wxString*>(m_str)->m_iterators.ptr = this;
if ( m_next )
m_next->m_prev = this;
}
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<wxString*>(m_str)->m_iterators.ptr = m_next;
m_next = m_prev = NULL;
m_citer = NULL;
#include "wx/crt.h"
#endif
+// ----------------------------------------------------------------------------
+// Checks on wxString characters
+// ----------------------------------------------------------------------------
+
+template<bool (T)(const wxUniChar& c)>
+ 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_