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