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