]> git.saurik.com Git - wxWidgets.git/blame - include/wx/string.h
moved XML classes to the core
[wxWidgets.git] / include / wx / string.h
CommitLineData
3c67202d 1///////////////////////////////////////////////////////////////////////////////
c801d85f 2// Name: string.h
3c67202d 3// Purpose: wxString and wxArrayString classes
c801d85f
KB
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 29/01/98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
371a5b4e 9// Licence: wxWindows licence
3c67202d 10///////////////////////////////////////////////////////////////////////////////
c801d85f 11
e90c1d2a
VZ
12/*
13 Efficient string class [more or less] compatible with MFC CString,
14 wxWindows version 1 wxString and std::string and some handy functions
15 missing from string.h.
16*/
17
34138703
JS
18#ifndef _WX_WXSTRINGH__
19#define _WX_WXSTRINGH__
c801d85f 20
af49c4b8 21#if defined(__GNUG__) && !defined(__APPLE__)
e90c1d2a
VZ
22 #pragma interface "string.h"
23#endif
24
25// ----------------------------------------------------------------------------
26// conditinal compilation
27// ----------------------------------------------------------------------------
28
29// compile the std::string compatibility functions if defined
30#define wxSTD_STRING_COMPATIBILITY
31
e90c1d2a
VZ
32// ----------------------------------------------------------------------------
33// headers
34// ----------------------------------------------------------------------------
35
5737d05f
VZ
36#include "wx/defs.h" // everybody should include this
37
9dea36ef 38#if defined(__WXMAC__) || defined(__VISAGECPP__)
3f4a0c5b 39 #include <ctype.h>
17dff81c 40#endif
3f4a0c5b 41
91b8de8d
RR
42#ifdef __EMX__
43 #include <std.h>
44#endif
45
9dea36ef
DW
46#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
47 // problem in VACPP V4 with including stdlib.h multiple times
48 // strconv includes it anyway
49# include <stdio.h>
50# include <string.h>
51# include <stdarg.h>
52# include <limits.h>
53#else
54# include <string.h>
55# include <stdio.h>
56# include <stdarg.h>
57# include <limits.h>
58# include <stdlib.h>
59#endif
c801d85f 60
57493f9f 61#ifdef HAVE_STRINGS_H
1bfcb0b6 62 #include <strings.h> // for strcasecmp()
d739313f 63#endif // HAVE_STRINGS_H
1bfcb0b6 64
e90c1d2a
VZ
65#include "wx/wxchar.h" // for wxChar
66#include "wx/buffer.h" // for wxCharBuffer
67#include "wx/strconv.h" // for wxConvertXXX() macros and wxMBConv classes
3f4a0c5b 68
c801d85f
KB
69// ---------------------------------------------------------------------------
70// macros
71// ---------------------------------------------------------------------------
72
5737d05f
VZ
73// casts [unfortunately!] needed to call some broken functions which require
74// "char *" instead of "const char *"
2bb67b80 75#define WXSTRINGCAST (wxChar *)(const wxChar *)
e90c1d2a
VZ
76#define wxCSTRINGCAST (wxChar *)(const wxChar *)
77#define wxMBSTRINGCAST (char *)(const char *)
78#define wxWCSTRINGCAST (wchar_t *)(const wchar_t *)
c801d85f 79
3c67202d 80// implementation only
5737d05f 81#define wxASSERT_VALID_INDEX(i) \
b1801e0e 82 wxASSERT_MSG( (size_t)(i) <= Len(), _T("invalid index in wxString") )
c801d85f 83
e90c1d2a
VZ
84// ----------------------------------------------------------------------------
85// constants
86// ----------------------------------------------------------------------------
87
66b6b045 88#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
67b81440 89// must define this static for VA or else you get multiply defined symbols everywhere
5d33ed2c 90extern const unsigned int wxSTRING_MAXLEN;
66b6b045
DW
91
92#else
e90c1d2a
VZ
93// maximum possible length for a string means "take all string" everywhere
94// (as sizeof(StringData) is unknown here, we substract 100)
95const unsigned int wxSTRING_MAXLEN = UINT_MAX - 100;
96
66b6b045
DW
97#endif
98
e90c1d2a
VZ
99// ----------------------------------------------------------------------------
100// global data
101// ----------------------------------------------------------------------------
102
103// global pointer to empty string
bddd7a8d 104extern WXDLLIMPEXP_DATA_BASE(const wxChar*) wxEmptyString;
6001e347 105
c801d85f 106// ---------------------------------------------------------------------------
e90c1d2a 107// global functions complementing standard C string library replacements for
3c67202d
VZ
108// strlen() and portable strcasecmp()
109//---------------------------------------------------------------------------
e90c1d2a
VZ
110
111// Use wxXXX() functions from wxchar.h instead! These functions are for
112// backwards compatibility only.
88150e60 113
3c67202d 114// checks whether the passed in pointer is NULL and if the string is empty
6d56eb5c 115inline bool IsEmpty(const char *p) { return (!p || !*p); }
c801d85f 116
3c67202d 117// safe version of strlen() (returns 0 if passed NULL pointer)
6d56eb5c 118inline size_t Strlen(const char *psz)
c801d85f
KB
119 { return psz ? strlen(psz) : 0; }
120
3c67202d 121// portable strcasecmp/_stricmp
6d56eb5c 122inline int Stricmp(const char *psz1, const char *psz2)
dd1eaa89 123{
7f0586ef
JS
124#if defined(__VISUALC__) && defined(__WXWINCE__)
125 register char c1, c2;
126 do {
127 c1 = tolower(*psz1++);
128 c2 = tolower(*psz2++);
129 } while ( c1 && (c1 == c2) );
130
131 return c1 - c2;
132#elif defined(__VISUALC__) || ( defined(__MWERKS__) && defined(__INTEL__) )
dd1eaa89 133 return _stricmp(psz1, psz2);
91b8de8d 134#elif defined(__SC__)
2432b92d 135 return _stricmp(psz1, psz2);
91b8de8d 136#elif defined(__SALFORDC__)
a3ef5bf5 137 return stricmp(psz1, psz2);
dd1eaa89
VZ
138#elif defined(__BORLANDC__)
139 return stricmp(psz1, psz2);
7be1f0d9
JS
140#elif defined(__WATCOMC__)
141 return stricmp(psz1, psz2);
14704334
VS
142#elif defined(__DJGPP__)
143 return stricmp(psz1, psz2);
91b8de8d
RR
144#elif defined(__EMX__)
145 return stricmp(psz1, psz2);
e2c87f4c 146#elif defined(__WXPM__)
1777b9bb 147 return stricmp(psz1, psz2);
91b8de8d 148#elif defined(__UNIX__) || defined(__GNUWIN32__)
dd1eaa89 149 return strcasecmp(psz1, psz2);
8be97d65 150#elif defined(__MWERKS__) && !defined(__INTEL__)
17dff81c
SC
151 register char c1, c2;
152 do {
153 c1 = tolower(*psz1++);
154 c2 = tolower(*psz2++);
155 } while ( c1 && (c1 == c2) );
156
157 return c1 - c2;
dd1eaa89
VZ
158#else
159 // almost all compilers/libraries provide this function (unfortunately under
160 // different names), that's why we don't implement our own which will surely
161 // be more efficient than this code (uncomment to use):
162 /*
163 register char c1, c2;
164 do {
165 c1 = tolower(*psz1++);
166 c2 = tolower(*psz2++);
167 } while ( c1 && (c1 == c2) );
168
169 return c1 - c2;
170 */
171
172 #error "Please define string case-insensitive compare for your OS/compiler"
173#endif // OS/compiler
174}
c801d85f 175
f04f3991 176// return an empty wxString
bddd7a8d 177class WXDLLIMPEXP_BASE wxString; // not yet defined
e90c1d2a 178inline const wxString& wxGetEmptyString() { return *(wxString *)&wxEmptyString; }
f04f3991 179
c801d85f 180// ---------------------------------------------------------------------------
f04f3991 181// string data prepended with some housekeeping info (used by wxString class),
c801d85f
KB
182// is never used directly (but had to be put here to allow inlining)
183// ---------------------------------------------------------------------------
e90c1d2a 184
bddd7a8d 185struct WXDLLIMPEXP_BASE wxStringData
c801d85f
KB
186{
187 int nRefs; // reference count
3c024cc2 188 size_t nDataLength, // actual string length
c801d85f
KB
189 nAllocLength; // allocated memory size
190
2bb67b80
OK
191 // mimics declaration 'wxChar data[nAllocLength]'
192 wxChar* data() const { return (wxChar*)(this + 1); }
c801d85f
KB
193
194 // empty string has a special ref count so it's never deleted
dbda9e86
JS
195 bool IsEmpty() const { return (nRefs == -1); }
196 bool IsShared() const { return (nRefs > 1); }
c801d85f
KB
197
198 // lock/unlock
dd1eaa89 199 void Lock() { if ( !IsEmpty() ) nRefs++; }
f6bcfd97 200
8ecf21b7 201 // VC++ will refuse to inline Unlock but profiling shows that it is wrong
f6bcfd97
BP
202#if defined(__VISUALC__) && (__VISUALC__ >= 1200)
203 __forceinline
204#endif
ca5e07c7
GD
205 // VC++ free must take place in same DLL as allocation when using non dll
206 // run-time library (e.g. Multithreaded instead of Multithreaded DLL)
8ecf21b7
GD
207#if defined(__VISUALC__) && defined(_MT) && !defined(_DLL)
208 void Unlock() { if ( !IsEmpty() && --nRefs == 0) Free(); }
ca5e07c7
GD
209 // we must not inline deallocation since allocation is not inlined
210 void Free();
8ecf21b7 211#else
f1317a5d 212 void Unlock() { if ( !IsEmpty() && --nRefs == 0) free(this); }
8ecf21b7 213#endif
8fd0f20b 214
dd1eaa89 215 // if we had taken control over string memory (GetWriteBuf), it's
8fd0f20b 216 // intentionally put in invalid state
dbda9e86
JS
217 void Validate(bool b) { nRefs = (b ? 1 : 0); }
218 bool IsValid() const { return (nRefs != 0); }
c801d85f
KB
219};
220
c801d85f 221// ---------------------------------------------------------------------------
3c67202d
VZ
222// This is (yet another one) String class for C++ programmers. It doesn't use
223// any of "advanced" C++ features (i.e. templates, exceptions, namespaces...)
224// thus you should be able to compile it with practicaly any C++ compiler.
225// This class uses copy-on-write technique, i.e. identical strings share the
226// same memory as long as neither of them is changed.
227//
228// This class aims to be as compatible as possible with the new standard
229// std::string class, but adds some additional functions and should be at
230// least as efficient than the standard implementation.
231//
232// Performance note: it's more efficient to write functions which take "const
233// String&" arguments than "const char *" if you assign the argument to
234// another string.
235//
236// It was compiled and tested under Win32, Linux (libc 5 & 6), Solaris 5.5.
237//
238// To do:
239// - ressource support (string tables in ressources)
240// - more wide character (UNICODE) support
241// - regular expressions support
c801d85f 242// ---------------------------------------------------------------------------
3c67202d 243
bddd7a8d 244class WXDLLIMPEXP_BASE wxString
3c67202d 245{
df5168c4 246#if !wxUSE_STL
bddd7a8d 247friend class WXDLLIMPEXP_BASE wxArrayString;
df5168c4 248#endif
c801d85f 249
3c67202d
VZ
250 // NB: special care was taken in arranging the member functions in such order
251 // that all inline functions can be effectively inlined, verify that all
252 // performace critical functions are still inlined if you change order!
dd1eaa89
VZ
253private:
254 // points to data preceded by wxStringData structure with ref count info
2bb67b80 255 wxChar *m_pchData;
dd1eaa89
VZ
256
257 // accessor to string data
258 wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; }
259
6b95b20d
VZ
260 // string (re)initialization functions
261 // initializes the string to the empty value (must be called only from
262 // ctors, use Reinit() otherwise)
e90c1d2a 263 void Init() { m_pchData = (wxChar *)wxEmptyString; }
6b95b20d 264 // initializaes the string with (a part of) C-string
2bb67b80 265 void InitWith(const wxChar *psz, size_t nPos = 0, size_t nLen = wxSTRING_MAXLEN);
6b95b20d
VZ
266 // as Init, but also frees old data
267 void Reinit() { GetStringData()->Unlock(); Init(); }
268
269 // memory allocation
b1801e0e
GD
270 // allocates memory for string of length nLen
271 bool AllocBuffer(size_t nLen);
6b95b20d 272 // copies data to another string
b1801e0e 273 bool AllocCopy(wxString&, int, int) const;
6b95b20d 274 // effectively copies data to string
b1801e0e 275 bool AssignCopy(size_t, const wxChar *);
6b95b20d
VZ
276
277 // append a (sub)string
083f7497 278 bool ConcatSelf(size_t nLen, const wxChar *src);
6b95b20d
VZ
279
280 // functions called before writing to the string: they copy it if there
281 // are other references to our data (should be the only owner when writing)
b1801e0e
GD
282 bool CopyBeforeWrite();
283 bool AllocBeforeWrite(size_t);
6b95b20d 284
00b4a13e
VZ
285 // if we hadn't made these operators private, it would be possible to
286 // compile "wxString s; s = 17;" without any warnings as 17 is implicitly
287 // converted to char in C and we do have operator=(char)
288 //
289 // NB: we don't need other versions (short/long and unsigned) as attempt
290 // to assign another numeric type to wxString will now result in
291 // ambiguity between operator=(char) and operator=(int)
292 wxString& operator=(int);
293
294 // these methods are not implemented - there is _no_ conversion from int to
c606a9a4
VZ
295 // string, you're doing something wrong if the compiler wants to call it!
296 //
297 // try `s << i' or `s.Printf("%d", i)' instead
298 wxString(int);
c606a9a4 299
c801d85f 300public:
3c67202d
VZ
301 // constructors and destructor
302 // ctor for an empty string
b1801e0e 303 wxString() : m_pchData(NULL) { Init(); }
3c67202d 304 // copy ctor
b1801e0e 305 wxString(const wxString& stringSrc) : m_pchData(NULL)
6b95b20d 306 {
09443a26
VZ
307 wxASSERT_MSG( stringSrc.GetStringData()->IsValid(),
308 _T("did you forget to call UngetWriteBuf()?") );
6b95b20d
VZ
309
310 if ( stringSrc.IsEmpty() ) {
311 // nothing to do for an empty string
312 Init();
313 }
314 else {
315 m_pchData = stringSrc.m_pchData; // share same data
316 GetStringData()->Lock(); // => one more copy
317 }
318 }
3c67202d 319 // string containing nRepeat copies of ch
2bb67b80 320 wxString(wxChar ch, size_t nRepeat = 1);
3c67202d 321 // ctor takes first nLength characters from C string
566b84d2 322 // (default value of wxSTRING_MAXLEN means take all the string)
2bb67b80 323 wxString(const wxChar *psz, size_t nLength = wxSTRING_MAXLEN)
b1801e0e
GD
324 : m_pchData(NULL)
325 { InitWith(psz, 0, nLength); }
f6bcfd97 326 wxString(const wxChar *psz, wxMBConv& WXUNUSED(conv), size_t nLength = wxSTRING_MAXLEN)
b1801e0e
GD
327 : m_pchData(NULL)
328 { InitWith(psz, 0, nLength); }
e90c1d2a 329
2bb67b80
OK
330#if wxUSE_UNICODE
331 // from multibyte string
332 // (NB: nLength is right now number of Unicode characters, not
333 // characters in psz! So try not to use it yet!)
2b5f62a0 334 wxString(const char *psz, wxMBConv& conv, size_t nLength = wxSTRING_MAXLEN);
2bb67b80
OK
335 // from wxWCharBuffer (i.e. return from wxGetString)
336 wxString(const wxWCharBuffer& psz)
337 { InitWith(psz, 0, wxSTRING_MAXLEN); }
e90c1d2a 338#else // ANSI
3c67202d 339 // from C string (for compilers using unsigned char)
2bb67b80 340 wxString(const unsigned char* psz, size_t nLength = wxSTRING_MAXLEN)
b1801e0e
GD
341 : m_pchData(NULL)
342 { InitWith((const char*)psz, 0, nLength); }
e90c1d2a 343
6f841509 344#if wxUSE_WCHAR_T
2bb67b80 345 // from wide (Unicode) string
1c2e6a28 346 wxString(const wchar_t *pwz, wxMBConv& conv = wxConvLibc, size_t nLength = wxSTRING_MAXLEN);
e90c1d2a
VZ
347#endif // !wxUSE_WCHAR_T
348
2bb67b80
OK
349 // from wxCharBuffer
350 wxString(const wxCharBuffer& psz)
b1801e0e
GD
351 : m_pchData(NULL)
352 { InitWith(psz, 0, wxSTRING_MAXLEN); }
e90c1d2a
VZ
353#endif // Unicode/ANSI
354
3c67202d 355 // dtor is not virtual, this class must not be inherited from!
6b95b20d 356 ~wxString() { GetStringData()->Unlock(); }
c801d85f 357
3c67202d
VZ
358 // generic attributes & operations
359 // as standard strlen()
47d67540 360 size_t Len() const { return GetStringData()->nDataLength; }
3c67202d 361 // string contains any characters?
dd1eaa89 362 bool IsEmpty() const { return Len() == 0; }
dcfde592
VZ
363 // empty string is "FALSE", so !str will return TRUE
364 bool operator!() const { return IsEmpty(); }
735d1db6
VZ
365 // truncate the string to given length
366 wxString& Truncate(size_t uiLen);
3c67202d 367 // empty string contents
dd1eaa89
VZ
368 void Empty()
369 {
735d1db6 370 Truncate(0);
dd1eaa89 371
735d1db6 372 wxASSERT_MSG( IsEmpty(), _T("string not empty after call to Empty()?") );
7be07660 373 }
3c67202d 374 // empty the string and free memory
7be07660
VZ
375 void Clear()
376 {
377 if ( !GetStringData()->IsEmpty() )
378 Reinit();
379
09443a26
VZ
380 wxASSERT_MSG( !GetStringData()->nDataLength &&
381 !GetStringData()->nAllocLength,
382 _T("string should be empty after Clear()") );
dd1eaa89
VZ
383 }
384
3c67202d
VZ
385 // contents test
386 // Is an ascii value
c801d85f 387 bool IsAscii() const;
3c67202d 388 // Is a number
c801d85f 389 bool IsNumber() const;
3c67202d 390 // Is a word
c801d85f 391 bool IsWord() const;
c801d85f 392
3c67202d
VZ
393 // data access (all indexes are 0 based)
394 // read access
2bb67b80 395 wxChar GetChar(size_t n) const
5737d05f 396 { wxASSERT_VALID_INDEX( n ); return m_pchData[n]; }
3c67202d 397 // read/write access
2bb67b80 398 wxChar& GetWritableChar(size_t n)
5737d05f 399 { wxASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
3c67202d 400 // write access
2bb67b80 401 void SetChar(size_t n, wxChar ch)
5737d05f 402 { wxASSERT_VALID_INDEX( n ); CopyBeforeWrite(); m_pchData[n] = ch; }
c801d85f 403
3c67202d 404 // get last character
2bb67b80 405 wxChar Last() const
09443a26
VZ
406 {
407 wxASSERT_MSG( !IsEmpty(), _T("wxString: index out of bounds") );
408
409 return m_pchData[Len() - 1];
410 }
411
3c67202d 412 // get writable last character
2bb67b80 413 wxChar& Last()
09443a26
VZ
414 {
415 wxASSERT_MSG( !IsEmpty(), _T("wxString: index out of bounds") );
416 CopyBeforeWrite();
417 return m_pchData[Len()-1];
418 }
c801d85f 419
d836ee96
VZ
420 /*
421 So why do we have all these overloaded operator[]s? A bit of history:
422 initially there was only one of them, taking size_t. Then people
423 started complaining because they wanted to use ints as indices (I
424 wonder why) and compilers were giving warnings about it, so we had to
425 add the operator[](int). Then it became apparent that you couldn't
426 write str[0] any longer because there was ambiguity between two
427 overloads and so you now had to write str[0u] (or, of course, use the
428 explicit casts to either int or size_t but nobody did this).
429
430 Finally, someone decided to compile wxWin on an Alpha machine and got
431 a surprize: str[0u] didn't compile there because it is of type
432 unsigned int and size_t is unsigned _long_ on Alpha and so there was
433 ambiguity between converting uint to int or ulong. To fix this one we
434 now add operator[](uint) for the machines where size_t is not already
435 the same as unsigned int - hopefully this fixes the problem (for some
436 time)
437
438 The only real fix is, of course, to remove all versions but the one
439 taking size_t...
440 */
441
3c67202d 442 // operator version of GetChar
2bb67b80 443 wxChar operator[](size_t n) const
5737d05f 444 { wxASSERT_VALID_INDEX( n ); return m_pchData[n]; }
c5248639 445
3c67202d 446 // operator version of GetChar
2bb67b80 447 wxChar operator[](int n) const
5737d05f 448 { wxASSERT_VALID_INDEX( n ); return m_pchData[n]; }
cd0b1709 449
f83db661 450 // operator version of GetWriteableChar
2bb67b80 451 wxChar& operator[](size_t n)
5737d05f 452 { wxASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
d836ee96
VZ
453
454#ifndef wxSIZE_T_IS_UINT
455 // operator version of GetChar
456 wxChar operator[](unsigned int n) const
5737d05f 457 { wxASSERT_VALID_INDEX( n ); return m_pchData[n]; }
d836ee96 458
f83db661 459 // operator version of GetWriteableChar
d836ee96 460 wxChar& operator[](unsigned int n)
5737d05f 461 { wxASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
d836ee96 462#endif // size_t != unsigned int
c801d85f 463
3c67202d 464 // implicit conversion to C string
2bb67b80 465 operator const wxChar*() const { return m_pchData; }
e015c2a3 466
3c67202d 467 // explicit conversion to C string (use this with printf()!)
2bb67b80 468 const wxChar* c_str() const { return m_pchData; }
e015c2a3 469 // identical to c_str(), for wxWin 1.6x compatibility
6f841509 470 const wxChar* wx_str() const { return m_pchData; }
e015c2a3 471 // identical to c_str(), for MFC compatibility
2bb67b80 472 const wxChar* GetData() const { return m_pchData; }
e90c1d2a 473
e015c2a3
VZ
474 // conversion to/from plain (i.e. 7 bit) ASCII: this is useful for
475 // converting numbers or strings which are certain not to contain special
476 // chars (typically system functions, X atoms, environment variables etc.)
477 //
478 // the behaviour of these functions with the strings containing anything
479 // else than 7 bit ASCII characters is undefined, use at your own risk.
b1ac3b56 480#if wxUSE_UNICODE
2b5f62a0
VZ
481 static wxString FromAscii(const char *ascii); // string
482 static wxString FromAscii(const char ascii); // char
b1ac3b56 483 const wxCharBuffer ToAscii() const;
e015c2a3
VZ
484#else // ANSI
485 static wxString FromAscii(const char *ascii) { return wxString( ascii ); }
2b5f62a0 486 static wxString FromAscii(const char ascii) { return wxString( ascii ); }
e015c2a3
VZ
487 const char *ToAscii() const { return c_str(); }
488#endif // Unicode/!Unicode
b1ac3b56 489
2b5f62a0 490 // conversions with (possible) format conversions: have to return a
e90c1d2a 491 // buffer with temporary data
f6bcfd97
BP
492 //
493 // the functions defined (in either Unicode or ANSI) mode are mb_str() to
494 // return an ANSI (multibyte) string, wc_str() to return a wide string and
495 // fn_str() to return a string which should be used with the OS APIs
496 // accepting the file names. The return value is always the same, but the
497 // type differs because a function may either return pointer to the buffer
498 // directly or have to use intermediate buffer for translation.
2bb67b80 499#if wxUSE_UNICODE
f6bcfd97
BP
500 const wxCharBuffer mb_str(wxMBConv& conv = wxConvLibc) const
501 { return conv.cWC2MB(m_pchData); }
502
e90c1d2a
VZ
503 const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); }
504
f6bcfd97
BP
505 const wxChar* wc_str() const { return m_pchData; }
506
507 // for compatibility with !wxUSE_UNICODE version
508 const wxChar* wc_str(wxMBConv& WXUNUSED(conv)) const { return m_pchData; }
e90c1d2a 509
2bb67b80 510#if wxMBFILES
5f709e67 511 const wxCharBuffer fn_str() const { return mb_str(wxConvFile); }
e90c1d2a 512#else // !wxMBFILES
2bb67b80 513 const wxChar* fn_str() const { return m_pchData; }
e90c1d2a
VZ
514#endif // wxMBFILES/!wxMBFILES
515#else // ANSI
e90c1d2a 516 const wxChar* mb_str() const { return m_pchData; }
f6bcfd97
BP
517
518 // for compatibility with wxUSE_UNICODE version
519 const wxChar* mb_str(wxMBConv& WXUNUSED(conv)) const { return m_pchData; }
520
e90c1d2a 521 const wxWX2MBbuf mbc_str() const { return mb_str(); }
f6bcfd97 522
6f841509 523#if wxUSE_WCHAR_T
f6bcfd97
BP
524 const wxWCharBuffer wc_str(wxMBConv& conv) const
525 { return conv.cMB2WC(m_pchData); }
e90c1d2a 526#endif // wxUSE_WCHAR_T
f6bcfd97 527
2bb67b80 528 const wxChar* fn_str() const { return m_pchData; }
e90c1d2a 529#endif // Unicode/ANSI
c801d85f 530
3c67202d
VZ
531 // overloaded assignment
532 // from another wxString
c801d85f 533 wxString& operator=(const wxString& stringSrc);
3c67202d 534 // from a character
2bb67b80 535 wxString& operator=(wxChar ch);
3c67202d 536 // from a C string
2bb67b80 537 wxString& operator=(const wxChar *psz);
111bb7f2
OK
538#if wxUSE_UNICODE
539 // from wxWCharBuffer
b1801e0e
GD
540 wxString& operator=(const wxWCharBuffer& psz)
541 { (void) operator=((const wchar_t *)psz); return *this; }
e90c1d2a 542#else // ANSI
3c67202d 543 // from another kind of C string
c801d85f 544 wxString& operator=(const unsigned char* psz);
6f841509 545#if wxUSE_WCHAR_T
3c67202d 546 // from a wide string
c801d85f 547 wxString& operator=(const wchar_t *pwz);
6f841509 548#endif
111bb7f2 549 // from wxCharBuffer
b1801e0e
GD
550 wxString& operator=(const wxCharBuffer& psz)
551 { (void) operator=((const char *)psz); return *this; }
e90c1d2a 552#endif // Unicode/ANSI
3c67202d
VZ
553
554 // string concatenation
555 // in place concatenation
556 /*
557 Concatenate and return the result. Note that the left to right
558 associativity of << allows to write things like "str << str1 << str2
559 << ..." (unlike with +=)
560 */
561 // string += string
dd1eaa89
VZ
562 wxString& operator<<(const wxString& s)
563 {
09443a26
VZ
564 wxASSERT_MSG( s.GetStringData()->IsValid(),
565 _T("did you forget to call UngetWriteBuf()?") );
dd1eaa89
VZ
566
567 ConcatSelf(s.Len(), s);
568 return *this;
569 }
3c67202d 570 // string += C string
2bb67b80
OK
571 wxString& operator<<(const wxChar *psz)
572 { ConcatSelf(wxStrlen(psz), psz); return *this; }
3c67202d 573 // string += char
2bb67b80 574 wxString& operator<<(wxChar ch) { ConcatSelf(1, &ch); return *this; }
dd1eaa89 575
3c67202d 576 // string += string
6b95b20d 577 void operator+=(const wxString& s) { (void)operator<<(s); }
3c67202d 578 // string += C string
2bb67b80 579 void operator+=(const wxChar *psz) { (void)operator<<(psz); }
3c67202d 580 // string += char
2bb67b80
OK
581 void operator+=(wxChar ch) { (void)operator<<(ch); }
582
583 // string += buffer (i.e. from wxGetString)
584#if wxUSE_UNICODE
09443a26
VZ
585 wxString& operator<<(const wxWCharBuffer& s)
586 { (void)operator<<((const wchar_t *)s); return *this; }
587 void operator+=(const wxWCharBuffer& s)
588 { (void)operator<<((const wchar_t *)s); }
589#else // !wxUSE_UNICODE
590 wxString& operator<<(const wxCharBuffer& s)
591 { (void)operator<<((const char *)s); return *this; }
592 void operator+=(const wxCharBuffer& s)
593 { (void)operator<<((const char *)s); }
594#endif // wxUSE_UNICODE/!wxUSE_UNICODE
6b95b20d 595
3c67202d 596 // string += C string
09443a26
VZ
597 wxString& Append(const wxString& s)
598 {
599 // test for IsEmpty() to share the string if possible
600 if ( IsEmpty() )
601 *this = s;
602 else
603 ConcatSelf(s.Length(), s.c_str());
604 return *this;
605 }
2bb67b80
OK
606 wxString& Append(const wxChar* psz)
607 { ConcatSelf(wxStrlen(psz), psz); return *this; }
3c67202d 608 // append count copies of given character
2bb67b80 609 wxString& Append(wxChar ch, size_t count = 1u)
3c67202d 610 { wxString str(ch, count); return *this << str; }
8f06a017
RD
611 wxString& Append(const wxChar* psz, size_t nLen)
612 { ConcatSelf(nLen, psz); return *this; }
3c67202d
VZ
613
614 // prepend a string, return the string itself
615 wxString& Prepend(const wxString& str)
616 { *this = str + *this; return *this; }
617
618 // non-destructive concatenation
619 //
bddd7a8d 620 friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string1, const wxString& string2);
3c67202d 621 //
bddd7a8d 622 friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string, wxChar ch);
3c67202d 623 //
bddd7a8d 624 friend wxString WXDLLIMPEXP_BASE operator+(wxChar ch, const wxString& string);
3c67202d 625 //
bddd7a8d 626 friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string, const wxChar *psz);
3c67202d 627 //
bddd7a8d 628 friend wxString WXDLLIMPEXP_BASE operator+(const wxChar *psz, const wxString& string);
3c67202d
VZ
629
630 // stream-like functions
631 // insert an int into string
3ce65f6c
VZ
632 wxString& operator<<(int i)
633 { return (*this) << Format(_T("%d"), i); }
634 // insert an unsigned int into string
635 wxString& operator<<(unsigned int ui)
636 { return (*this) << Format(_T("%u"), ui); }
637 // insert a long into string
638 wxString& operator<<(long l)
639 { return (*this) << Format(_T("%ld"), l); }
640 // insert an unsigned long into string
641 wxString& operator<<(unsigned long ul)
642 { return (*this) << Format(_T("%lu"), ul); }
3c67202d 643 // insert a float into string
3ce65f6c
VZ
644 wxString& operator<<(float f)
645 { return (*this) << Format(_T("%f"), f); }
3c67202d 646 // insert a double into string
3ce65f6c
VZ
647 wxString& operator<<(double d)
648 { return (*this) << Format(_T("%g"), d); }
c84c52de 649
3c67202d 650 // string comparison
30b21f9a 651 // case-sensitive comparison (returns a value < 0, = 0 or > 0)
f33fee2a 652 int Cmp(const wxChar *psz) const { return wxStrcmp(c_str(), psz); }
3c67202d 653 // same as Cmp() but not case-sensitive
f33fee2a 654 int CmpNoCase(const wxChar *psz) const { return wxStricmp(c_str(), psz); }
3c67202d
VZ
655 // test for the string equality, either considering case or not
656 // (if compareWithCase then the case matters)
2bb67b80 657 bool IsSameAs(const wxChar *psz, bool compareWithCase = TRUE) const
3c67202d 658 { return (compareWithCase ? Cmp(psz) : CmpNoCase(psz)) == 0; }
f33fee2a
VZ
659 // comparison with a signle character: returns TRUE if equal
660 bool IsSameAs(wxChar c, bool compareWithCase = TRUE) const
661 {
662 return (Len() == 1) && (compareWithCase ? GetChar(0u) == c
663 : wxToupper(GetChar(0u)) == wxToupper(c));
664 }
3c67202d
VZ
665
666 // simple sub-string extraction
667 // return substring starting at nFirst of length nCount (or till the end
668 // if nCount = default value)
566b84d2 669 wxString Mid(size_t nFirst, size_t nCount = wxSTRING_MAXLEN) const;
3c67202d 670
f6bcfd97 671 // operator version of Mid()
3c67202d
VZ
672 wxString operator()(size_t start, size_t len) const
673 { return Mid(start, len); }
674
c0881dc3 675 // check that the string starts with prefix and return the rest of the
f6bcfd97
BP
676 // string in the provided pointer if it is not NULL, otherwise return
677 // FALSE
678 bool StartsWith(const wxChar *prefix, wxString *rest = NULL) const;
679
3c67202d 680 // get first nCount characters
c801d85f 681 wxString Left(size_t nCount) const;
3c67202d 682 // get last nCount characters
c801d85f 683 wxString Right(size_t nCount) const;
c0881dc3 684 // get all characters before the first occurance of ch
3c67202d 685 // (returns the whole string if ch not found)
2bb67b80 686 wxString BeforeFirst(wxChar ch) const;
3c67202d
VZ
687 // get all characters before the last occurence of ch
688 // (returns empty string if ch not found)
2bb67b80 689 wxString BeforeLast(wxChar ch) const;
3c67202d
VZ
690 // get all characters after the first occurence of ch
691 // (returns empty string if ch not found)
2bb67b80 692 wxString AfterFirst(wxChar ch) const;
3c67202d
VZ
693 // get all characters after the last occurence of ch
694 // (returns the whole string if ch not found)
2bb67b80 695 wxString AfterLast(wxChar ch) const;
3c67202d
VZ
696
697 // for compatibility only, use more explicitly named functions above
2bb67b80
OK
698 wxString Before(wxChar ch) const { return BeforeLast(ch); }
699 wxString After(wxChar ch) const { return AfterFirst(ch); }
3c67202d
VZ
700
701 // case conversion
c84c52de 702 // convert to upper case in place, return the string itself
c801d85f 703 wxString& MakeUpper();
c84c52de 704 // convert to upper case, return the copy of the string
03ab016d
JS
705 // Here's something to remember: BC++ doesn't like returns in inlines.
706 wxString Upper() const ;
c84c52de 707 // convert to lower case in place, return the string itself
c801d85f 708 wxString& MakeLower();
c84c52de 709 // convert to lower case, return the copy of the string
03ab016d 710 wxString Lower() const ;
c801d85f 711
3c67202d
VZ
712 // trimming/padding whitespace (either side) and truncating
713 // remove spaces from left or from right (default) side
c801d85f 714 wxString& Trim(bool bFromRight = TRUE);
3c67202d 715 // add nCount copies chPad in the beginning or at the end (default)
223d09f6 716 wxString& Pad(size_t nCount, wxChar chPad = wxT(' '), bool bFromRight = TRUE);
dd1eaa89 717
3c67202d
VZ
718 // searching and replacing
719 // searching (return starting index, or -1 if not found)
2bb67b80 720 int Find(wxChar ch, bool bFromEnd = FALSE) const; // like strchr/strrchr
3c67202d 721 // searching (return starting index, or -1 if not found)
2bb67b80 722 int Find(const wxChar *pszSub) const; // like strstr
3c67202d
VZ
723 // replace first (or all of bReplaceAll) occurences of substring with
724 // another string, returns the number of replacements made
2bb67b80
OK
725 size_t Replace(const wxChar *szOld,
726 const wxChar *szNew,
3c67202d
VZ
727 bool bReplaceAll = TRUE);
728
729 // check if the string contents matches a mask containing '*' and '?'
2bb67b80 730 bool Matches(const wxChar *szMask) const;
c801d85f 731
538f35cc
VZ
732 // conversion to numbers: all functions return TRUE only if the whole
733 // string is a number and put the value of this number into the pointer
734 // provided, the base is the numeric base in which the conversion should be
735 // done and must be comprised between 2 and 36 or be 0 in which case the
736 // standard C rules apply (leading '0' => octal, "0x" => hex)
cd0b1709 737 // convert to a signed integer
538f35cc 738 bool ToLong(long *val, int base = 10) const;
cd0b1709 739 // convert to an unsigned integer
538f35cc 740 bool ToULong(unsigned long *val, int base = 10) const;
cd0b1709
VZ
741 // convert to a double
742 bool ToDouble(double *val) const;
743
3c67202d
VZ
744 // formated input/output
745 // as sprintf(), returns the number of characters written or < 0 on error
7357f981
GD
746 // (take 'this' into account in attribute parameter count)
747 int Printf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2;
3c67202d 748 // as vprintf(), returns the number of characters written or < 0 on error
2bb67b80 749 int PrintfV(const wxChar* pszFormat, va_list argptr);
dd1eaa89 750
341e7d28 751 // returns the string containing the result of Printf() to it
7357f981 752 static wxString Format(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_1;
341e7d28
VZ
753 // the same as above, but takes a va_list
754 static wxString FormatV(const wxChar *pszFormat, va_list argptr);
755
3c67202d
VZ
756 // raw access to string memory
757 // ensure that string has space for at least nLen characters
dd1eaa89 758 // only works if the data of this string is not shared
b1801e0e 759 bool Alloc(size_t nLen);
3c67202d 760 // minimize the string's memory
dd1eaa89 761 // only works if the data of this string is not shared
b1801e0e 762 bool Shrink();
3c67202d
VZ
763 // get writable buffer of at least nLen bytes. Unget() *must* be called
764 // a.s.a.p. to put string back in a reasonable state!
2bb67b80 765 wxChar *GetWriteBuf(size_t nLen);
3c67202d 766 // call this immediately after GetWriteBuf() has been used
8fd0f20b 767 void UngetWriteBuf();
8f06a017 768 void UngetWriteBuf(size_t nLen);
c801d85f 769
3c67202d
VZ
770 // wxWindows version 1 compatibility functions
771
772 // use Mid()
773 wxString SubString(size_t from, size_t to) const
774 { return Mid(from, (to - from + 1)); }
775 // values for second parameter of CompareTo function
c801d85f 776 enum caseCompare {exact, ignoreCase};
3c67202d 777 // values for first parameter of Strip function
c801d85f 778 enum stripType {leading = 0x1, trailing = 0x2, both = 0x3};
8870c26e 779
7357f981
GD
780 // use Printf()
781 // (take 'this' into account in attribute parameter count)
782 int sprintf(const wxChar *pszFormat, ...) ATTRIBUTE_PRINTF_2;
c801d85f 783
3c67202d 784 // use Cmp()
2bb67b80 785 inline int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
6b95b20d 786 { return cmp == exact ? Cmp(psz) : CmpNoCase(psz); }
c801d85f 787
3c67202d 788 // use Len
c801d85f 789 size_t Length() const { return Len(); }
3c67202d 790 // Count the number of characters
2bb67b80 791 int Freq(wxChar ch) const;
3c67202d 792 // use MakeLower
c801d85f 793 void LowerCase() { MakeLower(); }
3c67202d 794 // use MakeUpper
c801d85f 795 void UpperCase() { MakeUpper(); }
3c67202d 796 // use Trim except that it doesn't change this string
c801d85f
KB
797 wxString Strip(stripType w = trailing) const;
798
3c67202d 799 // use Find (more general variants not yet supported)
2bb67b80
OK
800 size_t Index(const wxChar* psz) const { return Find(psz); }
801 size_t Index(wxChar ch) const { return Find(ch); }
3c67202d 802 // use Truncate
c801d85f 803 wxString& Remove(size_t pos) { return Truncate(pos); }
28a156b1 804 wxString& RemoveLast(size_t n = 1) { return Truncate(Len() - n); }
c801d85f 805
3ed358cb 806 wxString& Remove(size_t nStart, size_t nLen) { return erase( nStart, nLen ); }
dd1eaa89 807
3c67202d 808 // use Find()
2bb67b80
OK
809 int First( const wxChar ch ) const { return Find(ch); }
810 int First( const wxChar* psz ) const { return Find(psz); }
3ed358cb 811 int First( const wxString &str ) const { return Find(str); }
2bb67b80 812 int Last( const wxChar ch ) const { return Find(ch, TRUE); }
3c67202d 813 bool Contains(const wxString& str) const { return Find(str) != -1; }
c801d85f 814
3c67202d 815 // use IsEmpty()
c801d85f 816 bool IsNull() const { return IsEmpty(); }
c801d85f 817
3c67202d
VZ
818#ifdef wxSTD_STRING_COMPATIBILITY
819 // std::string compatibility functions
dd1eaa89 820
2bc07607
VZ
821 // standard types
822 typedef wxChar value_type;
5460b9e3
VZ
823 typedef size_t size_type;
824 typedef value_type *iterator;
2bc07607
VZ
825 typedef const value_type *const_iterator;
826
3c67202d 827 // an 'invalid' value for string index
c801d85f 828 static const size_t npos;
dd1eaa89 829
3c67202d
VZ
830 // constructors
831 // take nLen chars starting at nPos
832 wxString(const wxString& str, size_t nPos, size_t nLen)
b1801e0e 833 : m_pchData(NULL)
3c67202d 834 {
09443a26
VZ
835 wxASSERT_MSG( str.GetStringData()->IsValid(),
836 _T("did you forget to call UngetWriteBuf()?") );
837
3c67202d
VZ
838 InitWith(str.c_str(), nPos, nLen == npos ? 0 : nLen);
839 }
840 // take all characters from pStart to pEnd
841 wxString(const void *pStart, const void *pEnd);
842
843 // lib.string.capacity
844 // return the length of the string
845 size_t size() const { return Len(); }
846 // return the length of the string
847 size_t length() const { return Len(); }
848 // return the maximum size of the string
566b84d2 849 size_t max_size() const { return wxSTRING_MAXLEN; }
3c67202d 850 // resize the string, filling the space with c if c != 0
223d09f6 851 void resize(size_t nSize, wxChar ch = wxT('\0'));
3c67202d
VZ
852 // delete the contents of the string
853 void clear() { Empty(); }
854 // returns true if the string is empty
855 bool empty() const { return IsEmpty(); }
252a752e 856 // inform string about planned change in size
2b5f62a0 857 void reserve(size_t sz) { Alloc(sz); }
3c67202d
VZ
858
859 // lib.string.access
860 // return the character at position n
2bb67b80 861 wxChar at(size_t n) const { return GetChar(n); }
3c67202d 862 // returns the writable character at position n
2bb67b80 863 wxChar& at(size_t n) { return GetWritableChar(n); }
3c67202d 864
2bc07607
VZ
865 // first valid index position
866 const_iterator begin() const { return wx_str(); }
867 // position one after the last valid one
868 const_iterator end() const { return wx_str() + length(); }
869
5460b9e3
VZ
870 // first valid index position
871 iterator begin() { CopyBeforeWrite(); return m_pchData; }
872 // position one after the last valid one
873 iterator end() { CopyBeforeWrite(); return m_pchData + length(); }
874
3c67202d
VZ
875 // lib.string.modifiers
876 // append a string
877 wxString& append(const wxString& str)
878 { *this += str; return *this; }
879 // append elements str[pos], ..., str[pos+n]
880 wxString& append(const wxString& str, size_t pos, size_t n)
881 { ConcatSelf(n, str.c_str() + pos); return *this; }
882 // append first n (or all if n == npos) characters of sz
2bb67b80
OK
883 wxString& append(const wxChar *sz, size_t n = npos)
884 { ConcatSelf(n == npos ? wxStrlen(sz) : n, sz); return *this; }
3c67202d
VZ
885
886 // append n copies of ch
2bb67b80 887 wxString& append(size_t n, wxChar ch) { return Pad(n, ch); }
3c67202d
VZ
888
889 // same as `this_string = str'
735d1db6
VZ
890 wxString& assign(const wxString& str)
891 { return *this = str; }
3c67202d
VZ
892 // same as ` = str[pos..pos + n]
893 wxString& assign(const wxString& str, size_t pos, size_t n)
735d1db6 894 { Empty(); return Append(str.c_str() + pos, n); }
3c67202d 895 // same as `= first n (or all if n == npos) characters of sz'
2bb67b80 896 wxString& assign(const wxChar *sz, size_t n = npos)
735d1db6 897 { Empty(); return Append(sz, n == npos ? wxStrlen(sz) : n); }
3c67202d 898 // same as `= n copies of ch'
2bb67b80 899 wxString& assign(size_t n, wxChar ch)
735d1db6 900 { Empty(); return Append(ch, n); }
3c67202d
VZ
901
902 // insert another string
903 wxString& insert(size_t nPos, const wxString& str);
904 // insert n chars of str starting at nStart (in str)
905 wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
2bb67b80 906 { return insert(nPos, wxString((const wxChar *)str + nStart, n)); }
3c67202d
VZ
907
908 // insert first n (or all if n == npos) characters of sz
2bb67b80 909 wxString& insert(size_t nPos, const wxChar *sz, size_t n = npos)
3c67202d
VZ
910 { return insert(nPos, wxString(sz, n)); }
911 // insert n copies of ch
2bb67b80 912 wxString& insert(size_t nPos, size_t n, wxChar ch)
3c67202d
VZ
913 { return insert(nPos, wxString(ch, n)); }
914
915 // delete characters from nStart to nStart + nLen
916 wxString& erase(size_t nStart = 0, size_t nLen = npos);
917
918 // replaces the substring of length nLen starting at nStart
2bb67b80 919 wxString& replace(size_t nStart, size_t nLen, const wxChar* sz);
3c67202d 920 // replaces the substring with nCount copies of ch
2bb67b80 921 wxString& replace(size_t nStart, size_t nLen, size_t nCount, wxChar ch);
3c67202d
VZ
922 // replaces a substring with another substring
923 wxString& replace(size_t nStart, size_t nLen,
924 const wxString& str, size_t nStart2, size_t nLen2);
925 // replaces the substring with first nCount chars of sz
fb20fa43
VZ
926 wxString& replace(size_t nStart, size_t nLen,
927 const wxChar* sz, size_t nCount);
3c67202d
VZ
928
929 // swap two strings
930 void swap(wxString& str);
931
932 // All find() functions take the nStart argument which specifies the
933 // position to start the search on, the default value is 0. All functions
934 // return npos if there were no match.
935
936 // find a substring
937 size_t find(const wxString& str, size_t nStart = 0) const;
938
939 // VC++ 1.5 can't cope with this syntax.
3f4a0c5b 940#if !defined(__VISUALC__) || defined(__WIN32__)
3c67202d 941 // find first n characters of sz
2bb67b80 942 size_t find(const wxChar* sz, size_t nStart = 0, size_t n = npos) const;
fb20fa43 943#endif // VC++ 1.5
3c67202d
VZ
944
945 // Gives a duplicate symbol (presumably a case-insensitivity problem)
62448488 946#if !defined(__BORLANDC__)
3c67202d 947 // find the first occurence of character ch after nStart
2bb67b80 948 size_t find(wxChar ch, size_t nStart = 0) const;
62448488 949#endif
3c67202d
VZ
950 // rfind() family is exactly like find() but works right to left
951
952 // as find, but from the end
953 size_t rfind(const wxString& str, size_t nStart = npos) const;
954
955 // VC++ 1.5 can't cope with this syntax.
3f4a0c5b 956#if !defined(__VISUALC__) || defined(__WIN32__)
3c67202d 957 // as find, but from the end
2bb67b80 958 size_t rfind(const wxChar* sz, size_t nStart = npos,
3c67202d
VZ
959 size_t n = npos) const;
960 // as find, but from the end
2bb67b80 961 size_t rfind(wxChar ch, size_t nStart = npos) const;
fb20fa43 962#endif // VC++ 1.5
3c67202d
VZ
963
964 // find first/last occurence of any character in the set
965
969d318c
VZ
966 // as strpbrk() but starts at nStart, returns npos if not found
967 size_t find_first_of(const wxString& str, size_t nStart = 0) const
968 { return find_first_of(str.c_str(), nStart); }
969 // same as above
2bb67b80 970 size_t find_first_of(const wxChar* sz, size_t nStart = 0) const;
3c67202d 971 // same as find(char, size_t)
969d318c
VZ
972 size_t find_first_of(wxChar c, size_t nStart = 0) const
973 { return find(c, nStart); }
974 // find the last (starting from nStart) char from str in this string
975 size_t find_last_of (const wxString& str, size_t nStart = npos) const
976 { return find_last_of(str.c_str(), nStart); }
977 // same as above
978 size_t find_last_of (const wxChar* sz, size_t nStart = npos) const;
979 // same as above
980 size_t find_last_of(wxChar c, size_t nStart = npos) const
981 { return rfind(c, nStart); }
3c67202d
VZ
982
983 // find first/last occurence of any character not in the set
984
969d318c
VZ
985 // as strspn() (starting from nStart), returns npos on failure
986 size_t find_first_not_of(const wxString& str, size_t nStart = 0) const
987 { return find_first_not_of(str.c_str(), nStart); }
988 // same as above
989 size_t find_first_not_of(const wxChar* sz, size_t nStart = 0) const;
990 // same as above
2bb67b80 991 size_t find_first_not_of(wxChar ch, size_t nStart = 0) const;
969d318c 992 // as strcspn()
fb20fa43
VZ
993 size_t find_last_not_of(const wxString& str, size_t nStart = npos) const
994 { return find_first_not_of(str.c_str(), nStart); }
969d318c
VZ
995 // same as above
996 size_t find_last_not_of(const wxChar* sz, size_t nStart = npos) const;
997 // same as above
2bb67b80 998 size_t find_last_not_of(wxChar ch, size_t nStart = npos) const;
3c67202d
VZ
999
1000 // All compare functions return -1, 0 or 1 if the [sub]string is less,
1001 // equal or greater than the compare() argument.
1002
1003 // just like strcmp()
1004 int compare(const wxString& str) const { return Cmp(str); }
1005 // comparison with a substring
fb20fa43
VZ
1006 int compare(size_t nStart, size_t nLen, const wxString& str) const
1007 { return Mid(nStart, nLen).Cmp(str); }
3c67202d
VZ
1008 // comparison of 2 substrings
1009 int compare(size_t nStart, size_t nLen,
fb20fa43
VZ
1010 const wxString& str, size_t nStart2, size_t nLen2) const
1011 { return Mid(nStart, nLen).Cmp(str.Mid(nStart2, nLen2)); }
3c67202d 1012 // just like strcmp()
2bb67b80 1013 int compare(const wxChar* sz) const { return Cmp(sz); }
3c67202d
VZ
1014 // substring comparison with first nCount characters of sz
1015 int compare(size_t nStart, size_t nLen,
fb20fa43
VZ
1016 const wxChar* sz, size_t nCount = npos) const
1017 { return Mid(nStart, nLen).Cmp(wxString(sz, nCount)); }
3c67202d
VZ
1018
1019 // substring extraction
8c264b23
VZ
1020 wxString substr(size_t nStart = 0, size_t nLen = npos) const
1021 { return Mid(nStart, nLen); }
3c67202d 1022#endif // wxSTD_STRING_COMPATIBILITY
c801d85f
KB
1023};
1024
df5168c4
MB
1025// define wxArrayString, for compatibility
1026#if WXWIN_COMPATIBILITY_2_4 && !wxUSE_STL
1027 #include "wx/arrstr.h"
ba8c1601 1028#endif
9d155f50 1029
1d218550
VZ
1030// ----------------------------------------------------------------------------
1031// wxStringBuffer: a tiny class allowing to get a writable pointer into string
1032// ----------------------------------------------------------------------------
1033
941b78cc
MB
1034#if wxUSE_STL
1035
1036class WXDLLIMPEXP_BASE wxStringBuffer
1037{
1038public:
1039 wxStringBuffer(wxString& str, size_t lenWanted = 1024)
1040 : m_str(str), m_buf(lenWanted), m_len(lenWanted)
1041 { }
1042
fe5fc682 1043 ~wxStringBuffer() { m_str.assign(m_buf.data(), wxStrlen(m_buf.data())); }
941b78cc
MB
1044
1045 operator wxChar*() { return m_buf.data(); }
1046
1047private:
1048 wxString& m_str;
1049#if wxUSE_UNICODE
1050 wxWCharBuffer m_buf;
1051#else
1052 wxCharBuffer m_buf;
1053#endif
1054 size_t m_len;
1055
1056 DECLARE_NO_COPY_CLASS(wxStringBuffer)
1057};
1058
1059class WXDLLIMPEXP_BASE wxStringBufferLength
1060{
1061public:
1062 wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
1063 : m_str(str), m_buf(lenWanted), m_len(0), m_lenSet(false)
1064 { }
1065
1066 ~wxStringBufferLength()
1067 {
1068 wxASSERT(m_lenSet);
1069 m_str.assign(m_buf.data(), m_len);
1070 }
1071
1072 operator wxChar*() { return m_buf.data(); }
1073 void SetLength(size_t length) { m_len = length; m_lenSet = true; }
1074
1075private:
1076 wxString& m_str;
1077#if wxUSE_UNICODE
1078 wxWCharBuffer m_buf;
1079#else
1080 wxCharBuffer m_buf;
1081#endif
1082 size_t m_len;
1083 bool m_lenSet;
1084
1085 DECLARE_NO_COPY_CLASS(wxStringBufferLength)
1086};
1087
1088#else // if !wxUSE_STL
1089
bddd7a8d 1090class WXDLLIMPEXP_BASE wxStringBuffer
1d218550
VZ
1091{
1092public:
1093 wxStringBuffer(wxString& str, size_t lenWanted = 1024)
b1801e0e
GD
1094 : m_str(str), m_buf(NULL)
1095 { m_buf = m_str.GetWriteBuf(lenWanted); }
e015c2a3 1096
1d218550 1097 ~wxStringBuffer() { m_str.UngetWriteBuf(); }
e015c2a3 1098
1d218550 1099 operator wxChar*() const { return m_buf; }
e015c2a3 1100
1d218550
VZ
1101private:
1102 wxString& m_str;
1103 wxChar *m_buf;
e015c2a3
VZ
1104
1105 DECLARE_NO_COPY_CLASS(wxStringBuffer)
1d218550
VZ
1106};
1107
941b78cc
MB
1108class WXDLLIMPEXP_BASE wxStringBufferLength
1109{
1110public:
1111 wxStringBufferLength(wxString& str, size_t lenWanted = 1024)
1112 : m_str(str), m_buf(NULL), m_len(0), m_lenSet(false)
1113 { m_buf = m_str.GetWriteBuf(lenWanted); }
1114
1115 ~wxStringBufferLength()
1116 {
1117 wxASSERT(m_lenSet);
1118 m_str.UngetWriteBuf(m_len);
1119 }
1120
1121 operator wxChar*() const { return m_buf; }
1122 void SetLength(size_t length) { m_len = length; m_lenSet = true; }
1123
1124private:
1125 wxString& m_str;
1126 wxChar *m_buf;
1127 size_t m_len;
1128 bool m_lenSet;
1129
1130 DECLARE_NO_COPY_CLASS(wxStringBufferLength)
1131};
1132
1133#endif // !wxUSE_STL
1134
c801d85f 1135// ---------------------------------------------------------------------------
3c67202d 1136// wxString comparison functions: operator versions are always case sensitive
c801d85f 1137// ---------------------------------------------------------------------------
f33fee2a 1138
0cbe5ee3
VZ
1139inline bool operator==(const wxString& s1, const wxString& s2)
1140 { return (s1.Len() == s2.Len()) && (s1.Cmp(s2) == 0); }
1141inline bool operator==(const wxString& s1, const wxChar * s2)
1142 { return s1.Cmp(s2) == 0; }
1143inline bool operator==(const wxChar * s1, const wxString& s2)
1144 { return s2.Cmp(s1) == 0; }
1145inline bool operator!=(const wxString& s1, const wxString& s2)
1146 { return (s1.Len() != s2.Len()) || (s1.Cmp(s2) != 0); }
1147inline bool operator!=(const wxString& s1, const wxChar * s2)
1148 { return s1.Cmp(s2) != 0; }
1149inline bool operator!=(const wxChar * s1, const wxString& s2)
1150 { return s2.Cmp(s1) != 0; }
1151inline bool operator< (const wxString& s1, const wxString& s2)
1152 { return s1.Cmp(s2) < 0; }
1153inline bool operator< (const wxString& s1, const wxChar * s2)
1154 { return s1.Cmp(s2) < 0; }
1155inline bool operator< (const wxChar * s1, const wxString& s2)
1156 { return s2.Cmp(s1) > 0; }
1157inline bool operator> (const wxString& s1, const wxString& s2)
1158 { return s1.Cmp(s2) > 0; }
1159inline bool operator> (const wxString& s1, const wxChar * s2)
1160 { return s1.Cmp(s2) > 0; }
1161inline bool operator> (const wxChar * s1, const wxString& s2)
1162 { return s2.Cmp(s1) < 0; }
1163inline bool operator<=(const wxString& s1, const wxString& s2)
1164 { return s1.Cmp(s2) <= 0; }
1165inline bool operator<=(const wxString& s1, const wxChar * s2)
1166 { return s1.Cmp(s2) <= 0; }
1167inline bool operator<=(const wxChar * s1, const wxString& s2)
1168 { return s2.Cmp(s1) >= 0; }
1169inline bool operator>=(const wxString& s1, const wxString& s2)
1170 { return s1.Cmp(s2) >= 0; }
1171inline bool operator>=(const wxString& s1, const wxChar * s2)
1172 { return s1.Cmp(s2) >= 0; }
1173inline bool operator>=(const wxChar * s1, const wxString& s2)
1174 { return s2.Cmp(s1) <= 0; }
3c67202d 1175
f33fee2a
VZ
1176// comparison with char
1177inline bool operator==(wxChar c, const wxString& s) { return s.IsSameAs(c); }
1178inline bool operator==(const wxString& s, wxChar c) { return s.IsSameAs(c); }
1179inline bool operator!=(wxChar c, const wxString& s) { return !s.IsSameAs(c); }
1180inline bool operator!=(const wxString& s, wxChar c) { return !s.IsSameAs(c); }
1181
5ca07d0f
OK
1182#if wxUSE_UNICODE
1183inline bool operator==(const wxString& s1, const wxWCharBuffer& s2)
f33fee2a 1184 { return (s1.Cmp((const wchar_t *)s2) == 0); }
5ca07d0f 1185inline bool operator==(const wxWCharBuffer& s1, const wxString& s2)
f33fee2a 1186 { return (s2.Cmp((const wchar_t *)s1) == 0); }
f6bcfd97
BP
1187inline bool operator!=(const wxString& s1, const wxWCharBuffer& s2)
1188 { return (s1.Cmp((const wchar_t *)s2) != 0); }
1189inline bool operator!=(const wxWCharBuffer& s1, const wxString& s2)
1190 { return (s2.Cmp((const wchar_t *)s1) != 0); }
0cbe5ee3 1191#else // !wxUSE_UNICODE
5ca07d0f 1192inline bool operator==(const wxString& s1, const wxCharBuffer& s2)
f33fee2a 1193 { return (s1.Cmp((const char *)s2) == 0); }
5ca07d0f 1194inline bool operator==(const wxCharBuffer& s1, const wxString& s2)
f33fee2a 1195 { return (s2.Cmp((const char *)s1) == 0); }
f6bcfd97
BP
1196inline bool operator!=(const wxString& s1, const wxCharBuffer& s2)
1197 { return (s1.Cmp((const char *)s2) != 0); }
1198inline bool operator!=(const wxCharBuffer& s1, const wxString& s2)
1199 { return (s2.Cmp((const char *)s1) != 0); }
0cbe5ee3 1200#endif // wxUSE_UNICODE/!wxUSE_UNICODE
5ca07d0f 1201
bddd7a8d
VZ
1202wxString WXDLLIMPEXP_BASE operator+(const wxString& string1, const wxString& string2);
1203wxString WXDLLIMPEXP_BASE operator+(const wxString& string, wxChar ch);
1204wxString WXDLLIMPEXP_BASE operator+(wxChar ch, const wxString& string);
1205wxString WXDLLIMPEXP_BASE operator+(const wxString& string, const wxChar *psz);
1206wxString WXDLLIMPEXP_BASE operator+(const wxChar *psz, const wxString& string);
028a2b5d 1207#if wxUSE_UNICODE
6d56eb5c 1208inline wxString operator+(const wxString& string, const wxWCharBuffer& buf)
e90c1d2a 1209 { return string + (const wchar_t *)buf; }
6d56eb5c 1210inline wxString operator+(const wxWCharBuffer& buf, const wxString& string)
e90c1d2a 1211 { return (const wchar_t *)buf + string; }
0cbe5ee3 1212#else // !wxUSE_UNICODE
6d56eb5c 1213inline wxString operator+(const wxString& string, const wxCharBuffer& buf)
e90c1d2a 1214 { return string + (const char *)buf; }
6d56eb5c 1215inline wxString operator+(const wxCharBuffer& buf, const wxString& string)
e90c1d2a 1216 { return (const char *)buf + string; }
0cbe5ee3 1217#endif // wxUSE_UNICODE/!wxUSE_UNICODE
f04f3991 1218
c801d85f 1219// ---------------------------------------------------------------------------
3c67202d 1220// Implementation only from here until the end of file
c801d85f
KB
1221// ---------------------------------------------------------------------------
1222
e90c1d2a 1223// don't pollute the library user's name space
5737d05f 1224#undef wxASSERT_VALID_INDEX
e90c1d2a 1225
38830220 1226#if defined(wxSTD_STRING_COMPATIBILITY) && wxUSE_STD_IOSTREAM
c801d85f 1227
65f19af1 1228#include "wx/iosfwrap.h"
c801d85f 1229
bddd7a8d
VZ
1230WXDLLIMPEXP_BASE wxSTD istream& operator>>(wxSTD istream&, wxString&);
1231WXDLLIMPEXP_BASE wxSTD ostream& operator<<(wxSTD ostream&, const wxString&);
c801d85f 1232
3c67202d 1233#endif // wxSTD_STRING_COMPATIBILITY
c801d85f 1234
34138703 1235#endif // _WX_WXSTRINGH__