#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
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
+#if !wxUSE_UNICODE || wxUSE_UTF8_LOCALE_ONLY
inline
#endif
const char* AsChar() const;
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;
+#if !wxUSE_UTF8_LOCALE_ONLY
+ int DoPrintfWchar(const wxChar *format, ...);
+ static wxString DoFormatWchar(const wxChar *format, ...);
+#endif
+#if wxUSE_UNICODE_UTF8
+ int DoPrintfUtf8(const char *format, ...);
+ static wxString DoFormatUtf8(const char *format, ...);
+#endif
};
// 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_FUNC_SANS_N0(static typename StringReturnType<T1>::type,
+ Format, 1, (const wxFormatString&),
+ DoFormatWchar, DoFormatUtf8)
+ // 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 wxFormatString& fmt, FormatDummyArg dummy = FormatDummyArg())
+ {
+ return DoFormatWchar(fmt);
+ }
+
+ // int Printf(const wxString& format, ...);
+ WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxFormatString&),
+ DoPrintfWchar, DoPrintfUtf8)
+ // int sprintf(const wxString& format, ...) ATTRIBUTE_PRINTF_2;
+ WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxFormatString&),
+ DoPrintfWchar, DoPrintfUtf8)
protected:
wxStringPrintfMixin() : wxStringPrintfMixinBase() {}
#else // wxUSE_UNICODE_UTF8
- // 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 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
// 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) {}
#else // UTF-8 or ANSI
{ 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
+ #if (!wxUSE_UNICODE || wxUSE_UTF8_LOCALE_ONLY) && wxUSE_STL_BASED_WXSTRING
// wxStringImpl is std::string in the encoding we want
operator const std::string&() const { return m_impl; }
#else
// FIXME-UTF8: broken for embedded NULs
{ return std::string(mb_str()); }
#endif
-
-#endif // wxUSE_STD_STRING
+#endif // wxUSE_STL
// first valid index position
const_iterator begin() const { return const_iterator(m_impl.begin()); }
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(); }
const char *ToAscii() const { return c_str(); }
#endif // Unicode/!Unicode
+ // conversion to/from UTF-8:
+#if wxUSE_UNICODE_UTF8
+ static wxString FromUTF8(const char *utf8)
+ {
+ wxASSERT( wxStringOperations::IsValidUtf8String(utf8) );
+ return FromImpl(wxStringImpl(utf8));
+ }
+ static wxString FromUTF8(const char *utf8, size_t len)
+ {
+ wxASSERT( wxStringOperations::IsValidUtf8String(utf8, len) );
+ return FromImpl(wxStringImpl(utf8, len));
+ }
+ const char* utf8_str() const { return wx_str(); }
+ const char* ToUTF8() const { return wx_str(); }
+#elif wxUSE_UNICODE_WCHAR
+ static wxString FromUTF8(const char *utf8)
+ { return wxString(utf8, wxConvUTF8); }
+ static wxString FromUTF8(const char *utf8, size_t len)
+ { return wxString(utf8, wxConvUTF8, len); }
+ const wxCharBuffer utf8_str() const { return mb_str(wxConvUTF8); }
+ const wxCharBuffer ToUTF8() const { return utf8_str(); }
+#else // ANSI
+ static wxString FromUTF8(const char *utf8)
+ { return wxString(wxConvUTF8.cMB2WC(utf8)); }
+ static wxString FromUTF8(const char *utf8, size_t len)
+ {
+ size_t wlen;
+ wxWCharBuffer buf(wxConvUTF8.cMB2WC(utf8, len == npos ? wxNO_LEN : len, &wlen));
+ return wxString(buf.data(), wlen);
+ }
+ const wxCharBuffer utf8_str() const { return wxConvUTF8.cWC2MB(wc_str()); }
+ const wxCharBuffer ToUTF8() const { return utf8_str(); }
+#endif
+
+ // functions for storing binary data in wxString:
+#if wxUSE_UNICODE
+ static wxString From8BitData(const char *data, size_t len)
+ { return wxString(data, wxConvISO8859_1, len); }
+ // version for NUL-terminated data:
+ static wxString From8BitData(const char *data)
+ { return wxString(data, wxConvISO8859_1); }
+ const wxCharBuffer To8BitData() const { return mb_str(wxConvISO8859_1); }
+#else // ANSI
+ static wxString From8BitData(const char *data, size_t len)
+ { return wxString(data, len); }
+ // version for NUL-terminated data:
+ static wxString From8BitData(const char *data)
+ { return wxString(data); }
+ const char *To8BitData() const { return c_str(); }
+#endif // Unicode/ANSI
+
// conversions with (possible) format conversions: have to return a
// buffer with temporary data
//
// type differs because a function may either return pointer to the buffer
// directly or have to use intermediate buffer for translation.
#if wxUSE_UNICODE
+
+#if wxUSE_UTF8_LOCALE_ONLY
+ const char* mb_str() const { return wx_str(); }
+ const wxCharBuffer mb_str(const wxMBConv& conv) const;
+#else
const wxCharBuffer mb_str(const wxMBConv& conv = wxConvLibc) const;
+#endif
const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); }
// string += buffer (i.e. from wxGetString)
wxString& operator<<(const wxWCharBuffer& s)
{ return operator<<((const wchar_t *)s); }
- wxString& operator+=(const wxWCharBuffer& s)
- { return operator<<((const wchar_t *)s); }
-
wxString& operator<<(const wxCharBuffer& s)
{ return operator<<((const char *)s); }
- wxString& operator+=(const wxCharBuffer& s)
- { return operator<<((const char *)s); }
// string += C string
wxString& Append(const wxString& s)
append(s);
return *this;
}
- wxString& Append(const wxCStrData& psz)
- { append(psz); return *this; }
wxString& Append(const char* psz)
{ append(psz); return *this; }
wxString& Append(const wchar_t* pwz)
{ append(pwz); return *this; }
+ wxString& Append(const wxCStrData& psz)
+ { append(psz); return *this; }
+ wxString& Append(const wxCharBuffer& psz)
+ { append(psz); return *this; }
+ wxString& Append(const wxWCharBuffer& psz)
+ { append(psz); return *this; }
// append count copies of given character
wxString& Append(wxUniChar ch, size_t count = 1u)
{ append(count, ch); return *this; }
{ return compare(pwz); }
int Cmp(const wxString& s) const
{ return compare(s); }
+ int Cmp(const wxCStrData& s) const
+ { return compare(s); }
+ int Cmp(const wxCharBuffer& s) const
+ { return compare(s); }
+ int Cmp(const wxWCharBuffer& s) const
+ { return compare(s); }
// same as Cmp() but not case-sensitive
int CmpNoCase(const wxString& s) const;
- int CmpNoCase(const char *psz) const
- { return CmpNoCase(wxString(psz)); }
- int CmpNoCase(const wchar_t *pwz) const
- { return CmpNoCase(wxString(pwz)); }
// test for the string equality, either considering case or not
// (if compareWithCase then the case matters)
bool IsSameAs(const wxString& str, bool compareWithCase = true) const
{ return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; }
bool IsSameAs(const wchar_t *str, bool compareWithCase = true) const
{ return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; }
+ bool IsSameAs(const wxCStrData& str, bool compareWithCase = true) const
+ { return IsSameAs(str.AsString(), compareWithCase); }
+ bool IsSameAs(const wxCharBuffer& str, bool compareWithCase = true) const
+ { return IsSameAs(str.data(), compareWithCase); }
+ bool IsSameAs(const wxWCharBuffer& str, bool compareWithCase = true) const
+ { return IsSameAs(str.data(), compareWithCase); }
// comparison with a single character: returns true if equal
bool IsSameAs(wxUniChar c, bool compareWithCase = true) const
{
int Find(wchar_t ch, bool bFromEnd = false) const
{ return Find(wxUniChar(ch), bFromEnd); }
// searching (return starting index, or -1 if not found)
- // FIXME-UTF8: keep wxString overload only
int Find(const wxString& sub) const // like strstr
{
size_type idx = find(sub);
return (idx == npos) ? wxNOT_FOUND : (int)idx;
}
+ int Find(const wxCStrData& sub) const
+ { return Find(sub.AsString()); }
+ int Find(const wxCharBuffer& sub) const
+ { return Find(sub.data()); }
+ int Find(const wxWCharBuffer& sub) const
+ { return Find(sub.data()); }
+
// replace first (or all of bReplaceAll) occurences of substring with
// another string, returns the number of replacements made
size_t Replace(const wxString& strOld,
// 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 wxFormatString&),
+ DoPrintfWchar, DoPrintfUtf8)
+#ifdef __WATCOMC__
+ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+ WX_VARARG_WATCOM_WORKAROUND(int, Printf, 1, (const wxString&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, Printf, 1, (const wxCStrData&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, Printf, 1, (const char*),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, Printf, 1, (const wchar_t*),
+ (wxFormatString(f1)));
+#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 wxFormatString&),
+ DoFormatWchar, DoFormatUtf8)
+#ifdef __WATCOMC__
+ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+ WX_VARARG_WATCOM_WORKAROUND(static wxString, Format, 1, (const wxString&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(static wxString, Format, 1, (const wxCStrData&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(static wxString, Format, 1, (const char*),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(static wxString, Format, 1, (const wchar_t*),
+ (wxFormatString(f1)));
+#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 wxFormatString&),
+ DoPrintfWchar, DoPrintfUtf8)
+#ifdef __WATCOMC__
+ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+ WX_VARARG_WATCOM_WORKAROUND(int, sprintf, 1, (const wxString&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, sprintf, 1, (const wxCStrData&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, sprintf, 1, (const char*),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, sprintf, 1, (const wchar_t*),
+ (wxFormatString(f1)));
+#endif
#endif // wxNEEDS_WXSTRING_PRINTF_MIXIN
// use Cmp()
int First( char ch ) const { return Find(ch); }
int First( unsigned char ch ) const { return Find(ch); }
int First( wchar_t ch ) const { return Find(ch); }
- int First( const wxChar* psz ) const { return Find(psz); }
int First( const wxString& str ) const { return Find(str); }
int Last( wxUniChar ch ) const { return Find(ch, true); }
bool Contains(const wxString& str) const { return Find(str) != wxNOT_FOUND; }
// append a string
wxString& append(const wxString& str)
{ m_impl.append(str.m_impl); return *this; }
- wxString& append(const wxCStrData& str)
- { m_impl.append(str.AsString().m_impl); return *this; }
// append first n (or all if n == npos) characters of sz
wxString& append(const char *sz)
{ m_impl.append(ImplStr(sz)); return *this; }
m_impl.append(str.data, str.len);
return *this;
}
+
+ wxString& append(const wxCStrData& str)
+ { return append(str.AsString()); }
+ wxString& append(const wxCharBuffer& str)
+ { return append(str.data()); }
+ wxString& append(const wxWCharBuffer& str)
+ { return append(str.data()); }
+
// append n copies of ch
wxString& append(size_t n, wxUniChar ch)
{
m_impl.assign(str.data, str.len);
return *this;
}
+
+ wxString& assign(const wxCStrData& str)
+ { return assign(str.AsString()); }
+ wxString& assign(const wxCharBuffer& str)
+ { return assign(str.data()); }
+ wxString& assign(const wxWCharBuffer& str)
+ { return assign(str.data()); }
+ wxString& assign(const wxCStrData& str, size_t len)
+ { return assign(str.AsString(), len); }
+ wxString& assign(const wxCharBuffer& str, size_t len)
+ { return assign(str.data(), len); }
+ wxString& assign(const wxWCharBuffer& str, size_t len)
+ { return assign(str.data(), len); }
+
// same as `= n copies of ch'
wxString& assign(size_t n, wxUniChar ch)
{
// string comparison
int compare(const wxString& str) const;
+ int compare(const char* sz) const;
+ int compare(const wchar_t* sz) const;
+ int compare(const wxCStrData& str) const
+ { return compare(str.AsString()); }
+ int compare(const wxCharBuffer& str) const
+ { return compare(str.data()); }
+ int compare(const wxWCharBuffer& str) const
+ { return compare(str.data()); }
// comparison with a substring
int compare(size_t nStart, size_t nLen, const wxString& str) const;
// comparison of 2 substrings
int compare(size_t nStart, size_t nLen,
const wxString& str, size_t nStart2, size_t nLen2) const;
- // just like strcmp()
- int compare(const char* sz) const;
- int compare(const wchar_t* sz) const;
// substring comparison with first nCount characters of sz
int compare(size_t nStart, size_t nLen,
const char* sz, size_t nCount = npos) const;
SubstrBufFromWC str(ImplStr(sz, n));
return PosFromImpl(m_impl.find(str.data, PosToImpl(nStart), str.len));
}
+ size_t find(const wxCharBuffer& s, size_t nStart = 0, size_t n = npos) const
+ { return find(s.data(), nStart, n); }
+ size_t find(const wxWCharBuffer& s, size_t nStart = 0, size_t n = npos) const
+ { return find(s.data(), nStart, n); }
+ 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
size_t find(wxUniChar ch, size_t nStart = 0) const
SubstrBufFromWC str(ImplStr(sz, n));
return PosFromImpl(m_impl.rfind(str.data, PosToImpl(nStart), str.len));
}
+ size_t rfind(const wxCharBuffer& s, size_t nStart = npos, size_t n = npos) const
+ { return rfind(s.data(), nStart, n); }
+ size_t rfind(const wxWCharBuffer& s, size_t nStart = npos, size_t n = npos) const
+ { return rfind(s.data(), nStart, n); }
+ size_t rfind(const wxCStrData& s, size_t nStart = npos, size_t n = npos) const
+ { return rfind(s.AsWChar(), nStart, n); }
// as find, but from the end
size_t rfind(wxUniChar ch, size_t nStart = npos) const
{
// as strpbrk() but starts at nStart, returns npos if not found
size_t find_first_of(const wxString& str, size_t nStart = 0) const
#if wxUSE_UNICODE // FIXME-UTF8: temporary
- { return find_first_of(str.mb_str().data(), nStart); }
+ { return find_first_of(str.wc_str(), nStart); }
#else
- { return find_first_of((const wxChar*)str.c_str(), nStart); }
+ { return find_first_of(str.mb_str(), nStart); }
#endif
// same as above
size_t find_first_of(const char* sz, size_t nStart = 0) const;
// find the last (starting from nStart) char from str in this string
size_t find_last_of (const wxString& str, size_t nStart = npos) const
#if wxUSE_UNICODE // FIXME-UTF8: temporary
- { return find_last_of(str.mb_str().data(), nStart); }
+ { return find_last_of(str.wc_str(), nStart); }
#else
- { return find_last_of((const wxChar*)str.c_str(), nStart); }
+ { return find_last_of(str.mb_str(), nStart); }
#endif
// same as above
size_t find_last_of (const char* sz, size_t nStart = npos) const;
// as strspn() (starting from nStart), returns npos on failure
size_t find_first_not_of(const wxString& str, size_t nStart = 0) const
#if wxUSE_UNICODE // FIXME-UTF8: temporary
- { return find_first_not_of(str.mb_str().data(), nStart); }
+ { return find_first_not_of(str.wc_str(), nStart); }
#else
- { return find_first_not_of((const wxChar*)str.c_str(), nStart); }
+ { return find_first_not_of(str.mb_str(), nStart); }
#endif
// same as above
size_t find_first_not_of(const char* sz, size_t nStart = 0) const;
// as strcspn()
size_t find_last_not_of(const wxString& str, size_t nStart = npos) const
#if wxUSE_UNICODE // FIXME-UTF8: temporary
- { return find_last_not_of(str.mb_str().data(), nStart); }
+ { return find_last_not_of(str.wc_str(), nStart); }
#else
- { return find_last_not_of((const wxChar*)str.c_str(), nStart); }
+ { return find_last_not_of(str.mb_str(), nStart); }
#endif
// same as above
size_t find_last_not_of(const char* sz, size_t nStart = npos) const;
size_t find_last_not_of(wchar_t ch, size_t nStart = npos) const
{ return find_last_not_of(wxUniChar(ch), nStart); }
+ // and additional overloads for the versions taking strings:
+ size_t find_first_of(const wxCStrData& sz, size_t nStart = 0) const
+ { return find_first_of(sz.AsString(), nStart); }
+ size_t find_first_of(const wxCharBuffer& sz, size_t nStart = 0) const
+ { return find_first_of(sz.data(), nStart); }
+ size_t find_first_of(const wxWCharBuffer& sz, size_t nStart = 0) const
+ { return find_first_of(sz.data(), nStart); }
+ size_t find_first_of(const wxCStrData& sz, size_t nStart, size_t n) const
+ { return find_first_of(sz.AsWChar(), nStart, n); }
+ size_t find_first_of(const wxCharBuffer& sz, size_t nStart, size_t n) const
+ { return find_first_of(sz.data(), nStart, n); }
+ size_t find_first_of(const wxWCharBuffer& sz, size_t nStart, size_t n) const
+ { return find_first_of(sz.data(), nStart, n); }
+
+ size_t find_last_of(const wxCStrData& sz, size_t nStart = 0) const
+ { return find_last_of(sz.AsString(), nStart); }
+ size_t find_last_of(const wxCharBuffer& sz, size_t nStart = 0) const
+ { return find_last_of(sz.data(), nStart); }
+ size_t find_last_of(const wxWCharBuffer& sz, size_t nStart = 0) const
+ { return find_last_of(sz.data(), nStart); }
+ size_t find_last_of(const wxCStrData& sz, size_t nStart, size_t n) const
+ { return find_last_of(sz.AsWChar(), nStart, n); }
+ size_t find_last_of(const wxCharBuffer& sz, size_t nStart, size_t n) const
+ { return find_last_of(sz.data(), nStart, n); }
+ size_t find_last_of(const wxWCharBuffer& sz, size_t nStart, size_t n) const
+ { return find_last_of(sz.data(), nStart, n); }
+
+ size_t find_first_not_of(const wxCStrData& sz, size_t nStart = 0) const
+ { return find_first_not_of(sz.AsString(), nStart); }
+ size_t find_first_not_of(const wxCharBuffer& sz, size_t nStart = 0) const
+ { return find_first_not_of(sz.data(), nStart); }
+ size_t find_first_not_of(const wxWCharBuffer& sz, size_t nStart = 0) const
+ { return find_first_not_of(sz.data(), nStart); }
+ size_t find_first_not_of(const wxCStrData& sz, size_t nStart, size_t n) const
+ { return find_first_not_of(sz.AsWChar(), nStart, n); }
+ size_t find_first_not_of(const wxCharBuffer& sz, size_t nStart, size_t n) const
+ { return find_first_not_of(sz.data(), nStart, n); }
+ size_t find_first_not_of(const wxWCharBuffer& sz, size_t nStart, size_t n) const
+ { return find_first_not_of(sz.data(), nStart, n); }
+
+ size_t find_last_not_of(const wxCStrData& sz, size_t nStart = 0) const
+ { return find_last_not_of(sz.AsString(), nStart); }
+ size_t find_last_not_of(const wxCharBuffer& sz, size_t nStart = 0) const
+ { return find_last_not_of(sz.data(), nStart); }
+ size_t find_last_not_of(const wxWCharBuffer& sz, size_t nStart = 0) const
+ { return find_last_not_of(sz.data(), nStart); }
+ size_t find_last_not_of(const wxCStrData& sz, size_t nStart, size_t n) const
+ { return find_last_not_of(sz.AsWChar(), nStart, n); }
+ size_t find_last_not_of(const wxCharBuffer& sz, size_t nStart, size_t n) const
+ { return find_last_not_of(sz.data(), nStart, n); }
+ size_t find_last_not_of(const wxWCharBuffer& sz, size_t nStart, size_t n) const
+ { return find_last_not_of(sz.data(), nStart, n); }
+
// string += string
wxString& operator+=(const wxString& s)
{ m_impl += s.m_impl; return *this; }
{ m_impl += ImplStr(pwz); return *this; }
wxString& operator+=(const wxCStrData& s)
{ m_impl += s.AsString().m_impl; return *this; }
+ wxString& operator+=(const wxCharBuffer& s)
+ { return operator+=(s.data()); }
+ wxString& operator+=(const wxWCharBuffer& s)
+ { return operator+=(s.data()); }
// string += char
wxString& operator+=(wxUniChar ch)
{ m_impl += wxStringOperations::EncodeChar(ch); return *this; }
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;
+ #if !wxUSE_UTF8_LOCALE_ONLY
+ int DoPrintfWchar(const wxChar *format, ...);
+ static wxString DoFormatWchar(const wxChar *format, ...);
+ #endif
+ #if wxUSE_UNICODE_UTF8
+ int DoPrintfUtf8(const char *format, ...);
+ static wxString DoFormatUtf8(const char *format, ...);
+ #endif
#endif
#if !wxUSE_STL_BASED_WXSTRING
T *m_buf;
};
-#if wxUSE_UNICODE
+#if wxUSE_UNICODE && !wxUSE_UTF8_LOCALE_ONLY
ConvertedBuffer<char> m_convertedToChar;
#endif
#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;
+
+ 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;
-class WXDLLIMPEXP_BASE wxStringBuffer
+ DECLARE_NO_COPY_CLASS(wxImplStringBuffer)
+};
+
+class wxImplStringBufferLength
{
public:
- wxStringBuffer(wxString& str, size_t lenWanted = 1024)
+ 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:
+ 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());
+ }
+
+ DECLARE_NO_COPY_CLASS(wxStringTypeBuffer)
+};
-class WXDLLIMPEXP_BASE wxStringBuffer
+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
// ---------------------------------------------------------------------------
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
}
#endif // wxUSE_UNICODE_WCHAR
-#if !wxUSE_UNICODE
+#if !wxUSE_UNICODE || wxUSE_UTF8_LOCALE_ONLY
inline const char* wxCStrData::AsChar() const
{
- return m_str->wx_str() + m_offset;
+ return wxStringOperations::AddToIter(m_str->wx_str(), m_offset);
}
#endif // !wxUSE_UNICODE
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_