## Public API Reference

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# csutil/csstring.h

Go to the documentation of this file.

    00001 /*
    00002     Crystal Space utility library: string class
    00003     Copyright (C) 1999,2000 by Andrew Zabolotny <bit@eltech.ru>
    00004
    00005     This library is free software; you can redistribute it and/or
    00006     modify it under the terms of the GNU Library General Public
    00007     License as published by the Free Software Foundation; either
    00008     version 2 of the License, or (at your option) any later version.
    00009
    00010     This library is distributed in the hope that it will be useful,
    00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013     Library General Public License for more details.
    00014
    00015     You should have received a copy of the GNU Library General Public
    00016     License along with this library; if not, write to the Free
    00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00018 */
    00019 #ifndef __CS_CSSTRING_H__
    00020 #define __CS_CSSTRING_H__
    00021
    00026 #include "csextern.h"
    00027 #include "csutil/snprintf.h"
    00028 #include "csutil/util.h"
    00029
    00051 class CS_CRYSTALSPACE_EXPORT csStringBase
    00052 {
    00053 protected:
    00058   enum { DEFAULT_GROW_BY = 64 };
    00059
    00061   char* Data;
    00063   size_t Size;
    00065   size_t MaxSize;
    00070   size_t GrowBy;
    00071
    00077   void ExpandIfNeeded (size_t NewSize);
    00078
    00083   virtual void SetCapacityInternal (size_t NewSize, bool soft);
    00084
    00086   size_t ComputeNewSize (size_t NewSize);
    00087
    00099   virtual char* GetDataMutable ()
    00100   { return Data; }
    00101
    00102 public:
    00110   void SetCapacity (size_t NewSize);
    00111
    00116   virtual size_t GetCapacity() const
    00117   { return MaxSize > 0 ? MaxSize - 1 : 0; }
    00118
    00126   csStringBase& Append (const char* Str, size_t Count = (size_t)-1);
    00127
    00135   csStringBase& Append (const csStringBase& Str, size_t Count = (size_t)-1);
    00136
    00141   csStringBase& Append (char c);
    00142
    00147   /*csStringBase& Append (unsigned char c)
    00148   { return Append(char(c)); }*/
    00149
    00151   csStringBase& Append (bool b) { return Append (b ? "1" : "0"); }
    00152
    00158   csStringBase& AppendFmt (const char* format, ...) CS_GNUC_PRINTF (2, 3);
    00159   csStringBase& AppendFmtV (const char* format, va_list args);
    00163
    00164   csStringBase& Append (short v) { return AppendFmt ("%hd", v); }
    00165   csStringBase& Append (unsigned short v) { return AppendFmt ("%hu", v); }
    00166   csStringBase& Append (int v) { return AppendFmt ("%d", v); }
    00167   csStringBase& Append (unsigned int v) { return AppendFmt ("%u", v); }
    00168   csStringBase& Append (long v) { return AppendFmt ("%ld", v); }
    00169   csStringBase& Append (unsigned long v) { return AppendFmt ("%lu", v); }
    00170   csStringBase& Append (float v) { return AppendFmt ("%g", v); }
    00171   csStringBase& Append (double v) { return AppendFmt ("%g", v); }
    00172 #ifndef __STRICT_ANSI__
    00173   csStringBase& Append (longlong v) { return AppendFmt ("%lld", v); }
    00174   csStringBase& Append (ulonglong v) { return AppendFmt ("%llu", v); }
    00175 #endif
    00176
    00182   csStringBase () : Data (0), Size (0), MaxSize (0), GrowBy (DEFAULT_GROW_BY)
    00183   {}
    00184
    00191   csStringBase (size_t Length) : Data (0), Size (0), MaxSize (0),
    00192     GrowBy (DEFAULT_GROW_BY)
    00193   { SetCapacity (Length); }
    00194
    00200   csStringBase (const csStringBase& copy) : Data (0), Size (0), MaxSize (0),
    00201     GrowBy (DEFAULT_GROW_BY)
    00202   { Append (copy); }
    00203
    00209   csStringBase (const char* src) : Data (0), Size (0), MaxSize (0),
    00210     GrowBy (DEFAULT_GROW_BY)
    00211   { Append (src); }
    00212
    00218   csStringBase (const char* src, size_t _length) : Data (0), Size (0),
    00219         MaxSize (0), GrowBy (DEFAULT_GROW_BY)
    00220   { Append (src, _length); }
    00221
    00223   csStringBase (char c) : Data (0), Size (0), MaxSize (0),
    00224     GrowBy (DEFAULT_GROW_BY)
    00225   { Append (c); }
    00226
    00228   csStringBase (unsigned char c) : Data(0), Size (0), MaxSize (0),
    00229     GrowBy (DEFAULT_GROW_BY)
    00230   { Append ((char) c); }
    00231
    00233   virtual ~csStringBase ();
    00234
    00247   void SetGrowsBy(size_t);
    00248
    00254   size_t GetGrowsBy() const
    00255   { return GrowBy; }
    00256
    00261   CS_DEPRECATED_METHOD void SetGrowsExponentially(bool b)
    00262   { SetGrowsBy(b ? 0 : DEFAULT_GROW_BY); }
    00263
    00268   CS_DEPRECATED_METHOD bool GetGrowsExponentially() const
    00269   { return GetGrowsBy() == 0; }
    00270
    00277   virtual void Free ();
    00278
    00295   csStringBase& Truncate (size_t Len);
    00296
    00302   csStringBase& Empty() { return Truncate (0); }
    00303
    00313   virtual void ShrinkBestFit ();
    00314
    00324   csStringBase& Reclaim () { ShrinkBestFit(); return *this; }
    00325
    00332   csStringBase& Clear () { return Empty(); }
    00333
    00341   virtual char const* GetData () const
    00342   { return Data; }
    00343
    00353    char const* GetDataSafe() const
    00354    { char const* p = GetData(); return p != 0 ? p : ""; }
    00355
    00361   size_t Length () const
    00362   { return Size; }
    00363
    00369   bool IsEmpty () const
    00370   { return (Size == 0); }
    00371
    00373   char& operator [] (size_t n)
    00374   {
    00375     CS_ASSERT (n < Size);
    00376     return GetDataMutable()[n];
    00377   }
    00378
    00380   char operator [] (size_t n) const
    00381   {
    00382     CS_ASSERT (n < Size);
    00383     return GetData()[n];
    00384   }
    00385
    00392   void SetAt (size_t n, const char c)
    00393   {
    00394     CS_ASSERT (n < Size);
    00395     GetDataMutable() [n] = c;
    00396   }
    00397
    00399   char GetAt (size_t n) const
    00400   {
    00401     CS_ASSERT (n < Size);
    00402     return GetData() [n];
    00403   }
    00404
    00411   csStringBase& DeleteAt (size_t Pos, size_t Count = 1);
    00412
    00419   csStringBase& Insert (size_t Pos, const csStringBase& Str);
    00420
    00427   csStringBase& Insert (size_t Pos, const char* Str);
    00428
    00435   csStringBase& Insert (size_t Pos, char C);
    00436
    00445   csStringBase& Overwrite (size_t Pos, const csStringBase& Str);
    00446
    00453   csStringBase Slice (size_t start, size_t len = (size_t)-1) const;
    00454
    00465   void SubString (csStringBase& sub, size_t start,
    00466     size_t len = (size_t)-1) const;
    00467
    00474   size_t FindFirst (char c, size_t pos = 0) const;
    00475
    00482   size_t FindFirst (const char *c, size_t pos = 0) const;
    00483
    00491   size_t FindLast (char c, size_t pos = (size_t)-1) const;
    00492
    00499   size_t Find (const char* search, size_t pos = 0) const;
    00500
    00508   /* CS_DEPRECATED_METHOD */
    00509   size_t FindStr (const char* search, size_t pos = 0) const
    00510   { return Find(search, pos); }
    00511
    00516   void ReplaceAll (const char* search, const char* replacement);
    00517
    00523   /* CS_DEPRECATED_METHOD */
    00524   void FindReplace (const char* search, const char* replacement)
    00525   { ReplaceAll(search, replacement); }
    00526
    00534   csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3);
    00535
    00543   csStringBase& FormatV (const char* format, va_list args);
    00544
    00554   csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1);
    00555
    00565   csStringBase& Replace (const char* Str, size_t Count = (size_t)-1);
    00566
    00571   template<typename T>
    00572   csStringBase& Replace (T const& val) { Truncate (0); return Append (val); }
    00573
    00580   bool Compare (const csStringBase& iStr) const
    00581   {
    00582     if (&iStr == this)
    00583       return true;
    00584     size_t const n = iStr.Length();
    00585     if (Size != n)
    00586       return false;
    00587     if (Size == 0 && n == 0)
    00588       return true;
    00589     return (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0);
    00590   }
    00591
    00598   bool Compare (const char* iStr) const
    00599   { return (strcmp (GetDataSafe(), iStr) == 0); }
    00600
    00607   bool CompareNoCase (const csStringBase& iStr) const
    00608   {
    00609     if (&iStr == this)
    00610       return true;
    00611     size_t const n = iStr.Length();
    00612     if (Size != n)
    00613       return false;
    00614     if (Size == 0 && n == 0)
    00615       return true;
    00616     return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0);
    00617   }
    00618
    00625   bool CompareNoCase (const char* iStr) const
    00626   { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); }
    00627
    00634   bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const
    00635   {
    00636     char const* p = GetDataSafe();
    00637     if (&iStr == this)
    00638       return true;
    00639     size_t const n = iStr.Length();
    00640     if (n == 0)
    00641       return true;
    00642     if (n > Size)
    00643       return false;
    00644     CS_ASSERT(p != 0);
    00645     if (ignore_case)
    00646       return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0);
    00647     else
    00648       return (strncmp (p, iStr.GetDataSafe (), n) == 0);
    00649   }
    00650
    00657   bool StartsWith (const char* iStr, bool ignore_case = false) const
    00658   {
    00659     char const* p = GetDataSafe();
    00660     if (iStr == 0)
    00661       return false;
    00662     size_t const n = strlen (iStr);
    00663     if (n == 0)
    00664       return true;
    00665     if (n > Size)
    00666       return false;
    00667     CS_ASSERT(p != 0);
    00668     if (ignore_case)
    00669       return (csStrNCaseCmp (p, iStr, n) == 0);
    00670     else
    00671       return (strncmp (p, iStr, n) == 0);
    00672   }
    00673
    00679   csStringBase Clone () const
    00680   { return csStringBase (*this); }
    00681
    00689   csStringBase& LTrim();
    00690
    00698   csStringBase& RTrim();
    00699
    00705   csStringBase& Trim();
    00706
    00712   csStringBase& Collapse();
    00713
    00722   csStringBase& PadLeft (size_t NewSize, char PadChar = ' ');
    00723
    00732   csStringBase& PadRight (size_t NewSize, char PadChar = ' ');
    00733
    00745   csStringBase& PadCenter (size_t NewSize, char PadChar = ' ');
    00746
    00750   template<typename T>
    00751   const csStringBase& operator = (T const& s) { return Replace (s); }
    00752
    00754   const csStringBase& operator = (const csStringBase& copy)
    00755   { Replace(copy); return *this; }
    00756
    00760   template<typename T>
    00761   csStringBase &operator += (T const& s) { return Append (s); }
    00762
    00763   // Specialization which prevents gcc from barfing on strings allocated via
    00764   // CS_ALLOC_STACK_ARRAY().
    00765   csStringBase &operator += (char const* s)
    00766   { return Append(s); }
    00767
    00769   csStringBase operator + (const csStringBase &iStr) const
    00770   { return Clone ().Append (iStr); }
    00771
    00779   operator const char* () const
    00780   { return GetData(); }
    00781
    00788   bool operator == (const csStringBase& Str) const
    00789   { return Compare (Str); }
    00796   bool operator == (const char* Str) const
    00797   { return Compare (Str); }
    00804   bool operator < (const csStringBase& Str) const
    00805   {
    00806     return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0;
    00807   }
    00814   bool operator < (const char* Str) const
    00815   {
    00816     return strcmp (GetDataSafe (), Str) < 0;
    00817   }
    00824   bool operator > (const csStringBase& Str) const
    00825   {
    00826     return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0;
    00827   }
    00834   bool operator > (const char* Str) const
    00835   {
    00836     return strcmp (GetDataSafe (), Str) > 0;
    00837   }
    00844   bool operator != (const csStringBase& Str) const
    00845   { return !Compare (Str); }
    00852   bool operator != (const char* Str) const
    00853   { return !Compare (Str); }
    00854
    00862   template <typename T>
    00863   csStringBase &operator << (T const& v)
    00864   { return Append (v); }
    00865
    00866   // Specialization which prevents gcc from barfing on strings allocated via
    00867   // CS_ALLOC_STACK_ARRAY().
    00868   csStringBase &operator << (char const* v)
    00869   { return Append(v); }
    00870
    00875   csStringBase& Downcase();
    00880   csStringBase& Upcase();
    00881
    00892   virtual char* Detach ()
    00893   { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; }
    00898   uint GetHash() const;
    00899 };
    00900
    00902 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2)
    00903 {
    00904   return csStringBase (iStr1).Append (iStr2);
    00905 }
    00906
    00908 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2)
    00909 {
    00910   return iStr1.Clone ().Append (iStr2);
    00911 }
    00912
    00917 template<int LEN = 36>
    00918 class csStringFast : public csStringBase
    00919 {
    00920 protected:
    00922   char minibuff[LEN];
    00931   size_t miniused;
    00932
    00933   virtual void SetCapacityInternal (size_t NewSize, bool soft)
    00934   {
    00935     if (Data != 0) // If dynamic buffer already allocated, just re-use it.
    00936       csStringBase::SetCapacityInternal(NewSize, soft);
    00937     else
    00938     {
    00939       NewSize++; // Plus one for implicit null byte.
    00940       if (NewSize <= LEN)
    00941         miniused = NewSize;
    00942       else
    00943       {
    00944         CS_ASSERT(MaxSize == 0);
    00945         if (soft)
    00946           NewSize = ComputeNewSize (NewSize);
    00947         Data = new char[NewSize];
    00948         MaxSize = NewSize;
    00949         if (Size == 0)
    00950           Data[0] = '\0';
    00951         else
    00952           memcpy(Data, minibuff, Size + 1);
    00953       }
    00954     }
    00955   }
    00956
    00957   virtual char* GetDataMutable ()
    00958   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
    00959
    00960 public:
    00964   csStringFast () : csStringBase(), miniused(0) { }
    00969   csStringFast (size_t Length) : csStringBase(), miniused(0)
    00970   { SetCapacity (Length); }
    00974   csStringFast (const csStringBase& copy) : csStringBase (), miniused(0)
    00975   { Append (copy); }
    00979   csStringFast (const csStringFast& copy) : csStringBase (), miniused(0)
    00980   { Append (copy); }
    00984   csStringFast (const char* src) : csStringBase(), miniused(0)
    00985   { Append (src); }
    00989   csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0)
    00990   { Append (src, _length); }
    00991
    00992
    00994   csStringFast (char c) : csStringBase(), miniused(0)
    00995   { Append (c); }
    00997   csStringFast (unsigned char c) : csStringBase(), miniused(0)
    00998   { Append ((char)c); }
    01000   virtual ~csStringFast () { }
    01001
    01003   const csStringFast& operator = (const csStringBase& copy)
    01004   { Replace(copy); return *this; }
    01005
    01007   template<typename T>
    01008   const csStringFast& operator = (T const& s) { Replace (s); return *this; }
    01009
    01010   virtual char const* GetData () const
    01011   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
    01012
    01013   virtual size_t GetCapacity() const
    01014   { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; }
    01015
    01016   virtual void ShrinkBestFit ()
    01017   {
    01018     if (Size == 0)
    01019     {
    01020       csStringBase::ShrinkBestFit();
    01021       miniused = 0;
    01022     }
    01023     else
    01024     {
    01025       size_t needed = Size + 1;
    01026       if (needed > LEN)
    01027         csStringBase::ShrinkBestFit();
    01028       else
    01029       {
    01030         miniused = needed;
    01031         if (Data != 0)
    01032         {
    01033           memcpy(minibuff, Data, needed); // Includes implicit null byte.
    01034           csStringBase::Free();
    01035         }
    01036       }
    01037     }
    01038   }
    01039
    01040   virtual void Free () { miniused = 0; csStringBase::Free(); }
    01041
    01042   virtual char* Detach ()
    01043   {
    01044     if (Data != 0)
    01045       return csStringBase::Detach();
    01046     else if (miniused == 0)
    01047       return 0; // Emulate NULL return of csStringBase in this case.
    01048     else
    01049     {
    01050       CS_ASSERT(MaxSize == 0);
    01051       char* d = csStrNew (minibuff);
    01052       Size = 0; miniused = 0;
    01053       return d;
    01054     }
    01055   }
    01056 };
    01057
    01058 CS_SPECIALIZE_TEMPLATE
    01059 class csStringFast<0> : public csStringBase
    01060 {
    01061 public:
    01062   csStringFast () : csStringBase() { }
    01063   csStringFast (size_t Length) : csStringBase(Length) { }
    01064   csStringFast (const csStringBase& copy) : csStringBase (copy) { }
    01065   csStringFast (const char* src) : csStringBase(src) { }
    01066   csStringFast (const char* src, size_t _length) : csStringBase(src, _length)
    01067   { }
    01068   csStringFast (char c) : csStringBase(c) { }
    01069   csStringFast (unsigned char c) : csStringBase(c) { }
    01070   const csStringFast& operator = (const csStringBase& copy)
    01071   { Replace(copy); return *this; }
    01072   const csStringFast& operator = (const char* copy)
    01073   { Replace(copy); return *this; }
    01074   const csStringFast& operator = (char x)
    01075   { Replace(x); return *this; }
    01076   const csStringFast& operator = (unsigned char x)
    01077   { Replace(x); return *this; }
    01078   const csStringFast& operator = (bool x)
    01079   { Replace(x); return *this; }
    01080   const csStringFast& operator = (short x)
    01081   { Replace(x); return *this; }
    01082   const csStringFast& operator = (unsigned short x)
    01083   { Replace(x); return *this; }
    01084   const csStringFast& operator = (int x)
    01085   { Replace(x); return *this; }
    01086   const csStringFast& operator = (unsigned int x)
    01087   { Replace(x); return *this; }
    01088   const csStringFast& operator = (long x)
    01089   { Replace(x); return *this; }
    01090   const csStringFast& operator = (unsigned long x)
    01091   { Replace(x); return *this; }
    01092   const csStringFast& operator = (float x)
    01093   { Replace(x); return *this; }
    01094   const csStringFast& operator = (double x)
    01095   { Replace(x); return *this; }
    01096 #ifndef __STRICT_ANSI__
    01097   const csStringFast& operator = (longlong x)
    01098   { Replace(x); return *this; }
    01099   const csStringFast& operator = (ulonglong x)
    01100   { Replace(x); return *this; }
    01101 #endif
    01102 };
    01103
    01104 #ifndef SWIG
    01105
    01110 typedef csStringFast<> csStringFastDefault;
    01111 #else
    01112 #define csStringFastDefault csStringFast<36>
    01113 %template(csStringParent) csStringFast<36>;
    01114 #endif
    01115
    01119 class csString : public csStringFastDefault
    01120 {
    01121 public:
    01123   csString () : csStringFast<> () { }
    01128   csString (size_t Length) : csStringFast<> (Length) { }
    01130
    01131   csString (const csString& copy) :
    01132     csStringFast<> ((const csStringBase&)copy) { }
    01133   csString (const csStringBase& copy) : csStringFast<> (copy) { }
    01135
    01136   csString (const char* src) : csStringFast<> (src) { }
    01138   csString (const char* src, size_t _length) : csStringFast<> (src, _length) { }
    01140   csString (char c) : csStringFast<> (c) { }
    01142   csString (unsigned char c) : csStringFast<> (c) { }
    01143
    01145
    01146   const csString& operator = (const csString& copy)
    01147   { Replace(copy); return *this; }
    01148   const csString& operator = (const csStringBase& copy)
    01149   { Replace(copy); return *this; }
    01150   const csString& operator = (const char* copy)
    01151   { Replace(copy); return *this; }
    01152   const csString& operator = (char x)
    01153   { Replace(x); return *this; }
    01154   const csString& operator = (unsigned char x)
    01155   { Replace(x); return *this; }
    01156   const csString& operator = (bool x)
    01157   { Replace(x); return *this; }
    01158   const csString& operator = (short x)
    01159   { Replace(x); return *this; }
    01160   const csString& operator = (unsigned short x)
    01161   { Replace(x); return *this; }
    01162   const csString& operator = (int x)
    01163   { Replace(x); return *this; }
    01164   const csString& operator = (unsigned int x)
    01165   { Replace(x); return *this; }
    01166   const csString& operator = (long x)
    01167   { Replace(x); return *this; }
    01168   const csString& operator = (unsigned long x)
    01169   { Replace(x); return *this; }
    01170   const csString& operator = (float x)
    01171   { Replace(x); return *this; }
    01172   const csString& operator = (double x)
    01173   { Replace(x); return *this; }
    01174 #ifndef __STRICT_ANSI__
    01175   const csString& operator = (longlong x)
    01176   { Replace(x); return *this; }
    01177   const csString& operator = (ulonglong x)
    01178   { Replace(x); return *this; }
    01179 #endif
    01180
    01181 };
    01182
    01183 #endif // __CS_CSSTRING_H__