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