1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/string.cpp
3 // Purpose: wxString class
4 // Author: Vadim Zeitlin, Ryan Norton
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // (c) 2004 Ryan Norton <wxprojects@comcast.net>
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
13 // ===========================================================================
14 // headers, declarations, constants
15 // ===========================================================================
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
25 #include "wx/string.h"
26 #include "wx/wxcrtvararg.h"
40 #include "wx/hashmap.h"
41 #include "wx/vector.h"
42 #include "wx/xlocale.h"
45 #include "wx/msw/wrapwin.h"
48 // string handling functions used by wxString:
49 #if wxUSE_UNICODE_UTF8
50 #define wxStringMemcpy memcpy
51 #define wxStringMemcmp memcmp
52 #define wxStringMemchr memchr
53 #define wxStringStrlen strlen
55 #define wxStringMemcpy wxTmemcpy
56 #define wxStringMemcmp wxTmemcmp
57 #define wxStringMemchr wxTmemchr
58 #define wxStringStrlen wxStrlen
61 // define a function declared in wx/buffer.h here as we don't have buffer.cpp
62 // and don't want to add it just because of this simple function
66 // wxXXXBuffer classes can be (implicitly) used during global statics
67 // initialization so wrap the status UntypedBufferData variable in a function
68 // to make it safe to access it even before all global statics are initialized
69 UntypedBufferData
*GetUntypedNullData()
71 static UntypedBufferData
s_untypedNullData(NULL
, 0);
73 return &s_untypedNullData
;
76 } // namespace wxPrivate
78 // ---------------------------------------------------------------------------
79 // static class variables definition
80 // ---------------------------------------------------------------------------
82 //According to STL _must_ be a -1 size_t
83 const size_t wxString::npos
= (size_t) -1;
85 #if wxUSE_STRING_POS_CACHE
87 #ifdef wxHAS_COMPILER_TLS
89 wxTLS_TYPE(wxString::Cache
) wxString::ms_cache
;
91 #else // !wxHAS_COMPILER_TLS
93 struct wxStrCacheInitializer
95 wxStrCacheInitializer()
97 // calling this function triggers s_cache initialization in it, and
98 // from now on it becomes safe to call from multiple threads
104 wxString::Cache& wxString::GetCache()
106 static wxTLS_TYPE(Cache) s_cache;
108 return wxTLS_VALUE(s_cache);
112 static wxStrCacheInitializer gs_stringCacheInit
;
114 #endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS
116 // gdb seems to be unable to display thread-local variables correctly, at least
117 // not my 6.4.98 version under amd64, so provide this debugging helper to do it
118 #if wxDEBUG_LEVEL >= 2
120 struct wxStrCacheDumper
122 static void ShowAll()
124 puts("*** wxString cache dump:");
125 for ( unsigned n
= 0; n
< wxString::Cache::SIZE
; n
++ )
127 const wxString::Cache::Element
&
128 c
= wxString::GetCacheBegin()[n
];
130 printf("\t%u%s\t%p: pos=(%lu, %lu), len=%ld\n",
132 n
== wxString::LastUsedCacheElement() ? " [*]" : "",
134 (unsigned long)c
.pos
,
135 (unsigned long)c
.impl
,
141 void wxDumpStrCache() { wxStrCacheDumper::ShowAll(); }
143 #endif // wxDEBUG_LEVEL >= 2
145 #ifdef wxPROFILE_STRING_CACHE
147 wxString::CacheStats
wxString::ms_cacheStats
;
149 struct wxStrCacheStatsDumper
151 ~wxStrCacheStatsDumper()
153 const wxString::CacheStats
& stats
= wxString::ms_cacheStats
;
157 puts("*** wxString cache statistics:");
158 printf("\tTotal non-trivial calls to PosToImpl(): %u\n",
160 printf("\tHits %u (of which %u not used) or %.2f%%\n",
163 100.*float(stats
.poshits
- stats
.mishits
)/stats
.postot
);
164 printf("\tAverage position requested: %.2f\n",
165 float(stats
.sumpos
) / stats
.postot
);
166 printf("\tAverage offset after cached hint: %.2f\n",
167 float(stats
.sumofs
) / stats
.postot
);
172 printf("\tNumber of calls to length(): %u, hits=%.2f%%\n",
173 stats
.lentot
, 100.*float(stats
.lenhits
)/stats
.lentot
);
178 static wxStrCacheStatsDumper s_showCacheStats
;
180 #endif // wxPROFILE_STRING_CACHE
182 #endif // wxUSE_STRING_POS_CACHE
184 // ----------------------------------------------------------------------------
186 // ----------------------------------------------------------------------------
188 #if wxUSE_STD_IOSTREAM
192 wxSTD ostream
& operator<<(wxSTD ostream
& os
, const wxCStrData
& str
)
194 #if wxUSE_UNICODE && !wxUSE_UNICODE_UTF8
195 const wxScopedCharBuffer
buf(str
.AsCharBuf());
197 os
.clear(wxSTD
ios_base::failbit
);
203 return os
<< str
.AsInternal();
207 wxSTD ostream
& operator<<(wxSTD ostream
& os
, const wxString
& str
)
209 return os
<< str
.c_str();
212 wxSTD ostream
& operator<<(wxSTD ostream
& os
, const wxScopedCharBuffer
& str
)
214 return os
<< str
.data();
218 wxSTD ostream
& operator<<(wxSTD ostream
& os
, const wxScopedWCharBuffer
& str
)
220 return os
<< str
.data();
224 #if wxUSE_UNICODE && defined(HAVE_WOSTREAM)
226 wxSTD wostream
& operator<<(wxSTD wostream
& wos
, const wxString
& str
)
228 return wos
<< str
.wc_str();
231 wxSTD wostream
& operator<<(wxSTD wostream
& wos
, const wxCStrData
& str
)
233 return wos
<< str
.AsWChar();
236 wxSTD wostream
& operator<<(wxSTD wostream
& wos
, const wxScopedWCharBuffer
& str
)
238 return wos
<< str
.data();
241 #endif // wxUSE_UNICODE && defined(HAVE_WOSTREAM)
243 #endif // wxUSE_STD_IOSTREAM
245 // ===========================================================================
246 // wxString class core
247 // ===========================================================================
249 #if wxUSE_UNICODE_UTF8
251 void wxString::PosLenToImpl(size_t pos
, size_t len
,
252 size_t *implPos
, size_t *implLen
) const
258 else // have valid start position
260 const const_iterator b
= GetIterForNthChar(pos
);
261 *implPos
= wxStringImpl::const_iterator(b
.impl()) - m_impl
.begin();
266 else // have valid length too
268 // we need to handle the case of length specifying a substring
269 // going beyond the end of the string, just as std::string does
270 const const_iterator
e(end());
272 while ( len
&& i
<= e
)
278 *implLen
= i
.impl() - b
.impl();
283 #endif // wxUSE_UNICODE_UTF8
285 // ----------------------------------------------------------------------------
286 // wxCStrData converted strings caching
287 // ----------------------------------------------------------------------------
289 // FIXME-UTF8: temporarily disabled because it doesn't work with global
290 // string objects; re-enable after fixing this bug and benchmarking
291 // performance to see if using a hash is a good idea at all
294 // For backward compatibility reasons, it must be possible to assign the value
295 // returned by wxString::c_str() to a char* or wchar_t* variable and work with
296 // it. Returning wxCharBuffer from (const char*)c_str() wouldn't do the trick,
297 // because the memory would be freed immediately, but it has to be valid as long
298 // as the string is not modified, so that code like this still works:
300 // const wxChar *s = str.c_str();
301 // while ( s ) { ... }
303 // FIXME-UTF8: not thread safe!
304 // FIXME-UTF8: we currently clear the cached conversion only when the string is
305 // destroyed, but we should do it when the string is modified, to
306 // keep memory usage down
307 // FIXME-UTF8: we do the conversion every time As[W]Char() is called, but if we
308 // invalidated the cache on every change, we could keep the previous
310 // FIXME-UTF8: add tracing of usage of these two methods - new code is supposed
311 // to use mb_str() or wc_str() instead of (const [w]char*)c_str()
314 static inline void DeleteStringFromConversionCache(T
& hash
, const wxString
*s
)
316 typename
T::iterator i
= hash
.find(wxConstCast(s
, wxString
));
317 if ( i
!= hash
.end() )
325 // NB: non-STL implementation doesn't compile with "const wxString*" key type,
326 // so we have to use wxString* here and const-cast when used
327 WX_DECLARE_HASH_MAP(wxString
*, char*, wxPointerHash
, wxPointerEqual
,
328 wxStringCharConversionCache
);
329 static wxStringCharConversionCache gs_stringsCharCache
;
331 const char* wxCStrData::AsChar() const
333 // remove previously cache value, if any (see FIXMEs above):
334 DeleteStringFromConversionCache(gs_stringsCharCache
, m_str
);
336 // convert the string and keep it:
337 const char *s
= gs_stringsCharCache
[wxConstCast(m_str
, wxString
)] =
338 m_str
->mb_str().release();
342 #endif // wxUSE_UNICODE
344 #if !wxUSE_UNICODE_WCHAR
345 WX_DECLARE_HASH_MAP(wxString
*, wchar_t*, wxPointerHash
, wxPointerEqual
,
346 wxStringWCharConversionCache
);
347 static wxStringWCharConversionCache gs_stringsWCharCache
;
349 const wchar_t* wxCStrData::AsWChar() const
351 // remove previously cache value, if any (see FIXMEs above):
352 DeleteStringFromConversionCache(gs_stringsWCharCache
, m_str
);
354 // convert the string and keep it:
355 const wchar_t *s
= gs_stringsWCharCache
[wxConstCast(m_str
, wxString
)] =
356 m_str
->wc_str().release();
360 #endif // !wxUSE_UNICODE_WCHAR
362 wxString::~wxString()
365 // FIXME-UTF8: do this only if locale is not UTF8 if wxUSE_UNICODE_UTF8
366 DeleteStringFromConversionCache(gs_stringsCharCache
, this);
368 #if !wxUSE_UNICODE_WCHAR
369 DeleteStringFromConversionCache(gs_stringsWCharCache
, this);
374 // ===========================================================================
375 // wxString class core
376 // ===========================================================================
378 // ---------------------------------------------------------------------------
379 // construction and conversion
380 // ---------------------------------------------------------------------------
382 #if wxUSE_UNICODE_WCHAR
384 wxString::SubstrBufFromMB
wxString::ConvertStr(const char *psz
, size_t nLength
,
385 const wxMBConv
& conv
)
388 if ( !psz
|| nLength
== 0 )
389 return SubstrBufFromMB(wxWCharBuffer(L
""), 0);
391 if ( nLength
== npos
)
395 wxScopedWCharBuffer
wcBuf(conv
.cMB2WC(psz
, nLength
, &wcLen
));
397 return SubstrBufFromMB(wxWCharBuffer(L
""), 0);
399 return SubstrBufFromMB(wcBuf
, wcLen
);
401 #endif // wxUSE_UNICODE_WCHAR
403 #if wxUSE_UNICODE_UTF8
405 wxString::SubstrBufFromMB
wxString::ConvertStr(const char *psz
, size_t nLength
,
406 const wxMBConv
& conv
)
409 if ( !psz
|| nLength
== 0 )
410 return SubstrBufFromMB(wxCharBuffer(""), 0);
412 // if psz is already in UTF-8, we don't have to do the roundtrip to
413 // wchar_t* and back:
416 // we need to validate the input because UTF8 iterators assume valid
417 // UTF-8 sequence and psz may be invalid:
418 if ( wxStringOperations::IsValidUtf8String(psz
, nLength
) )
420 // we must pass the real string length to SubstrBufFromMB ctor
421 if ( nLength
== npos
)
422 nLength
= psz
? strlen(psz
) : 0;
423 return SubstrBufFromMB(wxScopedCharBuffer::CreateNonOwned(psz
, nLength
),
426 // else: do the roundtrip through wchar_t*
429 if ( nLength
== npos
)
432 // first convert to wide string:
434 wxScopedWCharBuffer
wcBuf(conv
.cMB2WC(psz
, nLength
, &wcLen
));
436 return SubstrBufFromMB(wxCharBuffer(""), 0);
438 // and then to UTF-8:
439 SubstrBufFromMB
buf(ConvertStr(wcBuf
, wcLen
, wxMBConvStrictUTF8()));
440 // widechar -> UTF-8 conversion isn't supposed to ever fail:
441 wxASSERT_MSG( buf
.data
, wxT("conversion to UTF-8 failed") );
445 #endif // wxUSE_UNICODE_UTF8
447 #if wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE
449 wxString::SubstrBufFromWC
wxString::ConvertStr(const wchar_t *pwz
, size_t nLength
,
450 const wxMBConv
& conv
)
453 if ( !pwz
|| nLength
== 0 )
454 return SubstrBufFromWC(wxCharBuffer(""), 0);
456 if ( nLength
== npos
)
460 wxScopedCharBuffer
mbBuf(conv
.cWC2MB(pwz
, nLength
, &mbLen
));
462 return SubstrBufFromWC(wxCharBuffer(""), 0);
464 return SubstrBufFromWC(mbBuf
, mbLen
);
466 #endif // wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE
468 // This std::string::c_str()-like method returns a wide char pointer to string
469 // contents. In wxUSE_UNICODE_WCHAR case it is trivial as it can simply return
470 // a pointer to the internal representation. Otherwise a conversion is required
471 // and it returns a temporary buffer.
473 // However for compatibility with c_str() and to avoid breaking existing code
476 // for ( const wchar_t *p = s.wc_str(); *p; p++ )
479 // we actually need to ensure that the returned buffer is _not_ temporary and
480 // so we use wxString::m_convertedToWChar to store the returned data
481 #if !wxUSE_UNICODE_WCHAR
483 const wchar_t *wxString::AsWChar(const wxMBConv
& conv
) const
485 const char * const strMB
= m_impl
.c_str();
486 const size_t lenMB
= m_impl
.length();
488 // find out the size of the buffer needed
489 const size_t lenWC
= conv
.ToWChar(NULL
, 0, strMB
, lenMB
);
490 if ( lenWC
== wxCONV_FAILED
)
493 // keep the same buffer if the string size didn't change: this is not only
494 // an optimization but also ensure that code which modifies string
495 // character by character (without changing its length) can continue to use
496 // the pointer returned by a previous wc_str() call even after changing the
499 // TODO-UTF8: we could check for ">" instead of "!=" here as this would
500 // allow to save on buffer reallocations but at the cost of
501 // consuming (even) more memory, we should benchmark this to
502 // determine if it's worth doing
503 if ( !m_convertedToWChar
.m_str
|| lenWC
!= m_convertedToWChar
.m_len
)
505 if ( !const_cast<wxString
*>(this)->m_convertedToWChar
.Extend(lenWC
) )
509 // finally do convert
510 m_convertedToWChar
.m_str
[lenWC
] = L
'\0';
511 if ( conv
.ToWChar(m_convertedToWChar
.m_str
, lenWC
,
512 strMB
, lenMB
) == wxCONV_FAILED
)
515 return m_convertedToWChar
.m_str
;
518 #endif // !wxUSE_UNICODE_WCHAR
521 // Same thing for mb_str() which returns a normal char pointer to string
522 // contents: this always requires converting it to the specified encoding in
523 // non-ANSI build except if we need to convert to UTF-8 and this is what we
524 // already use internally.
527 const char *wxString::AsChar(const wxMBConv
& conv
) const
529 #if wxUSE_UNICODE_UTF8
531 return m_impl
.c_str();
533 const wchar_t * const strWC
= AsWChar(wxMBConvStrictUTF8());
534 const size_t lenWC
= m_convertedToWChar
.m_len
;
535 #else // wxUSE_UNICODE_WCHAR
536 const wchar_t * const strWC
= m_impl
.c_str();
537 const size_t lenWC
= m_impl
.length();
538 #endif // wxUSE_UNICODE_UTF8/wxUSE_UNICODE_WCHAR
540 const size_t lenMB
= conv
.FromWChar(NULL
, 0, strWC
, lenWC
);
541 if ( lenMB
== wxCONV_FAILED
)
544 if ( !m_convertedToChar
.m_str
|| lenMB
!= m_convertedToChar
.m_len
)
546 if ( !const_cast<wxString
*>(this)->m_convertedToChar
.Extend(lenMB
) )
550 m_convertedToChar
.m_str
[lenMB
] = '\0';
551 if ( conv
.FromWChar(m_convertedToChar
.m_str
, lenMB
,
552 strWC
, lenWC
) == wxCONV_FAILED
)
555 return m_convertedToChar
.m_str
;
558 #endif // wxUSE_UNICODE
560 // shrink to minimal size (releasing extra memory)
561 bool wxString::Shrink()
563 wxString
tmp(begin(), end());
565 return tmp
.length() == length();
568 // deprecated compatibility code:
569 #if WXWIN_COMPATIBILITY_2_8 && !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
570 wxStringCharType
*wxString::GetWriteBuf(size_t nLen
)
572 return DoGetWriteBuf(nLen
);
575 void wxString::UngetWriteBuf()
580 void wxString::UngetWriteBuf(size_t nLen
)
582 DoUngetWriteBuf(nLen
);
584 #endif // WXWIN_COMPATIBILITY_2_8 && !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
587 // ---------------------------------------------------------------------------
589 // ---------------------------------------------------------------------------
591 // all functions are inline in string.h
593 // ---------------------------------------------------------------------------
594 // concatenation operators
595 // ---------------------------------------------------------------------------
598 * concatenation functions come in 5 flavours:
600 * char + string and string + char
601 * C str + string and string + C str
604 wxString
operator+(const wxString
& str1
, const wxString
& str2
)
606 #if !wxUSE_STL_BASED_WXSTRING
607 wxASSERT( str1
.IsValid() );
608 wxASSERT( str2
.IsValid() );
617 wxString
operator+(const wxString
& str
, wxUniChar ch
)
619 #if !wxUSE_STL_BASED_WXSTRING
620 wxASSERT( str
.IsValid() );
629 wxString
operator+(wxUniChar ch
, const wxString
& str
)
631 #if !wxUSE_STL_BASED_WXSTRING
632 wxASSERT( str
.IsValid() );
641 wxString
operator+(const wxString
& str
, const char *psz
)
643 #if !wxUSE_STL_BASED_WXSTRING
644 wxASSERT( str
.IsValid() );
648 if ( !s
.Alloc(strlen(psz
) + str
.length()) ) {
649 wxFAIL_MSG( wxT("out of memory in wxString::operator+") );
657 wxString
operator+(const wxString
& str
, const wchar_t *pwz
)
659 #if !wxUSE_STL_BASED_WXSTRING
660 wxASSERT( str
.IsValid() );
664 if ( !s
.Alloc(wxWcslen(pwz
) + str
.length()) ) {
665 wxFAIL_MSG( wxT("out of memory in wxString::operator+") );
673 wxString
operator+(const char *psz
, const wxString
& str
)
675 #if !wxUSE_STL_BASED_WXSTRING
676 wxASSERT( str
.IsValid() );
680 if ( !s
.Alloc(strlen(psz
) + str
.length()) ) {
681 wxFAIL_MSG( wxT("out of memory in wxString::operator+") );
689 wxString
operator+(const wchar_t *pwz
, const wxString
& str
)
691 #if !wxUSE_STL_BASED_WXSTRING
692 wxASSERT( str
.IsValid() );
696 if ( !s
.Alloc(wxWcslen(pwz
) + str
.length()) ) {
697 wxFAIL_MSG( wxT("out of memory in wxString::operator+") );
705 // ---------------------------------------------------------------------------
707 // ---------------------------------------------------------------------------
709 bool wxString::IsSameAs(wxUniChar c
, bool compareWithCase
) const
711 return (length() == 1) && (compareWithCase
? GetChar(0u) == c
712 : wxToupper(GetChar(0u)) == wxToupper(c
));
715 #ifdef HAVE_STD_STRING_COMPARE
717 // NB: Comparison code (both if HAVE_STD_STRING_COMPARE and if not) works with
718 // UTF-8 encoded strings too, thanks to UTF-8's design which allows us to
719 // sort strings in characters code point order by sorting the byte sequence
720 // in byte values order (i.e. what strcmp() and memcmp() do).
722 int wxString::compare(const wxString
& str
) const
724 return m_impl
.compare(str
.m_impl
);
727 int wxString::compare(size_t nStart
, size_t nLen
,
728 const wxString
& str
) const
731 PosLenToImpl(nStart
, nLen
, &pos
, &len
);
732 return m_impl
.compare(pos
, len
, str
.m_impl
);
735 int wxString::compare(size_t nStart
, size_t nLen
,
737 size_t nStart2
, size_t nLen2
) const
740 PosLenToImpl(nStart
, nLen
, &pos
, &len
);
743 str
.PosLenToImpl(nStart2
, nLen2
, &pos2
, &len2
);
745 return m_impl
.compare(pos
, len
, str
.m_impl
, pos2
, len2
);
748 int wxString::compare(const char* sz
) const
750 return m_impl
.compare(ImplStr(sz
));
753 int wxString::compare(const wchar_t* sz
) const
755 return m_impl
.compare(ImplStr(sz
));
758 int wxString::compare(size_t nStart
, size_t nLen
,
759 const char* sz
, size_t nCount
) const
762 PosLenToImpl(nStart
, nLen
, &pos
, &len
);
764 SubstrBufFromMB
str(ImplStr(sz
, nCount
));
766 return m_impl
.compare(pos
, len
, str
.data
, str
.len
);
769 int wxString::compare(size_t nStart
, size_t nLen
,
770 const wchar_t* sz
, size_t nCount
) const
773 PosLenToImpl(nStart
, nLen
, &pos
, &len
);
775 SubstrBufFromWC
str(ImplStr(sz
, nCount
));
777 return m_impl
.compare(pos
, len
, str
.data
, str
.len
);
780 #else // !HAVE_STD_STRING_COMPARE
782 static inline int wxDoCmp(const wxStringCharType
* s1
, size_t l1
,
783 const wxStringCharType
* s2
, size_t l2
)
786 return wxStringMemcmp(s1
, s2
, l1
);
789 int ret
= wxStringMemcmp(s1
, s2
, l1
);
790 return ret
== 0 ? -1 : ret
;
794 int ret
= wxStringMemcmp(s1
, s2
, l2
);
795 return ret
== 0 ? +1 : ret
;
799 int wxString::compare(const wxString
& str
) const
801 return ::wxDoCmp(m_impl
.data(), m_impl
.length(),
802 str
.m_impl
.data(), str
.m_impl
.length());
805 int wxString::compare(size_t nStart
, size_t nLen
,
806 const wxString
& str
) const
808 wxASSERT(nStart
<= length());
809 size_type strLen
= length() - nStart
;
810 nLen
= strLen
< nLen
? strLen
: nLen
;
813 PosLenToImpl(nStart
, nLen
, &pos
, &len
);
815 return ::wxDoCmp(m_impl
.data() + pos
, len
,
816 str
.m_impl
.data(), str
.m_impl
.length());
819 int wxString::compare(size_t nStart
, size_t nLen
,
821 size_t nStart2
, size_t nLen2
) const
823 wxASSERT(nStart
<= length());
824 wxASSERT(nStart2
<= str
.length());
825 size_type strLen
= length() - nStart
,
826 strLen2
= str
.length() - nStart2
;
827 nLen
= strLen
< nLen
? strLen
: nLen
;
828 nLen2
= strLen2
< nLen2
? strLen2
: nLen2
;
831 PosLenToImpl(nStart
, nLen
, &pos
, &len
);
833 str
.PosLenToImpl(nStart2
, nLen2
, &pos2
, &len2
);
835 return ::wxDoCmp(m_impl
.data() + pos
, len
,
836 str
.m_impl
.data() + pos2
, len2
);
839 int wxString::compare(const char* sz
) const
841 SubstrBufFromMB
str(ImplStr(sz
, npos
));
842 if ( str
.len
== npos
)
843 str
.len
= wxStringStrlen(str
.data
);
844 return ::wxDoCmp(m_impl
.data(), m_impl
.length(), str
.data
, str
.len
);
847 int wxString::compare(const wchar_t* sz
) const
849 SubstrBufFromWC
str(ImplStr(sz
, npos
));
850 if ( str
.len
== npos
)
851 str
.len
= wxStringStrlen(str
.data
);
852 return ::wxDoCmp(m_impl
.data(), m_impl
.length(), str
.data
, str
.len
);
855 int wxString::compare(size_t nStart
, size_t nLen
,
856 const char* sz
, size_t nCount
) const
858 wxASSERT(nStart
<= length());
859 size_type strLen
= length() - nStart
;
860 nLen
= strLen
< nLen
? strLen
: nLen
;
863 PosLenToImpl(nStart
, nLen
, &pos
, &len
);
865 SubstrBufFromMB
str(ImplStr(sz
, nCount
));
866 if ( str
.len
== npos
)
867 str
.len
= wxStringStrlen(str
.data
);
869 return ::wxDoCmp(m_impl
.data() + pos
, len
, str
.data
, str
.len
);
872 int wxString::compare(size_t nStart
, size_t nLen
,
873 const wchar_t* sz
, size_t nCount
) const
875 wxASSERT(nStart
<= length());
876 size_type strLen
= length() - nStart
;
877 nLen
= strLen
< nLen
? strLen
: nLen
;
880 PosLenToImpl(nStart
, nLen
, &pos
, &len
);
882 SubstrBufFromWC
str(ImplStr(sz
, nCount
));
883 if ( str
.len
== npos
)
884 str
.len
= wxStringStrlen(str
.data
);
886 return ::wxDoCmp(m_impl
.data() + pos
, len
, str
.data
, str
.len
);
889 #endif // HAVE_STD_STRING_COMPARE/!HAVE_STD_STRING_COMPARE
892 // ---------------------------------------------------------------------------
893 // find_{first,last}_[not]_of functions
894 // ---------------------------------------------------------------------------
896 #if !wxUSE_STL_BASED_WXSTRING || wxUSE_UNICODE_UTF8
898 // NB: All these functions are implemented with the argument being wxChar*,
899 // i.e. widechar string in any Unicode build, even though native string
900 // representation is char* in the UTF-8 build. This is because we couldn't
901 // use memchr() to determine if a character is in a set encoded as UTF-8.
903 size_t wxString::find_first_of(const wxChar
* sz
, size_t nStart
) const
905 return find_first_of(sz
, nStart
, wxStrlen(sz
));
908 size_t wxString::find_first_not_of(const wxChar
* sz
, size_t nStart
) const
910 return find_first_not_of(sz
, nStart
, wxStrlen(sz
));
913 size_t wxString::find_first_of(const wxChar
* sz
, size_t nStart
, size_t n
) const
915 wxASSERT_MSG( nStart
<= length(), wxT("invalid index") );
918 for ( const_iterator i
= begin() + nStart
; i
!= end(); ++idx
, ++i
)
920 if ( wxTmemchr(sz
, *i
, n
) )
927 size_t wxString::find_first_not_of(const wxChar
* sz
, size_t nStart
, size_t n
) const
929 wxASSERT_MSG( nStart
<= length(), wxT("invalid index") );
932 for ( const_iterator i
= begin() + nStart
; i
!= end(); ++idx
, ++i
)
934 if ( !wxTmemchr(sz
, *i
, n
) )
942 size_t wxString::find_last_of(const wxChar
* sz
, size_t nStart
) const
944 return find_last_of(sz
, nStart
, wxStrlen(sz
));
947 size_t wxString::find_last_not_of(const wxChar
* sz
, size_t nStart
) const
949 return find_last_not_of(sz
, nStart
, wxStrlen(sz
));
952 size_t wxString::find_last_of(const wxChar
* sz
, size_t nStart
, size_t n
) const
954 size_t len
= length();
956 if ( nStart
== npos
)
962 wxASSERT_MSG( nStart
<= len
, wxT("invalid index") );
966 for ( const_reverse_iterator i
= rbegin() + (len
- nStart
- 1);
967 i
!= rend(); --idx
, ++i
)
969 if ( wxTmemchr(sz
, *i
, n
) )
976 size_t wxString::find_last_not_of(const wxChar
* sz
, size_t nStart
, size_t n
) const
978 size_t len
= length();
980 if ( nStart
== npos
)
986 wxASSERT_MSG( nStart
<= len
, wxT("invalid index") );
990 for ( const_reverse_iterator i
= rbegin() + (len
- nStart
- 1);
991 i
!= rend(); --idx
, ++i
)
993 if ( !wxTmemchr(sz
, *i
, n
) )
1000 size_t wxString::find_first_not_of(wxUniChar ch
, size_t nStart
) const
1002 wxASSERT_MSG( nStart
<= length(), wxT("invalid index") );
1004 size_t idx
= nStart
;
1005 for ( const_iterator i
= begin() + nStart
; i
!= end(); ++idx
, ++i
)
1014 size_t wxString::find_last_not_of(wxUniChar ch
, size_t nStart
) const
1016 size_t len
= length();
1018 if ( nStart
== npos
)
1024 wxASSERT_MSG( nStart
<= len
, wxT("invalid index") );
1027 size_t idx
= nStart
;
1028 for ( const_reverse_iterator i
= rbegin() + (len
- nStart
- 1);
1029 i
!= rend(); --idx
, ++i
)
1038 // the functions above were implemented for wchar_t* arguments in Unicode
1039 // build and char* in ANSI build; below are implementations for the other
1042 #define wxOtherCharType char
1043 #define STRCONV (const wxChar*)wxConvLibc.cMB2WC
1045 #define wxOtherCharType wchar_t
1046 #define STRCONV (const wxChar*)wxConvLibc.cWC2MB
1049 size_t wxString::find_first_of(const wxOtherCharType
* sz
, size_t nStart
) const
1050 { return find_first_of(STRCONV(sz
), nStart
); }
1052 size_t wxString::find_first_of(const wxOtherCharType
* sz
, size_t nStart
,
1054 { return find_first_of(STRCONV(sz
, n
, NULL
), nStart
, n
); }
1055 size_t wxString::find_last_of(const wxOtherCharType
* sz
, size_t nStart
) const
1056 { return find_last_of(STRCONV(sz
), nStart
); }
1057 size_t wxString::find_last_of(const wxOtherCharType
* sz
, size_t nStart
,
1059 { return find_last_of(STRCONV(sz
, n
, NULL
), nStart
, n
); }
1060 size_t wxString::find_first_not_of(const wxOtherCharType
* sz
, size_t nStart
) const
1061 { return find_first_not_of(STRCONV(sz
), nStart
); }
1062 size_t wxString::find_first_not_of(const wxOtherCharType
* sz
, size_t nStart
,
1064 { return find_first_not_of(STRCONV(sz
, n
, NULL
), nStart
, n
); }
1065 size_t wxString::find_last_not_of(const wxOtherCharType
* sz
, size_t nStart
) const
1066 { return find_last_not_of(STRCONV(sz
), nStart
); }
1067 size_t wxString::find_last_not_of(const wxOtherCharType
* sz
, size_t nStart
,
1069 { return find_last_not_of(STRCONV(sz
, n
, NULL
), nStart
, n
); }
1071 #undef wxOtherCharType
1074 #endif // !wxUSE_STL_BASED_WXSTRING || wxUSE_UNICODE_UTF8
1076 // ===========================================================================
1077 // other common string functions
1078 // ===========================================================================
1080 int wxString::CmpNoCase(const wxString
& s
) const
1082 #if defined(__WXMSW__) && !wxUSE_UNICODE_UTF8
1083 // Prefer to use CompareString() if available as it's more efficient than
1084 // doing it manually or even using wxStricmp() (see #10375)
1086 // Also note that not using NORM_STRINGSORT may result in not having a
1087 // strict weak ordering (e.g. s1 < s2 and s2 < s3 but s3 < s1) and so break
1088 // algorithms such as std::sort that rely on it. It's also more consistent
1089 // with the fall back version below.
1090 switch ( ::CompareString(LOCALE_USER_DEFAULT
,
1091 NORM_IGNORECASE
| SORT_STRINGSORT
,
1092 m_impl
.c_str(), m_impl
.length(),
1093 s
.m_impl
.c_str(), s
.m_impl
.length()) )
1095 case CSTR_LESS_THAN
:
1101 case CSTR_GREATER_THAN
:
1105 wxFAIL_MSG( "unexpected CompareString() return value" );
1109 wxLogLastError("CompareString");
1110 // use generic code below
1112 #endif // __WXMSW__ && !wxUSE_UNICODE_UTF8
1114 // do the comparison manually: notice that we can't use wxStricmp() as it
1115 // doesn't handle embedded NULs
1117 // FIXME-UTF8: use wxUniChar::ToLower/ToUpper once added
1118 const_iterator i1
= begin();
1119 const_iterator end1
= end();
1120 const_iterator i2
= s
.begin();
1121 const_iterator end2
= s
.end();
1123 for ( ; i1
!= end1
&& i2
!= end2
; ++i1
, ++i2
)
1125 wxUniChar lower1
= (wxChar
)wxTolower(*i1
);
1126 wxUniChar lower2
= (wxChar
)wxTolower(*i2
);
1127 if ( lower1
!= lower2
)
1128 return lower1
< lower2
? -1 : 1;
1131 size_t len1
= length();
1132 size_t len2
= s
.length();
1136 else if ( len1
> len2
)
1145 #ifndef __SCHAR_MAX__
1146 #define __SCHAR_MAX__ 127
1150 wxString
wxString::FromAscii(const char *ascii
, size_t len
)
1152 if (!ascii
|| len
== 0)
1153 return wxEmptyString
;
1158 wxStringInternalBuffer
buf(res
, len
);
1159 wxStringCharType
*dest
= buf
;
1161 for ( ; len
> 0; --len
)
1163 unsigned char c
= (unsigned char)*ascii
++;
1164 wxASSERT_MSG( c
< 0x80,
1165 wxT("Non-ASCII value passed to FromAscii().") );
1167 *dest
++ = (wchar_t)c
;
1174 wxString
wxString::FromAscii(const char *ascii
)
1176 return FromAscii(ascii
, wxStrlen(ascii
));
1179 wxString
wxString::FromAscii(char ascii
)
1181 // What do we do with '\0' ?
1183 unsigned char c
= (unsigned char)ascii
;
1185 wxASSERT_MSG( c
< 0x80, wxT("Non-ASCII value passed to FromAscii().") );
1187 // NB: the cast to wchar_t causes interpretation of 'ascii' as Latin1 value
1188 return wxString(wxUniChar((wchar_t)c
));
1191 const wxScopedCharBuffer
wxString::ToAscii() const
1193 // this will allocate enough space for the terminating NUL too
1194 wxCharBuffer
buffer(length());
1195 char *dest
= buffer
.data();
1197 for ( const_iterator i
= begin(); i
!= end(); ++i
)
1200 // FIXME-UTF8: unify substituted char ('_') with wxUniChar ('?')
1201 *dest
++ = c
.IsAscii() ? (char)c
: '_';
1203 // the output string can't have embedded NULs anyhow, so we can safely
1204 // stop at first of them even if we do have any
1212 #endif // wxUSE_UNICODE
1214 // extract string of length nCount starting at nFirst
1215 wxString
wxString::Mid(size_t nFirst
, size_t nCount
) const
1217 size_t nLen
= length();
1219 // default value of nCount is npos and means "till the end"
1220 if ( nCount
== npos
)
1222 nCount
= nLen
- nFirst
;
1225 // out-of-bounds requests return sensible things
1226 if ( nFirst
+ nCount
> nLen
)
1228 nCount
= nLen
- nFirst
;
1231 if ( nFirst
> nLen
)
1233 // AllocCopy() will return empty string
1234 return wxEmptyString
;
1237 wxString
dest(*this, nFirst
, nCount
);
1238 if ( dest
.length() != nCount
)
1240 wxFAIL_MSG( wxT("out of memory in wxString::Mid") );
1246 // check that the string starts with prefix and return the rest of the string
1247 // in the provided pointer if it is not NULL, otherwise return false
1248 bool wxString::StartsWith(const wxString
& prefix
, wxString
*rest
) const
1250 if ( compare(0, prefix
.length(), prefix
) != 0 )
1255 // put the rest of the string into provided pointer
1256 rest
->assign(*this, prefix
.length(), npos
);
1263 // check that the string ends with suffix and return the rest of it in the
1264 // provided pointer if it is not NULL, otherwise return false
1265 bool wxString::EndsWith(const wxString
& suffix
, wxString
*rest
) const
1267 int start
= length() - suffix
.length();
1269 if ( start
< 0 || compare(start
, npos
, suffix
) != 0 )
1274 // put the rest of the string into provided pointer
1275 rest
->assign(*this, 0, start
);
1282 // extract nCount last (rightmost) characters
1283 wxString
wxString::Right(size_t nCount
) const
1285 if ( nCount
> length() )
1288 wxString
dest(*this, length() - nCount
, nCount
);
1289 if ( dest
.length() != nCount
) {
1290 wxFAIL_MSG( wxT("out of memory in wxString::Right") );
1295 // get all characters after the last occurrence of ch
1296 // (returns the whole string if ch not found)
1297 wxString
wxString::AfterLast(wxUniChar ch
) const
1300 int iPos
= Find(ch
, true);
1301 if ( iPos
== wxNOT_FOUND
)
1304 str
.assign(*this, iPos
+ 1, npos
);
1309 // extract nCount first (leftmost) characters
1310 wxString
wxString::Left(size_t nCount
) const
1312 if ( nCount
> length() )
1315 wxString
dest(*this, 0, nCount
);
1316 if ( dest
.length() != nCount
) {
1317 wxFAIL_MSG( wxT("out of memory in wxString::Left") );
1322 // get all characters before the first occurrence of ch
1323 // (returns the whole string if ch not found)
1324 wxString
wxString::BeforeFirst(wxUniChar ch
) const
1326 int iPos
= Find(ch
);
1327 if ( iPos
== wxNOT_FOUND
)
1329 return wxString(*this, 0, iPos
);
1332 /// get all characters before the last occurrence of ch
1333 /// (returns empty string if ch not found)
1334 wxString
wxString::BeforeLast(wxUniChar ch
) const
1337 int iPos
= Find(ch
, true);
1338 if ( iPos
!= wxNOT_FOUND
&& iPos
!= 0 )
1339 str
= wxString(c_str(), iPos
);
1344 /// get all characters after the first occurrence of ch
1345 /// (returns empty string if ch not found)
1346 wxString
wxString::AfterFirst(wxUniChar ch
) const
1349 int iPos
= Find(ch
);
1350 if ( iPos
!= wxNOT_FOUND
)
1351 str
.assign(*this, iPos
+ 1, npos
);
1356 // replace first (or all) occurrences of some substring with another one
1357 size_t wxString::Replace(const wxString
& strOld
,
1358 const wxString
& strNew
, bool bReplaceAll
)
1360 // if we tried to replace an empty string we'd enter an infinite loop below
1361 wxCHECK_MSG( !strOld
.empty(), 0,
1362 wxT("wxString::Replace(): invalid parameter") );
1364 wxSTRING_INVALIDATE_CACHE();
1366 size_t uiCount
= 0; // count of replacements made
1368 // optimize the special common case: replacement of one character by
1369 // another one (in UTF-8 case we can only do this for ASCII characters)
1371 // benchmarks show that this special version is around 3 times faster
1372 // (depending on the proportion of matching characters and UTF-8/wchar_t
1374 if ( strOld
.m_impl
.length() == 1 && strNew
.m_impl
.length() == 1 )
1376 const wxStringCharType chOld
= strOld
.m_impl
[0],
1377 chNew
= strNew
.m_impl
[0];
1379 // this loop is the simplified version of the one below
1380 for ( size_t pos
= 0; ; )
1382 pos
= m_impl
.find(chOld
, pos
);
1386 m_impl
[pos
++] = chNew
;
1394 else if ( !bReplaceAll
)
1396 size_t pos
= m_impl
.find(strOld
, 0);
1399 m_impl
.replace(pos
, strOld
.m_impl
.length(), strNew
.m_impl
);
1403 else // replace all occurrences
1405 const size_t uiOldLen
= strOld
.m_impl
.length();
1406 const size_t uiNewLen
= strNew
.m_impl
.length();
1408 // first scan the string to find all positions at which the replacement
1410 wxVector
<size_t> replacePositions
;
1413 for ( pos
= m_impl
.find(strOld
.m_impl
, 0);
1415 pos
= m_impl
.find(strOld
.m_impl
, pos
+ uiOldLen
))
1417 replacePositions
.push_back(pos
);
1424 // allocate enough memory for the whole new string
1426 tmp
.m_impl
.reserve(m_impl
.length() + uiCount
*(uiNewLen
- uiOldLen
));
1428 // copy this string to tmp doing replacements on the fly
1430 for ( pos
= 0; replNum
< uiCount
; replNum
++ )
1432 const size_t nextReplPos
= replacePositions
[replNum
];
1434 if ( pos
!= nextReplPos
)
1436 tmp
.m_impl
.append(m_impl
, pos
, nextReplPos
- pos
);
1439 tmp
.m_impl
.append(strNew
.m_impl
);
1440 pos
= nextReplPos
+ uiOldLen
;
1443 if ( pos
!= m_impl
.length() )
1445 // append the rest of the string unchanged
1446 tmp
.m_impl
.append(m_impl
, pos
, m_impl
.length() - pos
);
1455 bool wxString::IsAscii() const
1457 for ( const_iterator i
= begin(); i
!= end(); ++i
)
1459 if ( !(*i
).IsAscii() )
1466 bool wxString::IsWord() const
1468 for ( const_iterator i
= begin(); i
!= end(); ++i
)
1470 if ( !wxIsalpha(*i
) )
1477 bool wxString::IsNumber() const
1482 const_iterator i
= begin();
1484 if ( *i
== wxT('-') || *i
== wxT('+') )
1487 for ( ; i
!= end(); ++i
)
1489 if ( !wxIsdigit(*i
) )
1496 wxString
wxString::Strip(stripType w
) const
1499 if ( w
& leading
) s
.Trim(false);
1500 if ( w
& trailing
) s
.Trim(true);
1504 // ---------------------------------------------------------------------------
1506 // ---------------------------------------------------------------------------
1508 wxString
& wxString::MakeUpper()
1510 for ( iterator it
= begin(), en
= end(); it
!= en
; ++it
)
1511 *it
= (wxChar
)wxToupper(*it
);
1516 wxString
& wxString::MakeLower()
1518 for ( iterator it
= begin(), en
= end(); it
!= en
; ++it
)
1519 *it
= (wxChar
)wxTolower(*it
);
1524 wxString
& wxString::MakeCapitalized()
1526 const iterator en
= end();
1527 iterator it
= begin();
1530 *it
= (wxChar
)wxToupper(*it
);
1531 for ( ++it
; it
!= en
; ++it
)
1532 *it
= (wxChar
)wxTolower(*it
);
1538 // ---------------------------------------------------------------------------
1539 // trimming and padding
1540 // ---------------------------------------------------------------------------
1542 // some compilers (VC++ 6.0 not to name them) return true for a call to
1543 // isspace('\xEA') in the C locale which seems to be broken to me, but we have
1544 // to live with this by checking that the character is a 7 bit one - even if
1545 // this may fail to detect some spaces (I don't know if Unicode doesn't have
1546 // space-like symbols somewhere except in the first 128 chars), it is arguably
1547 // still better than trimming away accented letters
1548 inline int wxSafeIsspace(wxChar ch
) { return (ch
< 127) && wxIsspace(ch
); }
1550 // trims spaces (in the sense of isspace) from left or right side
1551 wxString
& wxString::Trim(bool bFromRight
)
1553 // first check if we're going to modify the string at all
1556 (bFromRight
&& wxSafeIsspace(GetChar(length() - 1))) ||
1557 (!bFromRight
&& wxSafeIsspace(GetChar(0u)))
1563 // find last non-space character
1564 reverse_iterator psz
= rbegin();
1565 while ( (psz
!= rend()) && wxSafeIsspace(*psz
) )
1568 // truncate at trailing space start
1569 erase(psz
.base(), end());
1573 // find first non-space character
1574 iterator psz
= begin();
1575 while ( (psz
!= end()) && wxSafeIsspace(*psz
) )
1578 // fix up data and length
1579 erase(begin(), psz
);
1586 // adds nCount characters chPad to the string from either side
1587 wxString
& wxString::Pad(size_t nCount
, wxUniChar chPad
, bool bFromRight
)
1589 wxString
s(chPad
, nCount
);
1602 // truncate the string
1603 wxString
& wxString::Truncate(size_t uiLen
)
1605 if ( uiLen
< length() )
1607 erase(begin() + uiLen
, end());
1609 //else: nothing to do, string is already short enough
1614 // ---------------------------------------------------------------------------
1615 // finding (return wxNOT_FOUND if not found and index otherwise)
1616 // ---------------------------------------------------------------------------
1619 int wxString::Find(wxUniChar ch
, bool bFromEnd
) const
1621 size_type idx
= bFromEnd
? find_last_of(ch
) : find_first_of(ch
);
1623 return (idx
== npos
) ? wxNOT_FOUND
: (int)idx
;
1626 // ----------------------------------------------------------------------------
1627 // conversion to numbers
1628 // ----------------------------------------------------------------------------
1630 // The implementation of all the functions below is exactly the same so factor
1631 // it out. Note that number extraction works correctly on UTF-8 strings, so
1632 // we can use wxStringCharType and wx_str() for maximum efficiency.
1635 #define DO_IF_NOT_WINCE(x) x
1637 #define DO_IF_NOT_WINCE(x)
1640 #define WX_STRING_TO_X_TYPE_START \
1641 wxCHECK_MSG( pVal, false, wxT("NULL output pointer") ); \
1642 DO_IF_NOT_WINCE( errno = 0; ) \
1643 const wxStringCharType *start = wx_str(); \
1644 wxStringCharType *end;
1646 // notice that we return false without modifying the output parameter at all if
1647 // nothing could be parsed but we do modify it and return false then if we did
1648 // parse something successfully but not the entire string
1649 #define WX_STRING_TO_X_TYPE_END \
1650 if ( end == start DO_IF_NOT_WINCE(|| errno == ERANGE) ) \
1655 bool wxString::ToLong(long *pVal
, int base
) const
1657 wxASSERT_MSG( !base
|| (base
> 1 && base
<= 36), wxT("invalid base") );
1659 WX_STRING_TO_X_TYPE_START
1660 long val
= wxStrtol(start
, &end
, base
);
1661 WX_STRING_TO_X_TYPE_END
1664 bool wxString::ToULong(unsigned long *pVal
, int base
) const
1666 wxASSERT_MSG( !base
|| (base
> 1 && base
<= 36), wxT("invalid base") );
1668 WX_STRING_TO_X_TYPE_START
1669 unsigned long val
= wxStrtoul(start
, &end
, base
);
1670 WX_STRING_TO_X_TYPE_END
1673 bool wxString::ToLongLong(wxLongLong_t
*pVal
, int base
) const
1675 wxASSERT_MSG( !base
|| (base
> 1 && base
<= 36), wxT("invalid base") );
1677 WX_STRING_TO_X_TYPE_START
1678 wxLongLong_t val
= wxStrtoll(start
, &end
, base
);
1679 WX_STRING_TO_X_TYPE_END
1682 bool wxString::ToULongLong(wxULongLong_t
*pVal
, int base
) const
1684 wxASSERT_MSG( !base
|| (base
> 1 && base
<= 36), wxT("invalid base") );
1686 WX_STRING_TO_X_TYPE_START
1687 wxULongLong_t val
= wxStrtoull(start
, &end
, base
);
1688 WX_STRING_TO_X_TYPE_END
1691 bool wxString::ToDouble(double *pVal
) const
1693 WX_STRING_TO_X_TYPE_START
1694 double val
= wxStrtod(start
, &end
);
1695 WX_STRING_TO_X_TYPE_END
1700 bool wxString::ToCLong(long *pVal
, int base
) const
1702 wxASSERT_MSG( !base
|| (base
> 1 && base
<= 36), wxT("invalid base") );
1704 WX_STRING_TO_X_TYPE_START
1705 #if (wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE) && defined(wxHAS_XLOCALE_SUPPORT)
1706 long val
= wxStrtol_lA(start
, &end
, base
, wxCLocale
);
1708 long val
= wxStrtol_l(start
, &end
, base
, wxCLocale
);
1710 WX_STRING_TO_X_TYPE_END
1713 bool wxString::ToCULong(unsigned long *pVal
, int base
) const
1715 wxASSERT_MSG( !base
|| (base
> 1 && base
<= 36), wxT("invalid base") );
1717 WX_STRING_TO_X_TYPE_START
1718 #if (wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE) && defined(wxHAS_XLOCALE_SUPPORT)
1719 unsigned long val
= wxStrtoul_lA(start
, &end
, base
, wxCLocale
);
1721 unsigned long val
= wxStrtoul_l(start
, &end
, base
, wxCLocale
);
1723 WX_STRING_TO_X_TYPE_END
1726 bool wxString::ToCDouble(double *pVal
) const
1728 WX_STRING_TO_X_TYPE_START
1729 #if (wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE) && defined(wxHAS_XLOCALE_SUPPORT)
1730 double val
= wxStrtod_lA(start
, &end
, wxCLocale
);
1732 double val
= wxStrtod_l(start
, &end
, wxCLocale
);
1734 WX_STRING_TO_X_TYPE_END
1737 #else // wxUSE_XLOCALE
1739 // Provide implementation of these functions even when wxUSE_XLOCALE is
1740 // disabled, we still need them in wxWidgets internal code.
1742 // For integers we just assume the current locale uses the same number
1743 // representation as the C one as there is nothing else we can do.
1744 bool wxString::ToCLong(long *pVal
, int base
) const
1746 return ToLong(pVal
, base
);
1749 bool wxString::ToCULong(unsigned long *pVal
, int base
) const
1751 return ToULong(pVal
, base
);
1754 // For floating point numbers we have to handle the problem of the decimal
1755 // point which is different in different locales.
1756 bool wxString::ToCDouble(double *pVal
) const
1758 // Create a copy of this string using the decimal point instead of whatever
1759 // separator the current locale uses.
1761 wxString sep
= wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT
,
1762 wxLOCALE_CAT_NUMBER
);
1765 // We can avoid an unnecessary string copy in this case.
1766 return ToDouble(pVal
);
1768 #else // !wxUSE_INTL
1769 // We don't know what the current separator is so it might even be a point
1770 // already, try to parse the string as a double:
1771 if ( ToDouble(pVal
) )
1773 // It must have been the point, nothing else to do.
1777 // Try to guess the separator, using the most common alternative value.
1779 #endif // wxUSE_INTL/!wxUSE_INTL
1780 wxString
cstr(*this);
1781 cstr
.Replace(".", sep
);
1783 return cstr
.ToDouble(pVal
);
1786 #endif // wxUSE_XLOCALE/!wxUSE_XLOCALE
1788 // ---------------------------------------------------------------------------
1790 // ---------------------------------------------------------------------------
1792 #if !wxUSE_UTF8_LOCALE_ONLY
1794 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
1795 wxString
wxStringPrintfMixinBase::DoFormatWchar(const wxChar
*format
, ...)
1797 wxString
wxString::DoFormatWchar(const wxChar
*format
, ...)
1801 va_start(argptr
, format
);
1804 s
.PrintfV(format
, argptr
);
1810 #endif // !wxUSE_UTF8_LOCALE_ONLY
1812 #if wxUSE_UNICODE_UTF8
1814 wxString
wxString::DoFormatUtf8(const char *format
, ...)
1817 va_start(argptr
, format
);
1820 s
.PrintfV(format
, argptr
);
1826 #endif // wxUSE_UNICODE_UTF8
1829 wxString
wxString::FormatV(const wxString
& format
, va_list argptr
)
1832 s
.PrintfV(format
, argptr
);
1836 #if !wxUSE_UTF8_LOCALE_ONLY
1837 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
1838 int wxStringPrintfMixinBase::DoPrintfWchar(const wxChar
*format
, ...)
1840 int wxString::DoPrintfWchar(const wxChar
*format
, ...)
1844 va_start(argptr
, format
);
1846 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
1847 // get a pointer to the wxString instance; we have to use dynamic_cast<>
1848 // because it's the only cast that works safely for downcasting when
1849 // multiple inheritance is used:
1850 wxString
*str
= static_cast<wxString
*>(this);
1852 wxString
*str
= this;
1855 int iLen
= str
->PrintfV(format
, argptr
);
1861 #endif // !wxUSE_UTF8_LOCALE_ONLY
1863 #if wxUSE_UNICODE_UTF8
1864 int wxString::DoPrintfUtf8(const char *format
, ...)
1867 va_start(argptr
, format
);
1869 int iLen
= PrintfV(format
, argptr
);
1875 #endif // wxUSE_UNICODE_UTF8
1878 Uses wxVsnprintf and places the result into the this string.
1880 In ANSI build, wxVsnprintf is effectively vsnprintf but in Unicode build
1881 it is vswprintf. Due to a discrepancy between vsnprintf and vswprintf in
1882 the ISO C99 (and thus SUSv3) standard the return value for the case of
1883 an undersized buffer is inconsistent. For conforming vsnprintf
1884 implementations the function must return the number of characters that
1885 would have been printed had the buffer been large enough. For conforming
1886 vswprintf implementations the function must return a negative number
1889 What vswprintf sets errno to is undefined but Darwin seems to set it to
1890 EOVERFLOW. The only expected errno are EILSEQ and EINVAL. Both of
1891 those are defined in the standard and backed up by several conformance
1892 statements. Note that ENOMEM mentioned in the manual page does not
1893 apply to swprintf, only wprintf and fwprintf.
1895 Official manual page:
1896 http://www.opengroup.org/onlinepubs/009695399/functions/swprintf.html
1898 Some conformance statements (AIX, Solaris):
1899 http://www.opengroup.org/csq/view.mhtml?RID=ibm%2FSD1%2F3
1900 http://www.theopengroup.org/csq/view.mhtml?norationale=1&noreferences=1&RID=Fujitsu%2FSE2%2F10
1902 Since EILSEQ and EINVAL are rather common but EOVERFLOW is not and since
1903 EILSEQ and EINVAL are specifically defined to mean the error is other than
1904 an undersized buffer and no other errno are defined we treat those two
1905 as meaning hard errors and everything else gets the old behavior which
1906 is to keep looping and increasing buffer size until the function succeeds.
1908 In practice it's impossible to determine before compilation which behavior
1909 may be used. The vswprintf function may have vsnprintf-like behavior or
1910 vice-versa. Behavior detected on one release can theoretically change
1911 with an updated release. Not to mention that configure testing for it
1912 would require the test to be run on the host system, not the build system
1913 which makes cross compilation difficult. Therefore, we make no assumptions
1914 about behavior and try our best to handle every known case, including the
1915 case where wxVsnprintf returns a negative number and fails to set errno.
1917 There is yet one more non-standard implementation and that is our own.
1918 Fortunately, that can be detected at compile-time.
1920 On top of all that, ISO C99 explicitly defines snprintf to write a null
1921 character to the last position of the specified buffer. That would be at
1922 at the given buffer size minus 1. It is supposed to do this even if it
1923 turns out that the buffer is sized too small.
1925 Darwin (tested on 10.5) follows the C99 behavior exactly.
1927 Glibc 2.6 almost follows the C99 behavior except vswprintf never sets
1928 errno even when it fails. However, it only seems to ever fail due
1929 to an undersized buffer.
1931 #if wxUSE_UNICODE_UTF8
1932 template<typename BufferType
>
1934 // we only need one version in non-UTF8 builds and at least two Windows
1935 // compilers have problems with this function template, so use just one
1936 // normal function here
1938 static int DoStringPrintfV(wxString
& str
,
1939 const wxString
& format
, va_list argptr
)
1945 #if wxUSE_UNICODE_UTF8
1946 BufferType
tmp(str
, size
+ 1);
1947 typename
BufferType::CharType
*buf
= tmp
;
1949 wxStringBuffer
tmp(str
, size
+ 1);
1957 // in UTF-8 build, leaving uninitialized junk in the buffer
1958 // could result in invalid non-empty UTF-8 string, so just
1959 // reset the string to empty on failure:
1964 // wxVsnprintf() may modify the original arg pointer, so pass it
1967 wxVaCopy(argptrcopy
, argptr
);
1970 // Set errno to 0 to make it determinate if wxVsnprintf fails to set it.
1973 int len
= wxVsnprintf(buf
, size
, format
, argptrcopy
);
1976 // some implementations of vsnprintf() don't NUL terminate
1977 // the string if there is not enough space for it so
1978 // always do it manually
1979 // FIXME: This really seems to be the wrong and would be an off-by-one
1980 // bug except the code above allocates an extra character.
1981 buf
[size
] = wxT('\0');
1983 // vsnprintf() may return either -1 (traditional Unix behaviour) or the
1984 // total number of characters which would have been written if the
1985 // buffer were large enough (newer standards such as Unix98)
1988 // NB: wxVsnprintf() may call either wxCRT_VsnprintfW or
1989 // wxCRT_VsnprintfA in UTF-8 build; wxUSE_WXVSNPRINTF
1990 // is true if *both* of them use our own implementation,
1991 // otherwise we can't be sure
1992 #if wxUSE_WXVSNPRINTF
1993 // we know that our own implementation of wxVsnprintf() returns -1
1994 // only for a format error - thus there's something wrong with
1995 // the user's format string
1998 #else // possibly using system version
1999 // assume it only returns error if there is not enough space, but
2000 // as we don't know how much we need, double the current size of
2003 if( (errno
== EILSEQ
) || (errno
== EINVAL
) )
2004 // If errno was set to one of the two well-known hard errors
2005 // then fail immediately to avoid an infinite loop.
2008 #endif // __WXWINCE__
2009 // still not enough, as we don't know how much we need, double the
2010 // current size of the buffer
2012 #endif // wxUSE_WXVSNPRINTF/!wxUSE_WXVSNPRINTF
2014 else if ( len
>= size
)
2016 #if wxUSE_WXVSNPRINTF
2017 // we know that our own implementation of wxVsnprintf() returns
2018 // size+1 when there's not enough space but that's not the size
2019 // of the required buffer!
2020 size
*= 2; // so we just double the current size of the buffer
2022 // some vsnprintf() implementations NUL-terminate the buffer and
2023 // some don't in len == size case, to be safe always add 1
2024 // FIXME: I don't quite understand this comment. The vsnprintf
2025 // function is specifically defined to return the number of
2026 // characters printed not including the null terminator.
2027 // So OF COURSE you need to add 1 to get the right buffer size.
2028 // The following line is definitely correct, no question.
2032 else // ok, there was enough space
2038 // we could have overshot
2041 return str
.length();
2044 int wxString::PrintfV(const wxString
& format
, va_list argptr
)
2046 #if wxUSE_UNICODE_UTF8
2047 #if wxUSE_STL_BASED_WXSTRING
2048 typedef wxStringTypeBuffer
<char> Utf8Buffer
;
2050 typedef wxStringInternalBuffer Utf8Buffer
;
2054 #if wxUSE_UTF8_LOCALE_ONLY
2055 return DoStringPrintfV
<Utf8Buffer
>(*this, format
, argptr
);
2057 #if wxUSE_UNICODE_UTF8
2058 if ( wxLocaleIsUtf8
)
2059 return DoStringPrintfV
<Utf8Buffer
>(*this, format
, argptr
);
2062 return DoStringPrintfV
<wxStringBuffer
>(*this, format
, argptr
);
2064 return DoStringPrintfV(*this, format
, argptr
);
2065 #endif // UTF8/WCHAR
2069 // ----------------------------------------------------------------------------
2070 // misc other operations
2071 // ----------------------------------------------------------------------------
2073 // returns true if the string matches the pattern which may contain '*' and
2074 // '?' metacharacters (as usual, '?' matches any character and '*' any number
2076 bool wxString::Matches(const wxString
& mask
) const
2078 // I disable this code as it doesn't seem to be faster (in fact, it seems
2079 // to be much slower) than the old, hand-written code below and using it
2080 // here requires always linking with libregex even if the user code doesn't
2082 #if 0 // wxUSE_REGEX
2083 // first translate the shell-like mask into a regex
2085 pattern
.reserve(wxStrlen(pszMask
));
2087 pattern
+= wxT('^');
2093 pattern
+= wxT('.');
2097 pattern
+= wxT(".*");
2108 // these characters are special in a RE, quote them
2109 // (however note that we don't quote '[' and ']' to allow
2110 // using them for Unix shell like matching)
2111 pattern
+= wxT('\\');
2115 pattern
+= *pszMask
;
2120 pattern
+= wxT('$');
2123 return wxRegEx(pattern
, wxRE_NOSUB
| wxRE_EXTENDED
).Matches(c_str());
2124 #else // !wxUSE_REGEX
2125 // TODO: this is, of course, awfully inefficient...
2127 // FIXME-UTF8: implement using iterators, remove #if
2128 #if wxUSE_UNICODE_UTF8
2129 const wxScopedWCharBuffer maskBuf
= mask
.wc_str();
2130 const wxScopedWCharBuffer txtBuf
= wc_str();
2131 const wxChar
*pszMask
= maskBuf
.data();
2132 const wxChar
*pszTxt
= txtBuf
.data();
2134 const wxChar
*pszMask
= mask
.wx_str();
2135 // the char currently being checked
2136 const wxChar
*pszTxt
= wx_str();
2139 // the last location where '*' matched
2140 const wxChar
*pszLastStarInText
= NULL
;
2141 const wxChar
*pszLastStarInMask
= NULL
;
2144 for ( ; *pszMask
!= wxT('\0'); pszMask
++, pszTxt
++ ) {
2145 switch ( *pszMask
) {
2147 if ( *pszTxt
== wxT('\0') )
2150 // pszTxt and pszMask will be incremented in the loop statement
2156 // remember where we started to be able to backtrack later
2157 pszLastStarInText
= pszTxt
;
2158 pszLastStarInMask
= pszMask
;
2160 // ignore special chars immediately following this one
2161 // (should this be an error?)
2162 while ( *pszMask
== wxT('*') || *pszMask
== wxT('?') )
2165 // if there is nothing more, match
2166 if ( *pszMask
== wxT('\0') )
2169 // are there any other metacharacters in the mask?
2171 const wxChar
*pEndMask
= wxStrpbrk(pszMask
, wxT("*?"));
2173 if ( pEndMask
!= NULL
) {
2174 // we have to match the string between two metachars
2175 uiLenMask
= pEndMask
- pszMask
;
2178 // we have to match the remainder of the string
2179 uiLenMask
= wxStrlen(pszMask
);
2182 wxString
strToMatch(pszMask
, uiLenMask
);
2183 const wxChar
* pMatch
= wxStrstr(pszTxt
, strToMatch
);
2184 if ( pMatch
== NULL
)
2187 // -1 to compensate "++" in the loop
2188 pszTxt
= pMatch
+ uiLenMask
- 1;
2189 pszMask
+= uiLenMask
- 1;
2194 if ( *pszMask
!= *pszTxt
)
2200 // match only if nothing left
2201 if ( *pszTxt
== wxT('\0') )
2204 // if we failed to match, backtrack if we can
2205 if ( pszLastStarInText
) {
2206 pszTxt
= pszLastStarInText
+ 1;
2207 pszMask
= pszLastStarInMask
;
2209 pszLastStarInText
= NULL
;
2211 // don't bother resetting pszLastStarInMask, it's unnecessary
2217 #endif // wxUSE_REGEX/!wxUSE_REGEX
2220 // Count the number of chars
2221 int wxString::Freq(wxUniChar ch
) const
2224 for ( const_iterator i
= begin(); i
!= end(); ++i
)