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;
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;
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,
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
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;
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
#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;