#include <StringMgr.h>
#endif
-#include "wx/wxchar.h" // for wxChar, wxStrlen() etc.
+#include "wx/wxcrt.h" // for wxChar, wxStrlen() etc.
#include "wx/strvararg.h"
#include "wx/buffer.h" // for wxCharBuffer
#include "wx/strconv.h" // for wxConvertXXX() macros and wxMBConv classes
#include "wx/stringimpl.h"
+#include "wx/stringops.h"
#include "wx/unichar.h"
class WXDLLIMPEXP_BASE wxString;
public:
// Ctor constructs the object from char literal; they are needed to make
// operator?: compile and they intentionally take char*, not const char*
- wxCStrData(char *buf);
- wxCStrData(wchar_t *buf);
+ inline wxCStrData(char *buf);
+ inline wxCStrData(wchar_t *buf);
+ inline wxCStrData(const wxCStrData& data);
inline ~wxCStrData();
const wchar_t* AsWChar() const;
operator const wchar_t*() const { return AsWChar(); }
- inline operator bool() const;
-
#if !wxUSE_UNICODE
inline
#endif
inline wxString AsString() const;
+ // returns the value as C string in internal representation (equivalent
+ // to AsString().wx_str(), but more efficient)
+ const wxStringCharType *AsInternal() const;
+
// allow expressions like "c_str()[0]":
inline wxUniChar operator[](size_t n) const;
wxUniChar operator[](int n) const { return operator[](size_t(n)); }
protected:
wxStringPrintfMixinBase() {}
- int DoPrintf(const wxChar *format, ...) ATTRIBUTE_PRINTF_2;
- static wxString DoFormat(const wxChar *format, ...) ATTRIBUTE_PRINTF_1;
+ int DoPrintf(const wxString& format, ...);
+ static wxString DoFormat(const wxString& format, ...);
};
// this class contains template wrappers for wxString's vararg methods, it's
// these are duplicated wxString methods, they're also declared below
// if !wxNEEDS_WXSTRING_PRINTF_MIXIN:
- // int Printf(const wxChar *pszFormat, ...);
- WX_DEFINE_VARARG_FUNC(int, Printf, DoPrintf)
- // static wxString Format(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1;
- WX_DEFINE_VARARG_FUNC(static typename StringReturnType<T1>::type,
- Format, DoFormat)
- // int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2;
- WX_DEFINE_VARARG_FUNC(int, sprintf, DoPrintf)
+ // static wxString Format(const wString& format, ...) ATTRIBUTE_PRINTF_1;
+ WX_DEFINE_VARARG_FUNC2_SANS_N0(static typename StringReturnType<T1>::type,
+ Format, 1, (const wxString&),
+ DoFormat, DoFormat)
+ // We have to implement the version without template arguments manually
+ // because of the StringReturnType<> hack, although WX_DEFINE_VARARG_FUNC
+ // normally does it itself. It has to be a template so that we can use
+ // the hack, even though there's no real template parameter:
+ struct FormatDummyArg {} ;
+
+ template<typename T>
+ inline static typename StringReturnType<T>::type
+ Format(const wxString& fmt, FormatDummyArg dummy = FormatDummyArg())
+ {
+ return DoFormat(fmt);
+ }
+
+ // int Printf(const wxString& format, ...);
+ WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxString&), DoPrintf)
+ // int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2;
+ WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxString&), DoPrintf)
protected:
wxStringPrintfMixin() : wxStringPrintfMixinBase() {}
// buffer for holding temporary substring when using any of the methods
// that take (char*,size_t) or (wchar_t*,size_t) arguments:
- // FIXME-UTF8: This will need changes when UTF8 build is introduced
template<typename T>
struct SubstrBufFromType
{
{ return ConvertStr(str, n, wxConvLibc); }
#endif
- // moves the iterator to the next Unicode character
- static void IncIter(wxStringImpl::iterator& i) { ++i; }
- static void IncIter(wxStringImpl::const_iterator& i) { ++i; }
- // moves the iterator to the previous Unicode character
- static void DecIter(wxStringImpl::iterator& i) { --i; }
- static void DecIter(wxStringImpl::const_iterator& i) { --i; }
- // moves the iterator by n Unicode characters
- static wxStringImpl::iterator AddToIter(wxStringImpl::iterator i, int n)
- { return i + n; }
- static wxStringImpl::const_iterator AddToIter(wxStringImpl::const_iterator i, int n)
- { return i + n; }
- // returns distance of the two iterators in Unicode characters
- static int DiffIters(wxStringImpl::iterator i1, wxStringImpl::iterator i2)
- { return i1 - i2; }
- static int DiffIters(wxStringImpl::const_iterator i1, wxStringImpl::const_iterator i2)
- { return i1 - i2; }
-
- // encodes the character to a form used to represent it in internal
- // representation (returns a string in UTF8 version)
- static wxChar EncodeChar(wxUniChar ch) { return (wxChar)ch; }
- static wxUniChar DecodeChar(wxStringImpl::const_iterator i) { return *i; }
-
// translates position index in wxString to/from index in underlying
// wxStringImpl:
static size_t PosToImpl(size_t pos) { return pos; }
#else // wxUSE_UNICODE_UTF8
- // checks correctness of UTF-8 sequence
- static bool IsValidUtf8String(const char *c);
-#ifdef __WXDEBUG__
- static bool IsValidUtf8LeadByte(unsigned char c);
-#endif
-
- // table of offsets to skip forward when iterating
- static unsigned char ms_utf8IterTable[256];
-
- static void IncIter(wxStringImpl::iterator& i)
- {
- wxASSERT( IsValidUtf8LeadByte(*i) );
- i += ms_utf8IterTable[(unsigned char)*i];
- }
- static void IncIter(wxStringImpl::const_iterator& i)
- {
- wxASSERT( IsValidUtf8LeadByte(*i) );
- i += ms_utf8IterTable[(unsigned char)*i];
- }
-
- static void DecIter(wxStringImpl::iterator& i);
- static void DecIter(wxStringImpl::const_iterator& i);
- static wxStringImpl::iterator AddToIter(wxStringImpl::iterator i, int n);
- static wxStringImpl::const_iterator AddToIter(wxStringImpl::const_iterator i, int n);
- static int DiffIters(wxStringImpl::const_iterator i1, wxStringImpl::const_iterator i2);
- static int DiffIters(wxStringImpl::iterator i1, wxStringImpl::iterator i2);
-
- struct Utf8CharBuffer
- {
- char data[5];
- operator const char*() const { return data; }
- };
- static Utf8CharBuffer EncodeChar(wxUniChar ch);
- // returns n copies of ch encoded in UTF-8 string
- static wxCharBuffer EncodeNChars(size_t n, wxUniChar ch);
-
- // returns the length of UTF-8 encoding of the character with lead byte 'c'
- static size_t GetUtf8CharLength(char c)
- {
- wxASSERT( IsValidUtf8LeadByte(c) );
- return ms_utf8IterTable[(unsigned char)c];
- }
+ // FIXME-UTF8: return as-is without copying under UTF8 locale, return
+ // converted string under other locales - needs wxCharBuffer
+ // changes
+ static wxCharBuffer ImplStr(const char* str,
+ const wxMBConv& conv = wxConvLibc)
+ { return ConvertStr(str, npos, conv).data; }
+ static SubstrBufFromMB ImplStr(const char* str, size_t n,
+ const wxMBConv& conv = wxConvLibc)
+ { return ConvertStr(str, n, conv); }
- // decodes single UTF-8 character from UTF-8 string
- // FIXME-UTF8: move EncodeChar/DecodeChar and other operations to separate
- // class
- static wxUniChar DecodeChar(wxStringImpl::const_iterator i)
- { return wxUniCharRef::DecodeChar(i); }
- friend class WXDLLIMPEXP_BASE wxUniCharRef;
+ static wxCharBuffer ImplStr(const wchar_t* str)
+ { return ConvertStr(str, npos, wxConvUTF8).data; }
+ static SubstrBufFromWC ImplStr(const wchar_t* str, size_t n)
+ { return ConvertStr(str, n, wxConvUTF8); }
size_t PosToImpl(size_t pos) const
{
else
return const_iterator(m_impl.begin() + pos) - begin();
}
-
- // FIXME-UTF8: return as-is without copying under UTF8 locale, return
- // converted string under other locales - needs wxCharBuffer
- // changes
- static wxCharBuffer ImplStr(const char* str,
- const wxMBConv& conv = wxConvLibc)
- { return ConvertStr(str, npos, conv).data; }
- static SubstrBufFromMB ImplStr(const char* str, size_t n,
- const wxMBConv& conv = wxConvLibc)
- { return ConvertStr(str, n, conv); }
-
- static wxCharBuffer ImplStr(const wchar_t* str)
- { return ConvertStr(str, npos, wxConvUTF8).data; }
- static SubstrBufFromWC ImplStr(const wchar_t* str, size_t n)
- { return ConvertStr(str, n, wxConvUTF8); }
#endif // !wxUSE_UNICODE_UTF8/wxUSE_UNICODE_UTF8
public:
reference operator[](size_t n) const { return *(*this + n); } \
\
iterator_name& operator++() \
- { wxString::IncIter(m_cur); return *this; } \
+ { wxStringOperations::IncIter(m_cur); return *this; } \
iterator_name& operator--() \
- { wxString::DecIter(m_cur); return *this; } \
+ { wxStringOperations::DecIter(m_cur); return *this; } \
iterator_name operator++(int) \
{ \
iterator_name tmp = *this; \
- wxString::IncIter(m_cur); \
+ wxStringOperations::IncIter(m_cur); \
return tmp; \
} \
iterator_name operator--(int) \
{ \
iterator_name tmp = *this; \
- wxString::DecIter(m_cur); \
+ wxStringOperations::DecIter(m_cur); \
return tmp; \
} \
\
iterator_name& operator+=(int n) \
- { m_cur = wxString::AddToIter(m_cur, n); return *this; } \
+ { \
+ m_cur = wxStringOperations::AddToIter(m_cur, n); \
+ return *this; \
+ } \
iterator_name& operator+=(size_t n) \
- { m_cur = wxString::AddToIter(m_cur, (int)n); return *this; } \
+ { \
+ m_cur = wxStringOperations::AddToIter(m_cur, (int)n); \
+ return *this; \
+ } \
iterator_name& operator-=(int n) \
- { m_cur = wxString::AddToIter(m_cur, -n); return *this; } \
+ { \
+ m_cur = wxStringOperations::AddToIter(m_cur, -n); \
+ return *this; \
+ } \
iterator_name& operator-=(size_t n) \
- { m_cur = wxString::AddToIter(m_cur, -(int)n); return *this; } \
+ { \
+ m_cur = wxStringOperations::AddToIter(m_cur, -(int)n); \
+ return *this; \
+ } \
\
difference_type operator-(const iterator_name& i) const \
- { return wxString::DiffIters(m_cur, i.m_cur); } \
+ { return wxStringOperations::DiffIters(m_cur, i.m_cur); } \
\
bool operator==(const iterator_name& i) const \
{ return m_cur == i.m_cur; } \
iterator(const iterator& i) : m_cur(i.m_cur), m_str(i.m_str) {}
iterator operator+(int n) const
- { return iterator(m_str, wxString::AddToIter(m_cur, n)); }
+ { return iterator(m_str, wxStringOperations::AddToIter(m_cur, n)); }
iterator operator+(size_t n) const
- { return iterator(m_str, wxString::AddToIter(m_cur, (int)n)); }
+ { return iterator(m_str, wxStringOperations::AddToIter(m_cur, (int)n)); }
iterator operator-(int n) const
- { return iterator(m_str, wxString::AddToIter(m_cur, -n)); }
+ { return iterator(m_str, wxStringOperations::AddToIter(m_cur, -n)); }
iterator operator-(size_t n) const
- { return iterator(m_str, wxString::AddToIter(m_cur, -(int)n)); }
+ { return iterator(m_str, wxStringOperations::AddToIter(m_cur, -(int)n)); }
private:
iterator(wxString *str, underlying_iterator ptr)
iterator(const iterator& i) : m_cur(i.m_cur) {}
iterator operator+(int n) const
- { return iterator(wxString::AddToIter(m_cur, n)); }
+ { return iterator(wxStringOperations::AddToIter(m_cur, n)); }
iterator operator+(size_t n) const
- { return iterator(wxString::AddToIter(m_cur, (int)n)); }
+ { return iterator(wxStringOperations::AddToIter(m_cur, (int)n)); }
iterator operator-(int n) const
- { return iterator(wxString::AddToIter(m_cur, -n)); }
+ { return iterator(wxStringOperations::AddToIter(m_cur, -n)); }
iterator operator-(size_t n) const
- { return iterator(wxString::AddToIter(m_cur, -(int)n)); }
+ { return iterator(wxStringOperations::AddToIter(m_cur, -(int)n)); }
private:
// for internal wxString use only:
// NB: reference_type is intentionally value, not reference, the character
// may be encoded differently in wxString data:
WX_STR_ITERATOR_IMPL(const_iterator, const wxChar*, wxUniChar,
- wxString::DecodeChar(m_cur));
+ wxStringOperations::DecodeChar(m_cur));
public:
const_iterator(const const_iterator& i) : m_cur(i.m_cur) {}
const_iterator(const iterator& i) : m_cur(i.m_cur) {}
const_iterator operator+(int n) const
- { return const_iterator(wxString::AddToIter(m_cur, n)); }
+ { return const_iterator(wxStringOperations::AddToIter(m_cur, n)); }
const_iterator operator+(size_t n) const
- { return const_iterator(wxString::AddToIter(m_cur, (int)n)); }
+ { return const_iterator(wxStringOperations::AddToIter(m_cur, (int)n)); }
const_iterator operator-(int n) const
- { return const_iterator(wxString::AddToIter(m_cur, -n)); }
+ { return const_iterator(wxStringOperations::AddToIter(m_cur, -n)); }
const_iterator operator-(size_t n) const
- { return const_iterator(wxString::AddToIter(m_cur, -(int)n)); }
+ { return const_iterator(wxStringOperations::AddToIter(m_cur, -(int)n)); }
private:
// for internal wxString use only:
return const_iterator(data.m_str->begin() + data.m_offset);
}
+ // in UTF-8 STL build, creation from std::string requires conversion under
+ // non-UTF8 locales, so we can't have and use wxString(wxStringImpl) ctor;
+ // instead we define dummy type that lets us have wxString ctor for creation
+ // from wxStringImpl that couldn't be used by user code (in all other builds,
+ // "standard" ctors can be used):
+#if wxUSE_UNICODE_UTF8 && wxUSE_STL_BASED_WXSTRING
+ struct CtorFromStringImplTag {};
+
+ wxString(CtorFromStringImplTag* WXUNUSED(dummy), const wxStringImpl& src)
+ : m_impl(src) {}
+
+ static wxString FromImpl(const wxStringImpl& src)
+ { return wxString((CtorFromStringImplTag*)NULL, src); }
+#else
+ #if !wxUSE_STL_BASED_WXSTRING
+ wxString(const wxStringImpl& src) : m_impl(src) { }
+ // else: already defined as wxString(wxStdString) below
+ #endif
+ static wxString FromImpl(const wxStringImpl& src) { return wxString(src); }
+#endif
+
public:
// constructors and destructor
// ctor for an empty string
wxString() {}
// copy ctor
- // FIXME-UTF8: this one needs to do UTF-8 conversion in UTF-8 build!
- wxString(const wxStringImpl& stringSrc) : m_impl(stringSrc) { }
-
wxString(const wxString& stringSrc) : m_impl(stringSrc.m_impl) { }
// string containing nRepeat copies of ch
: m_impl(str.Mid(0, nLength).m_impl) {}
// even if we're not built with wxUSE_STL == 1 it is very convenient to allow
- // implicit conversions from std::string to wxString 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
+ // 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 && !wxUSE_STL_BASED_WXSTRING
- wxString(const wxStdString& s)
- // FIXME-UTF8: this one needs to do UTF-8 conversion in UTF-8 build!
- : m_impl(s.c_str()) { } // FIXME-UTF8: this is broken for embedded 0s
-#endif // wxUSE_STD_STRING && !wxUSE_STL_BASED_WXSTRING
+#if wxUSE_STD_STRING
+ #if wxUSE_UNICODE_WCHAR
+ wxString(const wxStdWideString& str) : m_impl(str) {}
+ #else // UTF-8 or ANSI
+ wxString(const wxStdWideString& str)
+ { assign(str.c_str(), str.length()); }
+ #endif
+
+ #if !wxUSE_UNICODE // ANSI build
+ // FIXME-UTF8: do this in UTF8 build #if wxUSE_UTF8_LOCALE_ONLY, too
+ wxString(const std::string& str) : m_impl(str) {}
+ #else // Unicode
+ wxString(const std::string& str)
+ { assign(str.c_str(), str.length()); }
+ #endif
+ #if wxUSE_UNICODE_WCHAR && wxUSE_STL_BASED_WXSTRING
+ // wxStringImpl is std::string in the encoding we want
+ operator const wxStdWideString&() const { return m_impl; }
+ #else
+ // wxStringImpl is either not std::string or needs conversion
+ operator wxStdWideString() const
+ // FIXME-UTF8: broken for embedded NULs
+ { return wxStdWideString(wc_str()); }
+ #endif
+
+ #if !wxUSE_UNICODE && wxUSE_STL_BASED_WXSTRING
+ // FIXME-UTF8: do this in UTF8 build #if wxUSE_UTF8_LOCALE_ONLY, too
+ // wxStringImpl is std::string in the encoding we want
+ operator const std::string&() const { return m_impl; }
+ #else
+ // wxStringImpl is either not std::string or needs conversion
+ operator std::string() const
+ // FIXME-UTF8: broken for embedded NULs
+ { return std::string(mb_str()); }
+ #endif
+
+#endif // wxUSE_STD_STRING
// first valid index position
const_iterator begin() const { return const_iterator(m_impl.begin()); }
{
size_t pos, len;
PosLenToImpl(nStart, nLen, &pos, &len);
- return m_impl.substr(pos, len);
+ return FromImpl(m_impl.substr(pos, len));
}
// generic attributes & operations
operator const char*() const { return c_str(); }
operator const wchar_t*() const { return c_str(); }
+ // implicit conversion to untyped pointer for compatibility with previous
+ // wxWidgets versions: this is the same as conversion to const char * so it
+ // may fail!
+ operator const void*() const { return c_str(); }
+
// identical to c_str(), for MFC compatibility
const wxCStrData GetData() const { return c_str(); }
// conversion to *non-const* multibyte or widestring buffer; modifying
// returned buffer won't affect the string, these methods are only useful
// for passing values to const-incorrect functions
- wxWritableCharBuffer char_str() const { return mb_str(); }
+ wxWritableCharBuffer char_str(const wxMBConv& conv = wxConvLibc) const
+ { return mb_str(conv); }
wxWritableWCharBuffer wchar_str() const { return wc_str(); }
// conversion to/from plain (i.e. 7 bit) ASCII: this is useful for
{ return *this = cstr.AsString(); }
// from a character
wxString& operator=(wxUniChar ch)
- { m_impl = EncodeChar(ch); return *this; }
+ { m_impl = wxStringOperations::EncodeChar(ch); return *this; }
wxString& operator=(wxUniCharRef ch)
{ return operator=((wxUniChar)ch); }
wxString& operator=(char ch)
// formatted input/output
// as sprintf(), returns the number of characters written or < 0 on error
// (take 'this' into account in attribute parameter count)
- // int Printf(const wxChar *pszFormat, ...);
- WX_DEFINE_VARARG_FUNC(int, Printf, DoPrintf)
+ // int Printf(const wxString& format, ...);
+ WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxString&), DoPrintf)
+#ifdef __WATCOMC__
+ WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const char*), DoPrintf)
+ WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wchar_t*), DoPrintf)
+ WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxCStrData&), DoPrintf)
+#endif
#endif // !wxNEEDS_WXSTRING_PRINTF_MIXIN
// as vprintf(), returns the number of characters written or < 0 on error
int PrintfV(const wxString& format, va_list argptr);
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
// returns the string containing the result of Printf() to it
- // static wxString Format(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1;
- WX_DEFINE_VARARG_FUNC(static wxString, Format, DoFormat)
+ // static wxString Format(const wxString& format, ...) ATTRIBUTE_PRINTF_1;
+ WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wxString&), DoFormat)
+#ifdef __WATCOMC__
+ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+ WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const char*), DoFormat)
+ WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wchar_t*), DoFormat)
+ WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wxCStrData&), DoFormat)
+#endif
#endif
// the same as above, but takes a va_list
static wxString FormatV(const wxString& format, va_list argptr);
//
// get writable buffer of at least nLen bytes. Unget() *must* be called
// a.s.a.p. to put string back in a reasonable state!
- wxDEPRECATED( wxChar *GetWriteBuf(size_t nLen) );
+ wxDEPRECATED( wxStringCharType *GetWriteBuf(size_t nLen) );
// call this immediately after GetWriteBuf() has been used
wxDEPRECATED( void UngetWriteBuf() );
wxDEPRECATED( void UngetWriteBuf(size_t nLen) );
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
// use Printf()
// (take 'this' into account in attribute parameter count)
- // int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2;
- WX_DEFINE_VARARG_FUNC(int, sprintf, DoPrintf)
+ // int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2;
+ WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxString&), DoPrintf)
+#ifdef __WATCOMC__
+ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+ WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const char*), DoPrintf)
+ WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wchar_t*), DoPrintf)
+ WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxCStrData&), DoPrintf)
+#endif
#endif // wxNEEDS_WXSTRING_PRINTF_MIXIN
// use Cmp()
{
#if wxUSE_UNICODE_UTF8
if ( !ch.IsAscii() )
- m_impl.append(EncodeNChars(n, ch));
+ m_impl.append(wxStringOperations::EncodeNChars(n, ch));
else
#endif
m_impl.append(n, (wxStringCharType)ch);
{
#if wxUSE_UNICODE_UTF8
if ( !ch.IsAscii() )
- m_impl.assign(EncodeNChars(n, ch));
+ m_impl.assign(wxStringOperations::EncodeNChars(n, ch));
else
#endif
m_impl.assign(n, (wxStringCharType)ch);
{
#if wxUSE_UNICODE_UTF8
if ( !ch.IsAscii() )
- m_impl.insert(PosToImpl(nPos), EncodeNChars(n, ch));
+ m_impl.insert(PosToImpl(nPos), wxStringOperations::EncodeNChars(n, ch));
else
#endif
m_impl.insert(PosToImpl(nPos), n, (wxStringCharType)ch);
if ( !ch.IsAscii() )
{
size_t pos = IterToImplPos(it);
- m_impl.insert(pos, EncodeChar(ch));
+ m_impl.insert(pos, wxStringOperations::EncodeChar(ch));
return iterator(this, m_impl.begin() + pos);
}
else
{
#if wxUSE_UNICODE_UTF8
if ( !ch.IsAscii() )
- m_impl.insert(IterToImplPos(it), EncodeNChars(n, ch));
+ m_impl.insert(IterToImplPos(it), wxStringOperations::EncodeNChars(n, ch));
else
#endif
m_impl.insert(it.impl(), n, (wxStringCharType)ch);
PosLenToImpl(nStart, nLen, &from, &len);
#if wxUSE_UNICODE_UTF8
if ( !ch.IsAscii() )
- m_impl.replace(from, len, EncodeNChars(nCount, ch));
+ m_impl.replace(from, len, wxStringOperations::EncodeNChars(nCount, ch));
else
#endif
m_impl.replace(from, len, nCount, (wxStringCharType)ch);
{
#if wxUSE_UNICODE_UTF8
if ( !ch.IsAscii() )
- m_impl.replace(first.impl(), last.impl(), EncodeNChars(n, ch));
+ m_impl.replace(first.impl(), last.impl(),
+ wxStringOperations::EncodeNChars(n, ch));
else
#endif
m_impl.replace(first.impl(), last.impl(), n, (wxStringCharType)ch);
// find the first occurence of character ch after nStart
size_t find(wxUniChar ch, size_t nStart = 0) const
- { return PosFromImpl(m_impl.find(EncodeChar(ch), PosToImpl(nStart))); }
+ {
+ return PosFromImpl(m_impl.find(wxStringOperations::EncodeChar(ch),
+ PosToImpl(nStart)));
+ }
size_t find(wxUniCharRef ch, size_t nStart = 0) const
{ return find(wxUniChar(ch), nStart); }
size_t find(char ch, size_t nStart = 0) const
}
// as find, but from the end
size_t rfind(wxUniChar ch, size_t nStart = npos) const
- { return PosFromImpl(m_impl.rfind(EncodeChar(ch), PosToImpl(nStart))); }
+ {
+ return PosFromImpl(m_impl.rfind(wxStringOperations::EncodeChar(ch),
+ PosToImpl(nStart)));
+ }
size_t rfind(wxUniCharRef ch, size_t nStart = npos) const
{ return rfind(wxUniChar(ch), nStart); }
size_t rfind(char ch, size_t nStart = npos) const
{ m_impl += s.AsString().m_impl; return *this; }
// string += char
wxString& operator+=(wxUniChar ch)
- { m_impl += EncodeChar(ch); return *this; }
+ { m_impl += wxStringOperations::EncodeChar(ch); return *this; }
wxString& operator+=(wxUniCharRef ch) { return *this += wxUniChar(ch); }
wxString& operator+=(int ch) { return *this += wxUniChar(ch); }
wxString& operator+=(char ch) { return *this += wxUniChar(ch); }
wxString& operator+=(wchar_t ch) { return *this += wxUniChar(ch); }
private:
-#if !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
+#if !wxUSE_STL_BASED_WXSTRING
// helpers for wxStringBuffer and wxStringBufferLength
wxStringCharType *DoGetWriteBuf(size_t nLen)
{ return m_impl.DoGetWriteBuf(nLen); }
{ m_impl.DoUngetWriteBuf(); }
void DoUngetWriteBuf(size_t nLen)
{ m_impl.DoUngetWriteBuf(nLen); }
-
- friend class WXDLLIMPEXP_BASE wxStringBuffer;
- friend class WXDLLIMPEXP_BASE wxStringBufferLength;
-#endif // !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
+#endif // !wxUSE_STL_BASED_WXSTRING
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
- int DoPrintf(const wxChar *format, ...) ATTRIBUTE_PRINTF_2;
- static wxString DoFormat(const wxChar *format, ...) ATTRIBUTE_PRINTF_1;
+ int DoPrintf(const wxString& format, ...);
+ static wxString DoFormat(const wxString& format, ...);
#endif
#if !wxUSE_STL_BASED_WXSTRING
#if !wxUSE_UNICODE_WCHAR
ConvertedBuffer<wchar_t> m_convertedToWChar;
#endif
+
friend class WXDLLIMPEXP_BASE wxCStrData;
+ friend class wxImplStringBuffer;
+ friend class wxImplStringBufferLength;
};
#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
// wxStringBuffer: a tiny class allowing to get a writable pointer into string
// ----------------------------------------------------------------------------
-#if wxUSE_STL_BASED_WXSTRING || wxUSE_UNICODE_UTF8
+#if !wxUSE_STL_BASED_WXSTRING
+// string buffer for direct access to string data in their native
+// representation:
+class wxImplStringBuffer
+{
+public:
+ typedef wxStringCharType CharType;
-class WXDLLIMPEXP_BASE wxStringBuffer
+ wxImplStringBuffer(wxString& str, size_t lenWanted = 1024)
+ : m_str(str), m_buf(NULL)
+ { m_buf = m_str.DoGetWriteBuf(lenWanted); }
+
+ ~wxImplStringBuffer() { m_str.DoUngetWriteBuf(); }
+
+ operator wxStringCharType*() const { return m_buf; }
+
+private:
+ wxString& m_str;
+ wxStringCharType *m_buf;
+
+ DECLARE_NO_COPY_CLASS(wxImplStringBuffer)
+};
+
+class wxImplStringBufferLength
+{
+public:
+ typedef wxStringCharType CharType;
+
+ wxImplStringBufferLength(wxString& str, size_t lenWanted = 1024)
+ : m_str(str), m_buf(NULL), m_len(0), m_lenSet(false)
+ {
+ m_buf = m_str.DoGetWriteBuf(lenWanted);
+ wxASSERT(m_buf != NULL);
+ }
+
+ ~wxImplStringBufferLength()
+ {
+ wxASSERT(m_lenSet);
+ m_str.DoUngetWriteBuf(m_len);
+ }
+
+ operator wxStringCharType*() const { return m_buf; }
+ void SetLength(size_t length) { m_len = length; m_lenSet = true; }
+
+private:
+ wxString& m_str;
+ wxStringCharType *m_buf;
+ size_t m_len;
+ bool m_lenSet;
+
+ DECLARE_NO_COPY_CLASS(wxImplStringBufferLength)
+};
+
+#endif // !wxUSE_STL_BASED_WXSTRING
+
+template<typename T>
+class wxStringTypeBufferBase
{
public:
- wxStringBuffer(wxString& str, size_t lenWanted = 1024)
+ typedef T CharType;
+
+ wxStringTypeBufferBase(wxString& str, size_t lenWanted = 1024)
: m_str(str), m_buf(lenWanted)
{ }
- ~wxStringBuffer() { m_str.assign(m_buf.data(), wxStrlen(m_buf.data())); }
- operator wxChar*() { return m_buf.data(); }
+ operator CharType*() { return m_buf.data(); }
-private:
+protected:
wxString& m_str;
-#if wxUSE_UNICODE
- wxWCharBuffer m_buf;
-#else
- wxCharBuffer m_buf;
-#endif
-
- DECLARE_NO_COPY_CLASS(wxStringBuffer)
+ wxCharTypeBuffer<CharType> m_buf;
};
-class WXDLLIMPEXP_BASE wxStringBufferLength
+template<typename T>
+class wxStringTypeBufferLengthBase
{
public:
- wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
+ typedef T CharType;
+
+ wxStringTypeBufferLengthBase(wxString& str, size_t lenWanted = 1024)
: m_str(str), m_buf(lenWanted), m_len(0), m_lenSet(false)
{ }
- ~wxStringBufferLength()
+ ~wxStringTypeBufferLengthBase()
{
wxASSERT(m_lenSet);
m_str.assign(m_buf.data(), m_len);
}
- operator wxChar*() { return m_buf.data(); }
+ operator CharType*() { return m_buf.data(); }
void SetLength(size_t length) { m_len = length; m_lenSet = true; }
-private:
+protected:
wxString& m_str;
-#if wxUSE_UNICODE
- wxWCharBuffer m_buf;
-#else
- wxCharBuffer m_buf;
-#endif
+ wxCharTypeBuffer<CharType> m_buf;
size_t m_len;
bool m_lenSet;
-
- DECLARE_NO_COPY_CLASS(wxStringBufferLength)
};
-#else // if !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
+template<typename T>
+class wxStringTypeBuffer : public wxStringTypeBufferBase<T>
+{
+public:
+ wxStringTypeBuffer(wxString& str, size_t lenWanted = 1024)
+ : wxStringTypeBufferBase<T>(str, lenWanted) {}
+ ~wxStringTypeBuffer()
+ {
+ this->m_str.assign(this->m_buf.data());
+ }
-class WXDLLIMPEXP_BASE wxStringBuffer
+ DECLARE_NO_COPY_CLASS(wxStringTypeBuffer)
+};
+
+template<typename T>
+class wxStringTypeBufferLength : public wxStringTypeBufferLengthBase<T>
{
public:
- wxStringBuffer(wxString& str, size_t lenWanted = 1024)
- : m_str(str), m_buf(NULL)
- { m_buf = m_str.DoGetWriteBuf(lenWanted); }
+ wxStringTypeBufferLength(wxString& str, size_t lenWanted = 1024)
+ : wxStringTypeBufferLengthBase<T>(str, lenWanted) {}
- ~wxStringBuffer() { m_str.DoUngetWriteBuf(); }
+ ~wxStringTypeBufferLength()
+ {
+ wxASSERT(this->m_lenSet);
+ this->m_str.assign(this->m_buf.data(), this->m_len);
+ }
- operator wxChar*() const { return m_buf; }
+ DECLARE_NO_COPY_CLASS(wxStringTypeBufferLength)
+};
-private:
- wxString& m_str;
- wxChar *m_buf;
+#if wxUSE_STL_BASED_WXSTRING
+class wxImplStringBuffer : public wxStringTypeBufferBase<wxStringCharType>
+{
+public:
+ wxImplStringBuffer(wxString& str, size_t lenWanted = 1024)
+ : wxStringTypeBufferBase<wxStringCharType>(str, lenWanted) {}
+ ~wxImplStringBuffer()
+ { m_str.m_impl.assign(m_buf.data()); }
- DECLARE_NO_COPY_CLASS(wxStringBuffer)
+ DECLARE_NO_COPY_CLASS(wxImplStringBuffer)
};
-class WXDLLIMPEXP_BASE wxStringBufferLength
+class wxImplStringBufferLength : public wxStringTypeBufferLengthBase<wxStringCharType>
{
public:
- wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
- : m_str(str), m_buf(NULL), m_len(0), m_lenSet(false)
- {
- m_buf = m_str.DoGetWriteBuf(lenWanted);
- wxASSERT(m_buf != NULL);
- }
+ wxImplStringBufferLength(wxString& str, size_t lenWanted = 1024)
+ : wxStringTypeBufferLengthBase<wxStringCharType>(str, lenWanted) {}
- ~wxStringBufferLength()
+ ~wxImplStringBufferLength()
{
wxASSERT(m_lenSet);
- m_str.DoUngetWriteBuf(m_len);
+ m_str.m_impl.assign(m_buf.data(), m_len);
}
- operator wxChar*() const { return m_buf; }
- void SetLength(size_t length) { m_len = length; m_lenSet = true; }
-
-private:
- wxString& m_str;
- wxChar *m_buf;
- size_t m_len;
- bool m_lenSet;
-
- DECLARE_NO_COPY_CLASS(wxStringBufferLength)
+ DECLARE_NO_COPY_CLASS(wxImplStringBufferLength)
};
+#endif // wxUSE_STL_BASED_WXSTRING
+
+#if wxUSE_STL_BASED_WXSTRING || wxUSE_UNICODE_UTF8
+typedef wxStringTypeBuffer<wxChar> wxStringBuffer;
+typedef wxStringTypeBufferLength<wxChar> wxStringBufferLength;
+#else // if !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
+typedef wxImplStringBuffer wxStringBuffer;
+typedef wxImplStringBufferLength wxStringBufferLength;
#endif // !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
// ---------------------------------------------------------------------------
// wxString comparison functions: operator versions are always case sensitive
// ---------------------------------------------------------------------------
-#define wxCMP_WXCHAR_STRING(p, s, op) s.Cmp(p) op 0
+#define wxCMP_WXCHAR_STRING(p, s, op) 0 op s.Cmp(p)
wxDEFINE_ALL_COMPARISONS(const wxChar *, const wxString&, wxCMP_WXCHAR_STRING)
inline wxCStrData::wxCStrData(wchar_t *buf)
: m_str(new wxString(buf)), m_offset(0), m_owned(true) {}
-inline wxCStrData::~wxCStrData()
+inline wxCStrData::wxCStrData(const wxCStrData& data)
+ : m_str(data.m_owned ? new wxString(*data.m_str) : data.m_str),
+ m_offset(data.m_offset),
+ m_owned(data.m_owned)
{
- if ( m_owned )
- delete m_str;
}
-inline wxCStrData::operator bool() const
+inline wxCStrData::~wxCStrData()
{
- return !m_str->empty();
+ if ( m_owned )
+ delete m_str;
}
// simple cases for AsChar() and AsWChar(), the complicated ones are
return m_str->Mid(m_offset);
}
+inline const wxStringCharType *wxCStrData::AsInternal() const
+{
+ return wxStringOperations::AddToIter(m_str->wx_str(), m_offset);
+}
+
inline wxUniChar wxCStrData::operator*() const
{
if ( m_str->empty() )
inline wxUniChar wxCStrData::operator[](size_t n) const
{
- return m_str->at(m_offset + n);
+ // NB: we intentionally use operator[] and not at() here because the former
+ // works for the terminating NUL while the latter does not
+ return (*m_str)[m_offset + n];
}
// ----------------------------------------------------------------------------
{
}
+#if WXWIN_COMPATIBILITY_2_8
+ // lot of code out there doesn't explicitly include wx/wxchar.h, but uses
+ // CRT wrappers that are now declared in wx/wxcrt.h and wx/wxcrtvararg.h,
+ // so let's include this header now that wxString is defined and it's safe
+ // to do it:
+ #include "wx/wxchar.h"
+#endif
+
#endif // _WX_WXSTRING_H_