]> git.saurik.com Git - wxWidgets.git/blob - include/wx/string.h
bbcd039ea3392483e7bde30f3521dde58a5f0500
[wxWidgets.git] / include / wx / string.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: string.h
3 // Purpose: wxString and wxArrayString classes
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>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_WXSTRINGH__
13 #define _WX_WXSTRINGH__
14
15 #ifdef __GNUG__
16 #pragma interface "string.h"
17 #endif
18
19 #ifdef __WXMAC__
20 #include <ctype.h>
21 #endif
22
23 #include <string.h>
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <limits.h>
27 #include <stdlib.h>
28
29 #ifdef HAVE_STRINGS_H
30 #include <strings.h> // for strcasecmp()
31 #endif // AIX
32
33 #ifndef WX_PRECOMP
34 #include "wx/defs.h"
35
36 #ifdef WXSTRING_IS_WXOBJECT
37 #include "wx/object.h"
38 #endif
39 #endif // !PCH
40
41 #include "wx/debug.h"
42 #include "wx/wxchar.h"
43 #include "wx/buffer.h"
44
45 /*
46 Efficient string class [more or less] compatible with MFC CString,
47 wxWindows version 1 wxString and std::string and some handy functions
48 missing from string.h.
49 */
50
51 // ---------------------------------------------------------------------------
52 // macros
53 // ---------------------------------------------------------------------------
54
55 // compile the std::string compatibility functions if defined
56 #define wxSTD_STRING_COMPATIBILITY
57
58 // define to derive wxString from wxObject
59 #ifdef WXSTRING_IS_WXOBJECT
60 #undef WXSTRING_IS_WXOBJECT
61 #endif
62
63 // maximum possible length for a string means "take all string" everywhere
64 // (as sizeof(StringData) is unknown here we substract 100)
65 const unsigned int wxSTRING_MAXLEN = UINT_MAX - 100;
66
67 // 'naughty' cast
68 #define WXSTRINGCAST (wxChar *)(const wxChar *)
69 #define MBSTRINGCAST (char *)(const char *)
70 #define WCSTRINGCAST (wchar_t *)(const wchar_t *)
71
72 // implementation only
73 #define ASSERT_VALID_INDEX(i) wxASSERT( (unsigned)(i) <= Len() )
74
75 // ---------------------------------------------------------------------------
76 // Global functions complementing standard C string library replacements for
77 // strlen() and portable strcasecmp()
78 //---------------------------------------------------------------------------
79 // USE wx* FUNCTIONS IN wx/wxchar.h INSTEAD - THIS IS ONLY FOR BINARY COMPATIBILITY
80
81 // checks whether the passed in pointer is NULL and if the string is empty
82 inline bool WXDLLEXPORT IsEmpty(const char *p) { return (!p || !*p); }
83
84 // safe version of strlen() (returns 0 if passed NULL pointer)
85 inline size_t WXDLLEXPORT Strlen(const char *psz)
86 { return psz ? strlen(psz) : 0; }
87
88 // portable strcasecmp/_stricmp
89 inline int WXDLLEXPORT Stricmp(const char *psz1, const char *psz2)
90 {
91 #if defined(__VISUALC__) || ( defined(__MWERKS__) && defined(__INTEL__) )
92 return _stricmp(psz1, psz2);
93 #elif defined(__SC__)
94 return _stricmp(psz1, psz2);
95 #elif defined(__SALFORDC__)
96 return stricmp(psz1, psz2);
97 #elif defined(__BORLANDC__)
98 return stricmp(psz1, psz2);
99 #elif defined(__WATCOMC__)
100 return stricmp(psz1, psz2);
101 #elif defined(__UNIX__) || defined(__GNUWIN32__)
102 return strcasecmp(psz1, psz2);
103 #elif defined(__MWERKS__) && !defined(__INTEL__)
104 register char c1, c2;
105 do {
106 c1 = tolower(*psz1++);
107 c2 = tolower(*psz2++);
108 } while ( c1 && (c1 == c2) );
109
110 return c1 - c2;
111 #else
112 // almost all compilers/libraries provide this function (unfortunately under
113 // different names), that's why we don't implement our own which will surely
114 // be more efficient than this code (uncomment to use):
115 /*
116 register char c1, c2;
117 do {
118 c1 = tolower(*psz1++);
119 c2 = tolower(*psz2++);
120 } while ( c1 && (c1 == c2) );
121
122 return c1 - c2;
123 */
124
125 #error "Please define string case-insensitive compare for your OS/compiler"
126 #endif // OS/compiler
127 }
128
129 // ----------------------------------------------------------------------------
130 // global data
131 // ----------------------------------------------------------------------------
132
133 WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString;
134
135 // global pointer to empty string
136 WXDLLEXPORT_DATA(extern const wxChar*) g_szNul;
137
138 // return an empty wxString
139 class WXDLLEXPORT wxString; // not yet defined
140 inline const wxString& wxGetEmptyString() { return *(wxString *)&g_szNul; }
141
142 // ---------------------------------------------------------------------------
143 // string data prepended with some housekeeping info (used by wxString class),
144 // is never used directly (but had to be put here to allow inlining)
145 // ---------------------------------------------------------------------------
146 struct WXDLLEXPORT wxStringData
147 {
148 int nRefs; // reference count
149 size_t nDataLength, // actual string length
150 nAllocLength; // allocated memory size
151
152 // mimics declaration 'wxChar data[nAllocLength]'
153 wxChar* data() const { return (wxChar*)(this + 1); }
154
155 // empty string has a special ref count so it's never deleted
156 bool IsEmpty() const { return (nRefs == -1); }
157 bool IsShared() const { return (nRefs > 1); }
158
159 // lock/unlock
160 void Lock() { if ( !IsEmpty() ) nRefs++; }
161 void Unlock() { if ( !IsEmpty() && --nRefs == 0) free(this); }
162
163 // if we had taken control over string memory (GetWriteBuf), it's
164 // intentionally put in invalid state
165 void Validate(bool b) { nRefs = (b ? 1 : 0); }
166 bool IsValid() const { return (nRefs != 0); }
167 };
168
169 // ---------------------------------------------------------------------------
170 // types of multibyte<->Unicode conversions
171 // ---------------------------------------------------------------------------
172 class WXDLLEXPORT wxMBConv
173 {
174 public:
175 virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const;
176 virtual size_t WC2MB(char *buf, const wchar_t *psz, size_t n) const;
177 const wxWCharBuffer cMB2WC(const char *psz) const
178 {
179 size_t nLen = MB2WC((wchar_t *) NULL, psz, 0);
180 wxWCharBuffer buf(nLen);
181 MB2WC(WCSTRINGCAST buf, psz, nLen);
182 return buf;
183 }
184 const wxCharBuffer cWC2MB(const wchar_t *psz) const
185 {
186 size_t nLen = WC2MB((char *) NULL, psz, 0);
187 wxCharBuffer buf(nLen);
188 WC2MB(MBSTRINGCAST buf, psz, nLen);
189 return buf;
190 }
191 #if wxUSE_UNICODE
192 const wxWCharBuffer cMB2WX(const char *psz) const { return cMB2WC(psz); }
193 const wxCharBuffer cWX2MB(const wchar_t *psz) const { return cWC2MB(psz); }
194 const wchar_t* cWC2WX(const wchar_t *psz) const { return psz; }
195 const wchar_t* cMB2WC(const wchar_t *psz) const { return psz; }
196 #else
197 const char* cMB2WX(const char *psz) const { return psz; }
198 const char* cWX2MB(const char *psz) const { return psz; }
199 const wxCharBuffer cWC2WX(const wchar_t *psz) const { return cWC2MB(psz); }
200 const wxWCharBuffer cWX2WC(const char *psz) const { return cMB2WC(psz); }
201 #endif
202 };
203 WXDLLEXPORT_DATA(extern wxMBConv) wxConv_libc;
204
205 #define wxANOTHER_MBCONV(type) \
206 class type : public wxMBConv { \
207 public: \
208 virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const; \
209 virtual size_t WC2MB(char *buf, const wchar_t *psz, size_t n) const; \
210 }
211
212 WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConv_file)) wxConv_file;
213 WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConv_UTF7)) wxConv_UTF7;
214 WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConv_UTF8)) wxConv_UTF8;
215 #ifdef __WXGTK__
216 WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConv_gdk)) wxConv_gdk;
217 #endif
218
219 class WXDLLEXPORT wxCSConv : public wxMBConv
220 {
221 private:
222 wxChar *data;
223 public:
224 wxCSConv(const wxChar *charset);
225 virtual ~wxCSConv(void);
226 virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const;
227 virtual size_t WC2MB(char *buf, const wchar_t *psz, size_t n) const;
228 };
229
230 // filenames are multibyte on Unix and probably widechar on Windows?
231 #ifdef __UNIX__
232 #define wxMBFILES 1
233 #else
234 #define wxMBFILES 0
235 #endif
236
237 #if wxMBFILES
238 #define wxFNCONV(name) wxConv_file.cWX2MB(name)
239 #define FNSTRINGCAST MBSTRINGCAST
240 #else
241 #define wxFNCONV(name) name
242 #define FNSTRINGCAST WXSTRINGCAST
243 #endif
244
245 // ---------------------------------------------------------------------------
246 // This is (yet another one) String class for C++ programmers. It doesn't use
247 // any of "advanced" C++ features (i.e. templates, exceptions, namespaces...)
248 // thus you should be able to compile it with practicaly any C++ compiler.
249 // This class uses copy-on-write technique, i.e. identical strings share the
250 // same memory as long as neither of them is changed.
251 //
252 // This class aims to be as compatible as possible with the new standard
253 // std::string class, but adds some additional functions and should be at
254 // least as efficient than the standard implementation.
255 //
256 // Performance note: it's more efficient to write functions which take "const
257 // String&" arguments than "const char *" if you assign the argument to
258 // another string.
259 //
260 // It was compiled and tested under Win32, Linux (libc 5 & 6), Solaris 5.5.
261 //
262 // To do:
263 // - ressource support (string tables in ressources)
264 // - more wide character (UNICODE) support
265 // - regular expressions support
266 // ---------------------------------------------------------------------------
267
268 #ifdef WXSTRING_IS_WXOBJECT
269 class WXDLLEXPORT wxString : public wxObject
270 {
271 DECLARE_DYNAMIC_CLASS(wxString)
272 #else //WXSTRING_IS_WXOBJECT
273 class WXDLLEXPORT wxString
274 {
275 #endif //WXSTRING_IS_WXOBJECT
276
277 friend class WXDLLEXPORT wxArrayString;
278
279 // NB: special care was taken in arranging the member functions in such order
280 // that all inline functions can be effectively inlined, verify that all
281 // performace critical functions are still inlined if you change order!
282 private:
283 // points to data preceded by wxStringData structure with ref count info
284 wxChar *m_pchData;
285
286 // accessor to string data
287 wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; }
288
289 // string (re)initialization functions
290 // initializes the string to the empty value (must be called only from
291 // ctors, use Reinit() otherwise)
292 void Init() { m_pchData = (wxChar *)g_szNul; }
293 // initializaes the string with (a part of) C-string
294 void InitWith(const wxChar *psz, size_t nPos = 0, size_t nLen = wxSTRING_MAXLEN);
295 // as Init, but also frees old data
296 void Reinit() { GetStringData()->Unlock(); Init(); }
297
298 // memory allocation
299 // allocates memory for string of lenght nLen
300 void AllocBuffer(size_t nLen);
301 // copies data to another string
302 void AllocCopy(wxString&, int, int) const;
303 // effectively copies data to string
304 void AssignCopy(size_t, const wxChar *);
305
306 // append a (sub)string
307 void ConcatSelf(int nLen, const wxChar *src);
308
309 // functions called before writing to the string: they copy it if there
310 // are other references to our data (should be the only owner when writing)
311 void CopyBeforeWrite();
312 void AllocBeforeWrite(size_t);
313
314 // this method is not implemented - there is _no_ conversion from int to
315 // string, you're doing something wrong if the compiler wants to call it!
316 //
317 // try `s << i' or `s.Printf("%d", i)' instead
318 wxString(int);
319 wxString(long);
320
321 public:
322 // constructors and destructor
323 // ctor for an empty string
324 wxString() { Init(); }
325 // copy ctor
326 wxString(const wxString& stringSrc)
327 {
328 wxASSERT( stringSrc.GetStringData()->IsValid() );
329
330 if ( stringSrc.IsEmpty() ) {
331 // nothing to do for an empty string
332 Init();
333 }
334 else {
335 m_pchData = stringSrc.m_pchData; // share same data
336 GetStringData()->Lock(); // => one more copy
337 }
338 }
339 // string containing nRepeat copies of ch
340 wxString(wxChar ch, size_t nRepeat = 1);
341 // ctor takes first nLength characters from C string
342 // (default value of wxSTRING_MAXLEN means take all the string)
343 wxString(const wxChar *psz, size_t nLength = wxSTRING_MAXLEN)
344 { InitWith(psz, 0, nLength); }
345 #if wxUSE_UNICODE
346 // from multibyte string
347 // (NB: nLength is right now number of Unicode characters, not
348 // characters in psz! So try not to use it yet!)
349 wxString(const char *psz, wxMBConv& conv = wxConv_libc, size_t nLength = wxSTRING_MAXLEN);
350 // from wxWCharBuffer (i.e. return from wxGetString)
351 wxString(const wxWCharBuffer& psz)
352 { InitWith(psz, 0, wxSTRING_MAXLEN); }
353 #else
354 // from C string (for compilers using unsigned char)
355 wxString(const unsigned char* psz, size_t nLength = wxSTRING_MAXLEN)
356 { InitWith((const char*)psz, 0, nLength); }
357 // from wide (Unicode) string
358 wxString(const wchar_t *pwz);
359 // from wxCharBuffer
360 wxString(const wxCharBuffer& psz)
361 { InitWith(psz, 0, wxSTRING_MAXLEN); }
362 #endif
363 // dtor is not virtual, this class must not be inherited from!
364 ~wxString() { GetStringData()->Unlock(); }
365
366 // generic attributes & operations
367 // as standard strlen()
368 size_t Len() const { return GetStringData()->nDataLength; }
369 // string contains any characters?
370 bool IsEmpty() const { return Len() == 0; }
371 // empty string is "FALSE", so !str will return TRUE
372 bool operator!() const { return IsEmpty(); }
373 // empty string contents
374 void Empty()
375 {
376 if ( !IsEmpty() )
377 Reinit();
378
379 // should be empty
380 wxASSERT( GetStringData()->nDataLength == 0 );
381 }
382 // empty the string and free memory
383 void Clear()
384 {
385 if ( !GetStringData()->IsEmpty() )
386 Reinit();
387
388 wxASSERT( GetStringData()->nDataLength == 0 ); // should be empty
389 wxASSERT( GetStringData()->nAllocLength == 0 ); // and not own any memory
390 }
391
392 // contents test
393 // Is an ascii value
394 bool IsAscii() const;
395 // Is a number
396 bool IsNumber() const;
397 // Is a word
398 bool IsWord() const;
399
400 // data access (all indexes are 0 based)
401 // read access
402 wxChar GetChar(size_t n) const
403 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
404 // read/write access
405 wxChar& GetWritableChar(size_t n)
406 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
407 // write access
408 void SetChar(size_t n, wxChar ch)
409 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); m_pchData[n] = ch; }
410
411 // get last character
412 wxChar Last() const
413 { wxASSERT( !IsEmpty() ); return m_pchData[Len() - 1]; }
414 // get writable last character
415 wxChar& Last()
416 { wxASSERT( !IsEmpty() ); CopyBeforeWrite(); return m_pchData[Len()-1]; }
417
418 // under Unix it is tested with configure, assume it works on other
419 // platforms (there might be overloading problems if size_t and int are
420 // the same type)
421 #if !defined(__UNIX__) || wxUSE_SIZE_T_STRING_OPERATOR
422 // operator version of GetChar
423 wxChar operator[](size_t n) const
424 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
425 #endif
426
427 // operator version of GetChar
428 wxChar operator[](int n) const
429 { ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
430 // operator version of GetWritableChar
431 wxChar& operator[](size_t n)
432 { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
433
434 // implicit conversion to C string
435 operator const wxChar*() const { return m_pchData; }
436 // explicit conversion to C string (use this with printf()!)
437 const wxChar* c_str() const { return m_pchData; }
438 //
439 const wxChar* GetData() const { return m_pchData; }
440 #if wxUSE_UNICODE
441 const wxCharBuffer mb_str(wxMBConv& conv = wxConv_libc) const { return conv.cWC2MB(m_pchData); }
442 const wxChar* wc_str(wxMBConv& WXUNUSED(conv) = wxConv_libc) const { return m_pchData; }
443 #if wxMBFILES
444 const wxCharBuffer fn_str() const { return mb_str(wxConv_file); }
445 #else
446 const wxChar* fn_str() const { return m_pchData; }
447 #endif
448 #else
449 const wxChar* mb_str(wxMBConv& WXUNUSED(conv) = wxConv_libc ) const { return m_pchData; }
450 const wxWCharBuffer wc_str(wxMBConv& conv) const { return conv.cMB2WC(m_pchData); }
451 const wxChar* fn_str() const { return m_pchData; }
452 #endif
453
454 // overloaded assignment
455 // from another wxString
456 wxString& operator=(const wxString& stringSrc);
457 // from a character
458 wxString& operator=(wxChar ch);
459 // from a C string
460 wxString& operator=(const wxChar *psz);
461 #if wxUSE_UNICODE
462 // from wxWCharBuffer
463 wxString& operator=(const wxWCharBuffer& psz) { return operator=((const wchar_t *)psz); }
464 #else
465 // from another kind of C string
466 wxString& operator=(const unsigned char* psz);
467 // from a wide string
468 wxString& operator=(const wchar_t *pwz);
469 // from wxCharBuffer
470 wxString& operator=(const wxCharBuffer& psz) { return operator=((const char *)psz); }
471 #endif
472
473 // string concatenation
474 // in place concatenation
475 /*
476 Concatenate and return the result. Note that the left to right
477 associativity of << allows to write things like "str << str1 << str2
478 << ..." (unlike with +=)
479 */
480 // string += string
481 wxString& operator<<(const wxString& s)
482 {
483 wxASSERT( s.GetStringData()->IsValid() );
484
485 ConcatSelf(s.Len(), s);
486 return *this;
487 }
488 // string += C string
489 wxString& operator<<(const wxChar *psz)
490 { ConcatSelf(wxStrlen(psz), psz); return *this; }
491 // string += char
492 wxString& operator<<(wxChar ch) { ConcatSelf(1, &ch); return *this; }
493
494 // string += string
495 void operator+=(const wxString& s) { (void)operator<<(s); }
496 // string += C string
497 void operator+=(const wxChar *psz) { (void)operator<<(psz); }
498 // string += char
499 void operator+=(wxChar ch) { (void)operator<<(ch); }
500
501 // string += buffer (i.e. from wxGetString)
502 #if wxUSE_UNICODE
503 wxString& operator<<(const wxWCharBuffer& s) { (void)operator<<((const wchar_t *)s); return *this; }
504 void operator+=(const wxWCharBuffer& s) { (void)operator<<((const wchar_t *)s); }
505 #else
506 wxString& operator<<(const wxCharBuffer& s) { (void)operator<<((const char *)s); return *this; }
507 void operator+=(const wxCharBuffer& s) { (void)operator<<((const char *)s); }
508 #endif
509
510 // string += C string
511 wxString& Append(const wxChar* psz)
512 { ConcatSelf(wxStrlen(psz), psz); return *this; }
513 // append count copies of given character
514 wxString& Append(wxChar ch, size_t count = 1u)
515 { wxString str(ch, count); return *this << str; }
516
517 // prepend a string, return the string itself
518 wxString& Prepend(const wxString& str)
519 { *this = str + *this; return *this; }
520
521 // non-destructive concatenation
522 //
523 friend wxString WXDLLEXPORT operator+(const wxString& string1, const wxString& string2);
524 //
525 friend wxString WXDLLEXPORT operator+(const wxString& string, wxChar ch);
526 //
527 friend wxString WXDLLEXPORT operator+(wxChar ch, const wxString& string);
528 //
529 friend wxString WXDLLEXPORT operator+(const wxString& string, const wxChar *psz);
530 //
531 friend wxString WXDLLEXPORT operator+(const wxChar *psz, const wxString& string);
532
533 // stream-like functions
534 // insert an int into string
535 wxString& operator<<(int i);
536 // insert a float into string
537 wxString& operator<<(float f);
538 // insert a double into string
539 wxString& operator<<(double d);
540
541 // string comparison
542 // case-sensitive comparison (returns a value < 0, = 0 or > 0)
543 int Cmp(const wxChar *psz) const { return wxStrcmp(c_str(), psz); }
544 // same as Cmp() but not case-sensitive
545 int CmpNoCase(const wxChar *psz) const { return wxStricmp(c_str(), psz); }
546 // test for the string equality, either considering case or not
547 // (if compareWithCase then the case matters)
548 bool IsSameAs(const wxChar *psz, bool compareWithCase = TRUE) const
549 { return (compareWithCase ? Cmp(psz) : CmpNoCase(psz)) == 0; }
550
551 // simple sub-string extraction
552 // return substring starting at nFirst of length nCount (or till the end
553 // if nCount = default value)
554 wxString Mid(size_t nFirst, size_t nCount = wxSTRING_MAXLEN) const;
555
556 // operator version of Mid()
557 wxString operator()(size_t start, size_t len) const
558 { return Mid(start, len); }
559
560 // get first nCount characters
561 wxString Left(size_t nCount) const;
562 // get last nCount characters
563 wxString Right(size_t nCount) const;
564 // get all characters before the first occurence of ch
565 // (returns the whole string if ch not found)
566 wxString BeforeFirst(wxChar ch) const;
567 // get all characters before the last occurence of ch
568 // (returns empty string if ch not found)
569 wxString BeforeLast(wxChar ch) const;
570 // get all characters after the first occurence of ch
571 // (returns empty string if ch not found)
572 wxString AfterFirst(wxChar ch) const;
573 // get all characters after the last occurence of ch
574 // (returns the whole string if ch not found)
575 wxString AfterLast(wxChar ch) const;
576
577 // for compatibility only, use more explicitly named functions above
578 wxString Before(wxChar ch) const { return BeforeLast(ch); }
579 wxString After(wxChar ch) const { return AfterFirst(ch); }
580
581 // case conversion
582 // convert to upper case in place, return the string itself
583 wxString& MakeUpper();
584 // convert to upper case, return the copy of the string
585 // Here's something to remember: BC++ doesn't like returns in inlines.
586 wxString Upper() const ;
587 // convert to lower case in place, return the string itself
588 wxString& MakeLower();
589 // convert to lower case, return the copy of the string
590 wxString Lower() const ;
591
592 // trimming/padding whitespace (either side) and truncating
593 // remove spaces from left or from right (default) side
594 wxString& Trim(bool bFromRight = TRUE);
595 // add nCount copies chPad in the beginning or at the end (default)
596 wxString& Pad(size_t nCount, wxChar chPad = _T(' '), bool bFromRight = TRUE);
597 // truncate string to given length
598 wxString& Truncate(size_t uiLen);
599
600 // searching and replacing
601 // searching (return starting index, or -1 if not found)
602 int Find(wxChar ch, bool bFromEnd = FALSE) const; // like strchr/strrchr
603 // searching (return starting index, or -1 if not found)
604 int Find(const wxChar *pszSub) const; // like strstr
605 // replace first (or all of bReplaceAll) occurences of substring with
606 // another string, returns the number of replacements made
607 size_t Replace(const wxChar *szOld,
608 const wxChar *szNew,
609 bool bReplaceAll = TRUE);
610
611 // check if the string contents matches a mask containing '*' and '?'
612 bool Matches(const wxChar *szMask) const;
613
614 // formated input/output
615 // as sprintf(), returns the number of characters written or < 0 on error
616 int Printf(const wxChar *pszFormat, ...);
617 // as vprintf(), returns the number of characters written or < 0 on error
618 int PrintfV(const wxChar* pszFormat, va_list argptr);
619
620 // raw access to string memory
621 // ensure that string has space for at least nLen characters
622 // only works if the data of this string is not shared
623 void Alloc(size_t nLen);
624 // minimize the string's memory
625 // only works if the data of this string is not shared
626 void Shrink();
627 // get writable buffer of at least nLen bytes. Unget() *must* be called
628 // a.s.a.p. to put string back in a reasonable state!
629 wxChar *GetWriteBuf(size_t nLen);
630 // call this immediately after GetWriteBuf() has been used
631 void UngetWriteBuf();
632
633 // wxWindows version 1 compatibility functions
634
635 // use Mid()
636 wxString SubString(size_t from, size_t to) const
637 { return Mid(from, (to - from + 1)); }
638 // values for second parameter of CompareTo function
639 enum caseCompare {exact, ignoreCase};
640 // values for first parameter of Strip function
641 enum stripType {leading = 0x1, trailing = 0x2, both = 0x3};
642
643 // use Printf()
644 int sprintf(const wxChar *pszFormat, ...);
645
646 // use Cmp()
647 inline int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
648 { return cmp == exact ? Cmp(psz) : CmpNoCase(psz); }
649
650 // use Len
651 size_t Length() const { return Len(); }
652 // Count the number of characters
653 int Freq(wxChar ch) const;
654 // use MakeLower
655 void LowerCase() { MakeLower(); }
656 // use MakeUpper
657 void UpperCase() { MakeUpper(); }
658 // use Trim except that it doesn't change this string
659 wxString Strip(stripType w = trailing) const;
660
661 // use Find (more general variants not yet supported)
662 size_t Index(const wxChar* psz) const { return Find(psz); }
663 size_t Index(wxChar ch) const { return Find(ch); }
664 // use Truncate
665 wxString& Remove(size_t pos) { return Truncate(pos); }
666 wxString& RemoveLast() { return Truncate(Len() - 1); }
667
668 wxString& Remove(size_t nStart, size_t nLen) { return erase( nStart, nLen ); }
669
670 // use Find()
671 int First( const wxChar ch ) const { return Find(ch); }
672 int First( const wxChar* psz ) const { return Find(psz); }
673 int First( const wxString &str ) const { return Find(str); }
674 int Last( const wxChar ch ) const { return Find(ch, TRUE); }
675 bool Contains(const wxString& str) const { return Find(str) != -1; }
676
677 // use IsEmpty()
678 bool IsNull() const { return IsEmpty(); }
679
680 #ifdef wxSTD_STRING_COMPATIBILITY
681 // std::string compatibility functions
682
683 // an 'invalid' value for string index
684 static const size_t npos;
685
686 // constructors
687 // take nLen chars starting at nPos
688 wxString(const wxString& str, size_t nPos, size_t nLen)
689 {
690 wxASSERT( str.GetStringData()->IsValid() );
691 InitWith(str.c_str(), nPos, nLen == npos ? 0 : nLen);
692 }
693 // take all characters from pStart to pEnd
694 wxString(const void *pStart, const void *pEnd);
695
696 // lib.string.capacity
697 // return the length of the string
698 size_t size() const { return Len(); }
699 // return the length of the string
700 size_t length() const { return Len(); }
701 // return the maximum size of the string
702 size_t max_size() const { return wxSTRING_MAXLEN; }
703 // resize the string, filling the space with c if c != 0
704 void resize(size_t nSize, wxChar ch = _T('\0'));
705 // delete the contents of the string
706 void clear() { Empty(); }
707 // returns true if the string is empty
708 bool empty() const { return IsEmpty(); }
709
710 // lib.string.access
711 // return the character at position n
712 wxChar at(size_t n) const { return GetChar(n); }
713 // returns the writable character at position n
714 wxChar& at(size_t n) { return GetWritableChar(n); }
715
716 // lib.string.modifiers
717 // append a string
718 wxString& append(const wxString& str)
719 { *this += str; return *this; }
720 // append elements str[pos], ..., str[pos+n]
721 wxString& append(const wxString& str, size_t pos, size_t n)
722 { ConcatSelf(n, str.c_str() + pos); return *this; }
723 // append first n (or all if n == npos) characters of sz
724 wxString& append(const wxChar *sz, size_t n = npos)
725 { ConcatSelf(n == npos ? wxStrlen(sz) : n, sz); return *this; }
726
727 // append n copies of ch
728 wxString& append(size_t n, wxChar ch) { return Pad(n, ch); }
729
730 // same as `this_string = str'
731 wxString& assign(const wxString& str) { return (*this) = str; }
732 // same as ` = str[pos..pos + n]
733 wxString& assign(const wxString& str, size_t pos, size_t n)
734 { return *this = wxString((const wxChar *)str + pos, n); }
735 // same as `= first n (or all if n == npos) characters of sz'
736 wxString& assign(const wxChar *sz, size_t n = npos)
737 { return *this = wxString(sz, n); }
738 // same as `= n copies of ch'
739 wxString& assign(size_t n, wxChar ch)
740 { return *this = wxString(ch, n); }
741
742 // insert another string
743 wxString& insert(size_t nPos, const wxString& str);
744 // insert n chars of str starting at nStart (in str)
745 wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
746 { return insert(nPos, wxString((const wxChar *)str + nStart, n)); }
747
748 // insert first n (or all if n == npos) characters of sz
749 wxString& insert(size_t nPos, const wxChar *sz, size_t n = npos)
750 { return insert(nPos, wxString(sz, n)); }
751 // insert n copies of ch
752 wxString& insert(size_t nPos, size_t n, wxChar ch)
753 { return insert(nPos, wxString(ch, n)); }
754
755 // delete characters from nStart to nStart + nLen
756 wxString& erase(size_t nStart = 0, size_t nLen = npos);
757
758 // replaces the substring of length nLen starting at nStart
759 wxString& replace(size_t nStart, size_t nLen, const wxChar* sz);
760 // replaces the substring with nCount copies of ch
761 wxString& replace(size_t nStart, size_t nLen, size_t nCount, wxChar ch);
762 // replaces a substring with another substring
763 wxString& replace(size_t nStart, size_t nLen,
764 const wxString& str, size_t nStart2, size_t nLen2);
765 // replaces the substring with first nCount chars of sz
766 wxString& replace(size_t nStart, size_t nLen,
767 const wxChar* sz, size_t nCount);
768
769 // swap two strings
770 void swap(wxString& str);
771
772 // All find() functions take the nStart argument which specifies the
773 // position to start the search on, the default value is 0. All functions
774 // return npos if there were no match.
775
776 // find a substring
777 size_t find(const wxString& str, size_t nStart = 0) const;
778
779 // VC++ 1.5 can't cope with this syntax.
780 #if !defined(__VISUALC__) || defined(__WIN32__)
781 // find first n characters of sz
782 size_t find(const wxChar* sz, size_t nStart = 0, size_t n = npos) const;
783 #endif
784
785 // Gives a duplicate symbol (presumably a case-insensitivity problem)
786 #if !defined(__BORLANDC__)
787 // find the first occurence of character ch after nStart
788 size_t find(wxChar ch, size_t nStart = 0) const;
789 #endif
790 // rfind() family is exactly like find() but works right to left
791
792 // as find, but from the end
793 size_t rfind(const wxString& str, size_t nStart = npos) const;
794
795 // VC++ 1.5 can't cope with this syntax.
796 #if !defined(__VISUALC__) || defined(__WIN32__)
797 // as find, but from the end
798 size_t rfind(const wxChar* sz, size_t nStart = npos,
799 size_t n = npos) const;
800 // as find, but from the end
801 size_t rfind(wxChar ch, size_t nStart = npos) const;
802 #endif
803
804 // find first/last occurence of any character in the set
805
806 //
807 size_t find_first_of(const wxString& str, size_t nStart = 0) const;
808 //
809 size_t find_first_of(const wxChar* sz, size_t nStart = 0) const;
810 // same as find(char, size_t)
811 size_t find_first_of(wxChar c, size_t nStart = 0) const;
812 //
813 size_t find_last_of (const wxString& str, size_t nStart = npos) const;
814 //
815 size_t find_last_of (const wxChar* s, size_t nStart = npos) const;
816 // same as rfind(char, size_t)
817 size_t find_last_of (wxChar c, size_t nStart = npos) const;
818
819 // find first/last occurence of any character not in the set
820
821 //
822 size_t find_first_not_of(const wxString& str, size_t nStart = 0) const;
823 //
824 size_t find_first_not_of(const wxChar* s, size_t nStart = 0) const;
825 //
826 size_t find_first_not_of(wxChar ch, size_t nStart = 0) const;
827 //
828 size_t find_last_not_of(const wxString& str, size_t nStart=npos) const;
829 //
830 size_t find_last_not_of(const wxChar* s, size_t nStart = npos) const;
831 //
832 size_t find_last_not_of(wxChar ch, size_t nStart = npos) const;
833
834 // All compare functions return -1, 0 or 1 if the [sub]string is less,
835 // equal or greater than the compare() argument.
836
837 // just like strcmp()
838 int compare(const wxString& str) const { return Cmp(str); }
839 // comparison with a substring
840 int compare(size_t nStart, size_t nLen, const wxString& str) const;
841 // comparison of 2 substrings
842 int compare(size_t nStart, size_t nLen,
843 const wxString& str, size_t nStart2, size_t nLen2) const;
844 // just like strcmp()
845 int compare(const wxChar* sz) const { return Cmp(sz); }
846 // substring comparison with first nCount characters of sz
847 int compare(size_t nStart, size_t nLen,
848 const wxChar* sz, size_t nCount = npos) const;
849
850 // substring extraction
851 wxString substr(size_t nStart = 0, size_t nLen = npos) const;
852 #endif // wxSTD_STRING_COMPATIBILITY
853 };
854
855 // ----------------------------------------------------------------------------
856 // The string array uses it's knowledge of internal structure of the wxString
857 // class to optimize string storage. Normally, we would store pointers to
858 // string, but as wxString is, in fact, itself a pointer (sizeof(wxString) is
859 // sizeof(char *)) we store these pointers instead. The cast to "wxString *" is
860 // really all we need to turn such pointer into a string!
861 //
862 // Of course, it can be called a dirty hack, but we use twice less memory and
863 // this approach is also more speed efficient, so it's probably worth it.
864 //
865 // Usage notes: when a string is added/inserted, a new copy of it is created,
866 // so the original string may be safely deleted. When a string is retrieved
867 // from the array (operator[] or Item() method), a reference is returned.
868 // ----------------------------------------------------------------------------
869 class WXDLLEXPORT wxArrayString
870 {
871 public:
872 // type of function used by wxArrayString::Sort()
873 typedef int (*CompareFunction)(const wxString& first,
874 const wxString& second);
875
876 // constructors and destructor
877 // default ctor
878 wxArrayString();
879 // copy ctor
880 wxArrayString(const wxArrayString& array);
881 // assignment operator
882 wxArrayString& operator=(const wxArrayString& src);
883 // not virtual, this class should not be derived from
884 ~wxArrayString();
885
886 // memory management
887 // empties the list, but doesn't release memory
888 void Empty();
889 // empties the list and releases memory
890 void Clear();
891 // preallocates memory for given number of items
892 void Alloc(size_t nCount);
893 // minimzes the memory usage (by freeing all extra memory)
894 void Shrink();
895
896 // simple accessors
897 // number of elements in the array
898 size_t GetCount() const { return m_nCount; }
899 // is it empty?
900 bool IsEmpty() const { return m_nCount == 0; }
901 // number of elements in the array (GetCount is preferred API)
902 size_t Count() const { return m_nCount; }
903
904 // items access (range checking is done in debug version)
905 // get item at position uiIndex
906 wxString& Item(size_t nIndex) const
907 { wxASSERT( nIndex < m_nCount ); return *(wxString *)&(m_pItems[nIndex]); }
908 // same as Item()
909 wxString& operator[](size_t nIndex) const { return Item(nIndex); }
910 // get last item
911 wxString& Last() const { wxASSERT( !IsEmpty() ); return Item(Count() - 1); }
912
913 // item management
914 // Search the element in the array, starting from the beginning if
915 // bFromEnd is FALSE or from end otherwise. If bCase, comparison is case
916 // sensitive (default). Returns index of the first item matched or
917 // wxNOT_FOUND
918 int Index (const wxChar *sz, bool bCase = TRUE, bool bFromEnd = FALSE) const;
919 // add new element at the end
920 void Add(const wxString& str);
921 // add new element at given position
922 void Insert(const wxString& str, size_t uiIndex);
923 // remove first item matching this value
924 void Remove(const wxChar *sz);
925 // remove item by index
926 void Remove(size_t nIndex);
927
928 // sorting
929 // sort array elements in alphabetical order (or reversed alphabetical
930 // order if reverseOrder parameter is TRUE)
931 void Sort(bool reverseOrder = FALSE);
932 // sort array elements using specified comparaison function
933 void Sort(CompareFunction compareFunction);
934
935 private:
936 void Grow(); // makes array bigger if needed
937 void Free(); // free the string stored
938
939 void DoSort(); // common part of all Sort() variants
940
941 size_t m_nSize, // current size of the array
942 m_nCount; // current number of elements
943
944 wxChar **m_pItems; // pointer to data
945 };
946
947 // ---------------------------------------------------------------------------
948 // wxString comparison functions: operator versions are always case sensitive
949 // ---------------------------------------------------------------------------
950 //
951 inline bool operator==(const wxString& s1, const wxString& s2) { return (s1.Cmp(s2) == 0); }
952 //
953 inline bool operator==(const wxString& s1, const wxChar * s2) { return (s1.Cmp(s2) == 0); }
954 //
955 inline bool operator==(const wxChar * s1, const wxString& s2) { return (s2.Cmp(s1) == 0); }
956 //
957 inline bool operator!=(const wxString& s1, const wxString& s2) { return (s1.Cmp(s2) != 0); }
958 //
959 inline bool operator!=(const wxString& s1, const wxChar * s2) { return (s1.Cmp(s2) != 0); }
960 //
961 inline bool operator!=(const wxChar * s1, const wxString& s2) { return (s2.Cmp(s1) != 0); }
962 //
963 inline bool operator< (const wxString& s1, const wxString& s2) { return (s1.Cmp(s2) < 0); }
964 //
965 inline bool operator< (const wxString& s1, const wxChar * s2) { return (s1.Cmp(s2) < 0); }
966 //
967 inline bool operator< (const wxChar * s1, const wxString& s2) { return (s2.Cmp(s1) > 0); }
968 //
969 inline bool operator> (const wxString& s1, const wxString& s2) { return (s1.Cmp(s2) > 0); }
970 //
971 inline bool operator> (const wxString& s1, const wxChar * s2) { return (s1.Cmp(s2) > 0); }
972 //
973 inline bool operator> (const wxChar * s1, const wxString& s2) { return (s2.Cmp(s1) < 0); }
974 //
975 inline bool operator<=(const wxString& s1, const wxString& s2) { return (s1.Cmp(s2) <= 0); }
976 //
977 inline bool operator<=(const wxString& s1, const wxChar * s2) { return (s1.Cmp(s2) <= 0); }
978 //
979 inline bool operator<=(const wxChar * s1, const wxString& s2) { return (s2.Cmp(s1) >= 0); }
980 //
981 inline bool operator>=(const wxString& s1, const wxString& s2) { return (s1.Cmp(s2) >= 0); }
982 //
983 inline bool operator>=(const wxString& s1, const wxChar * s2) { return (s1.Cmp(s2) >= 0); }
984 //
985 inline bool operator>=(const wxChar * s1, const wxString& s2) { return (s2.Cmp(s1) <= 0); }
986
987 wxString WXDLLEXPORT operator+(const wxString& string1, const wxString& string2);
988 wxString WXDLLEXPORT operator+(const wxString& string, wxChar ch);
989 wxString WXDLLEXPORT operator+(wxChar ch, const wxString& string);
990 wxString WXDLLEXPORT operator+(const wxString& string, const wxChar *psz);
991 wxString WXDLLEXPORT operator+(const wxChar *psz, const wxString& string);
992
993 // ---------------------------------------------------------------------------
994 // Implementation only from here until the end of file
995 // ---------------------------------------------------------------------------
996
997 #ifdef wxSTD_STRING_COMPATIBILITY
998
999 #include "wx/ioswrap.h"
1000
1001 WXDLLEXPORT istream& operator>>(istream& is, wxString& str);
1002
1003 #endif // wxSTD_STRING_COMPATIBILITY
1004
1005 #endif // _WX_WXSTRINGH__