// static class variables definition
// ---------------------------------------------------------------------------
-#if !wxUSE_STL
+#if !wxUSE_STL_BASED_WXSTRING
//According to STL _must_ be a -1 size_t
const size_t wxStringBase::npos = (size_t) -1;
#endif
// static data
// ----------------------------------------------------------------------------
-#if wxUSE_STL
+#if wxUSE_STL_BASED_WXSTRING
extern const wxChar WXDLLIMPEXP_BASE *wxEmptyString = _T("");
wxSTD ostream& operator<<(wxSTD ostream& os, const wxString& str)
{
-#ifdef __BORLANDC__
- os << str.mb_str();
+ return os << str.c_str();
+}
+
+wxSTD ostream& operator<<(wxSTD ostream& os, const wxCStrData& str)
+{
+#if wxUSE_UNICODE && !defined(__BORLANDC__)
+ return os << str.AsWChar();
#else
- os << str.c_str();
+ return os << str.AsChar();
#endif
- return os;
}
#endif // wxUSE_STD_IOSTREAM
#define STATISTICS_ADD(av, val)
#endif // WXSTRING_STATISTICS
-#if !wxUSE_STL
+#if !wxUSE_STL_BASED_WXSTRING
// ===========================================================================
// wxStringData class deallocation
}
}
-wxStringBase::wxStringBase(size_type n, wxChar ch)
+wxStringBase::wxStringBase(size_type n, wxUniChar ch)
{
Init();
append(n, ch);
return true;
}
-wxStringBase& wxStringBase::append(size_t n, wxChar ch)
+wxStringBase& wxStringBase::append(size_t n, wxUniChar ch)
{
size_type len = length();
return *this;
}
-void wxStringBase::resize(size_t nSize, wxChar ch)
+void wxStringBase::resize(size_t nSize, wxUniChar ch)
{
size_t len = length();
return find(wxStringBase(sz, n), nStart);
}
-size_t wxStringBase::find(wxChar ch, size_t nStart) const
+size_t wxStringBase::find(wxUniChar ch, size_t nStart) const
{
wxASSERT( nStart <= length() );
return rfind(wxStringBase(sz, n), nStart);
}
-size_t wxStringBase::rfind(wxChar ch, size_t nStart) const
+size_t wxStringBase::rfind(wxUniChar ch, size_t nStart) const
{
if ( nStart == npos )
{
return find_first_not_of(wxStringBase(sz, n), nStart);
}
-size_t wxStringBase::find_first_not_of(wxChar ch, size_t nStart) const
+size_t wxStringBase::find_first_not_of(wxUniChar ch, size_t nStart) const
{
wxASSERT( nStart <= length() );
- for ( const wxChar *p = c_str() + nStart; *p; p++ )
+ for ( const_iterator p = begin() + nStart; (bool)*p; ++p ) // FIXME-DMARS
{
if ( *p != ch )
- return p - c_str();
+ return p - begin();
}
return npos;
return find_last_not_of(wxStringBase(sz, n), nStart);
}
-size_t wxStringBase::find_last_not_of(wxChar ch, size_t nStart) const
+size_t wxStringBase::find_last_not_of(wxUniChar ch, size_t nStart) const
{
if ( nStart == npos )
{
wxASSERT( nStart <= length() );
}
- for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
+ for ( const_iterator p = begin() + nStart; p != begin(); --p )
{
if ( *p != ch )
- return p - c_str();
+ return p - begin();
}
return npos;
}
wxStringBase& wxStringBase::replace(size_t nStart, size_t nLen,
- size_t nCount, wxChar ch)
+ size_t nCount, wxUniChar ch)
{
return replace(nStart, nLen, wxStringBase(nCount, ch).c_str());
}
}
// assigns a single character
-wxStringBase& wxStringBase::operator=(wxChar ch)
+wxStringBase& wxStringBase::operator=(wxUniChar ch)
{
- if ( !AssignCopy(1, &ch) ) {
+ wxChar c(ch);
+ if ( !AssignCopy(1, &c) ) {
wxFAIL_MSG( _T("out of memory in wxStringBase::operator=(wxChar)") );
}
return *this;
return true;
}
-#endif // !wxUSE_STL
+#endif // !wxUSE_STL_BASED_WXSTRING
-#if !wxUSE_STL || !defined(HAVE_STD_STRING_COMPARE)
+#if !wxUSE_STL_BASED_WXSTRING || !defined(HAVE_STD_STRING_COMPARE)
-#if !wxUSE_STL
+#if !wxUSE_STL_BASED_WXSTRING
#define STRINGCLASS wxStringBase
#else
#define STRINGCLASS wxString
#undef STRINGCLASS
-#endif // !wxUSE_STL || !defined(HAVE_STD_STRING_COMPARE)
+#endif // !wxUSE_STL_BASED_WXSTRING || !defined(HAVE_STD_STRING_COMPARE)
// ===========================================================================
// wxString class core
return tmp.length() == length();
}
-#if !wxUSE_STL
+#if !wxUSE_STL_BASED_WXSTRING
// get the pointer to writable buffer of (at least) nLen bytes
wxChar *wxString::DoGetWriteBuf(size_t nLen)
{
}
#endif // WXWIN_COMPATIBILITY_2_8
-#endif // !wxUSE_STL
+#endif // !wxUSE_STL_BASED_WXSTRING
// ---------------------------------------------------------------------------
wxString operator+(const wxString& str1, const wxString& str2)
{
-#if !wxUSE_STL
+#if !wxUSE_STL_BASED_WXSTRING
wxASSERT( str1.GetStringData()->IsValid() );
wxASSERT( str2.GetStringData()->IsValid() );
#endif
return s;
}
-wxString operator+(const wxString& str, wxChar ch)
+wxString operator+(const wxString& str, wxUniChar ch)
{
-#if !wxUSE_STL
+#if !wxUSE_STL_BASED_WXSTRING
wxASSERT( str.GetStringData()->IsValid() );
#endif
return s;
}
-wxString operator+(wxChar ch, const wxString& str)
+wxString operator+(wxUniChar ch, const wxString& str)
{
-#if !wxUSE_STL
+#if !wxUSE_STL_BASED_WXSTRING
wxASSERT( str.GetStringData()->IsValid() );
#endif
wxString operator+(const wxString& str, const wxChar *psz)
{
-#if !wxUSE_STL
+#if !wxUSE_STL_BASED_WXSTRING
wxASSERT( str.GetStringData()->IsValid() );
#endif
wxString operator+(const wxChar *psz, const wxString& str)
{
-#if !wxUSE_STL
+#if !wxUSE_STL_BASED_WXSTRING
wxASSERT( str.GetStringData()->IsValid() );
#endif
wxASSERT_MSG( suffix, _T("invalid parameter in wxString::EndssWith") );
int start = length() - wxStrlen(suffix);
- if ( start < 0 || wxStrcmp(c_str() + start, suffix) != 0 )
+ if ( start < 0 || wxStrcmp(wx_str() + start, suffix) != 0 )
return false;
if ( rest )
// get all characters after the last occurence of ch
// (returns the whole string if ch not found)
-wxString wxString::AfterLast(wxChar ch) const
+wxString wxString::AfterLast(wxUniChar ch) const
{
wxString str;
int iPos = Find(ch, true);
if ( iPos == wxNOT_FOUND )
str = *this;
else
- str = c_str() + iPos + 1;
+ str = wx_str() + iPos + 1;
return str;
}
// get all characters before the first occurence of ch
// (returns the whole string if ch not found)
-wxString wxString::BeforeFirst(wxChar ch) const
+wxString wxString::BeforeFirst(wxUniChar ch) const
{
int iPos = Find(ch);
if ( iPos == wxNOT_FOUND ) iPos = length();
/// get all characters before the last occurence of ch
/// (returns empty string if ch not found)
-wxString wxString::BeforeLast(wxChar ch) const
+wxString wxString::BeforeLast(wxUniChar ch) const
{
wxString str;
int iPos = Find(ch, true);
/// get all characters after the first occurence of ch
/// (returns empty string if ch not found)
-wxString wxString::AfterFirst(wxChar ch) const
+wxString wxString::AfterFirst(wxUniChar ch) const
{
wxString str;
int iPos = Find(ch);
if ( iPos != wxNOT_FOUND )
- str = c_str() + iPos + 1;
+ str = wx_str() + iPos + 1;
return str;
}
}
// adds nCount characters chPad to the string from either side
-wxString& wxString::Pad(size_t nCount, wxChar chPad, bool bFromRight)
+wxString& wxString::Pad(size_t nCount, wxUniChar chPad, bool bFromRight)
{
wxString s(chPad, nCount);
// ---------------------------------------------------------------------------
// find a character
-int wxString::Find(wxChar ch, bool bFromEnd) const
+int wxString::Find(wxUniChar ch, bool bFromEnd) const
{
size_type idx = bFromEnd ? find_last_of(ch) : find_first_of(ch);
bool wxString::ToLong(long *val, int base) const
{
- return wxStringToIntType(c_str(), val, base, wxStrtol);
+ return wxStringToIntType((const wxChar*)c_str(), val, base, wxStrtol);
}
bool wxString::ToULong(unsigned long *val, int base) const
{
- return wxStringToIntType(c_str(), val, base, wxStrtoul);
+ return wxStringToIntType((const wxChar*)c_str(), val, base, wxStrtoul);
}
bool wxString::ToLongLong(wxLongLong_t *val, int base) const
{
#ifdef wxHAS_STRTOLL
- return wxStringToIntType(c_str(), val, base, wxStrtoll);
+ return wxStringToIntType((const wxChar*)c_str(), val, base, wxStrtoll);
#else
// TODO: implement this ourselves
wxUnusedVar(val);
bool wxString::ToULongLong(wxULongLong_t *val, int base) const
{
#ifdef wxHAS_STRTOLL
- return wxStringToIntType(c_str(), val, base, wxStrtoull);
+ return wxStringToIntType((const wxChar*)c_str(), val, base, wxStrtoull);
#else
// TODO: implement this ourselves
wxUnusedVar(val);
// ---------------------------------------------------------------------------
/* static */
-wxString wxString::Format(const wxChar *pszFormat, ...)
+#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
+wxString wxStringPrintfMixinBase::DoFormat(const wxChar *format, ...)
+#else
+wxString wxString::DoFormat(const wxChar *format, ...)
+#endif
{
va_list argptr;
- va_start(argptr, pszFormat);
+ va_start(argptr, format);
wxString s;
- s.PrintfV(pszFormat, argptr);
+ s.PrintfV(format, argptr);
va_end(argptr);
}
/* static */
-wxString wxString::FormatV(const wxChar *pszFormat, va_list argptr)
+wxString wxString::FormatV(const wxString& format, va_list argptr)
{
wxString s;
- s.PrintfV(pszFormat, argptr);
+ s.PrintfV(format, argptr);
return s;
}
-int wxString::Printf(const wxChar *pszFormat, ...)
+#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
+int wxStringPrintfMixinBase::DoPrintf(const wxChar *format, ...)
+#else
+int wxString::DoPrintf(const wxChar *format, ...)
+#endif
{
va_list argptr;
- va_start(argptr, pszFormat);
+ va_start(argptr, format);
+
+#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
+ // get a pointer to the wxString instance; we have to use dynamic_cast<>
+ // because it's the only cast that works safely for downcasting when
+ // multiple inheritance is used:
+ wxString *str = static_cast<wxString*>(this);
+#else
+ wxString *str = this;
+#endif
- int iLen = PrintfV(pszFormat, argptr);
+ int iLen = str->PrintfV(format, argptr);
va_end(argptr);
return iLen;
}
-int wxString::PrintfV(const wxChar* pszFormat, va_list argptr)
+int wxString::PrintfV(const wxString& format, va_list argptr)
{
int size = 1024;
// only a copy
va_list argptrcopy;
wxVaCopy(argptrcopy, argptr);
- int len = wxVsnprintf(buf, size, pszFormat, argptrcopy);
+ int len = wxVsnprintf(buf, size, format, argptrcopy);
va_end(argptrcopy);
// some implementations of vsnprintf() don't NUL terminate
}
// Count the number of chars
-int wxString::Freq(wxChar ch) const
+int wxString::Freq(wxUniChar ch) const
{
int count = 0;
int len = length();
// convert to lower case, return the copy of the string
wxString wxString::Lower() const { wxString s(*this); return s.MakeLower(); }
-int wxString::sprintf(const wxChar *pszFormat, ...)
- {
- va_list argptr;
- va_start(argptr, pszFormat);
- int iLen = PrintfV(pszFormat, argptr);
- va_end(argptr);
- return iLen;
- }
-
// ============================================================================
// ArrayString
// ============================================================================
{
return -s1->Cmp(*s2);
}
+
+
+
+// ===========================================================================
+// wxJoin and wxSplit
+// ===========================================================================
+
+#include "wx/tokenzr.h"
+
+wxString wxJoin(const wxArrayString& arr, const wxChar sep, const wxChar escape)
+{
+ size_t count = arr.size();
+ if ( count == 0 )
+ return wxEmptyString;
+
+ wxString str;
+
+ // pre-allocate memory using the estimation of the average length of the
+ // strings in the given array: this is very imprecise, of course, but
+ // better than nothing
+ str.reserve(count*(arr[0].length() + arr[count-1].length()) / 2);
+
+ if ( escape == wxT('\0') )
+ {
+ // escaping is disabled:
+ for ( size_t i = 0; i < count; i++ )
+ {
+ if ( i )
+ str += sep;
+ str += arr[i];
+ }
+ }
+ else // use escape character
+ {
+ for ( size_t n = 0; n < count; n++ )
+ {
+ if ( n )
+ str += sep;
+
+ for ( wxString::const_iterator i = arr[n].begin(),
+ end = arr[n].end();
+ i != end;
+ ++i )
+ {
+ const wxChar ch = *i;
+ if ( ch == sep )
+ str += escape; // escape this separator
+ str += ch;
+ }
+ }
+ }
+
+ str.Shrink(); // release extra memory if we allocated too much
+ return str;
+}
+
+wxArrayString wxSplit(const wxString& str, const wxChar sep, const wxChar escape)
+{
+ if ( escape == wxT('\0') )
+ {
+ // simple case: we don't need to honour the escape character
+ return wxStringTokenize(str, sep, wxTOKEN_RET_EMPTY_ALL);
+ }
+
+ wxArrayString ret;
+ wxString curr;
+ wxChar prev = wxT('\0');
+
+ for ( wxString::const_iterator i = str.begin(),
+ end = str.end();
+ i != end;
+ ++i )
+ {
+ const wxChar ch = *i;
+
+ if ( ch == sep )
+ {
+ if ( prev == escape )
+ {
+ // remove the escape character and don't consider this
+ // occurrence of 'sep' as a real separator
+ *curr.rbegin() = sep;
+ }
+ else // real separator
+ {
+ ret.push_back(curr);
+ curr.clear();
+ }
+ }
+ else // normal character
+ {
+ curr += ch;
+ }
+
+ prev = ch;
+ }
+
+ // add the last token
+ if ( !curr.empty() || prev == sep )
+ ret.Add(curr);
+
+ return ret;
+}