| ## 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/csuctransform.h"
    00028 #include "csutil/snprintf.h"
    00029 #include "csutil/util.h"
    00030
    00052 class CS_CRYSTALSPACE_EXPORT csStringBase
    00053 {
    00054 protected:
    00059   enum { DEFAULT_GROW_BY = 64 };
    00060
    00062   char* Data;
    00064   size_t Size;
    00066   size_t MaxSize;
    00071   size_t GrowBy;
    00072
    00078   void ExpandIfNeeded (size_t NewSize);
    00079
    00084   virtual void SetCapacityInternal (size_t NewSize, bool soft);
    00085
    00087   size_t ComputeNewSize (size_t NewSize);
    00088
    00100   virtual char* GetDataMutable ()
    00101   { return Data; }
    00102
    00103 public:
    00111   void SetCapacity (size_t NewSize);
    00112
    00117   virtual size_t GetCapacity() const
    00118   { return MaxSize > 0 ? MaxSize - 1 : 0; }
    00119
    00127   csStringBase& Append (const char* Str, size_t Count = (size_t)-1);
    00128
    00137   csStringBase& Append (const wchar_t* Str, size_t Count = (size_t)-1);
    00138
    00146   csStringBase& Append (const csStringBase& Str, size_t Count = (size_t)-1);
    00147
    00152   csStringBase& Append (char c);
    00153
    00158   /*csStringBase& Append (unsigned char c)
    00159   { return Append(char(c)); }*/
    00160
    00162   csStringBase& Append (bool b) { return Append (b ? "1" : "0"); }
    00163
    00169   csStringBase& AppendFmt (const char* format, ...) CS_GNUC_PRINTF (2, 3);
    00170   csStringBase& AppendFmtV (const char* format, va_list args);
    00174
    00175   csStringBase& Append (short v) { return AppendFmt ("%hd", v); }
    00176   csStringBase& Append (unsigned short v) { return AppendFmt ("%hu", v); }
    00177   csStringBase& Append (int v) { return AppendFmt ("%d", v); }
    00178   csStringBase& Append (unsigned int v) { return AppendFmt ("%u", v); }
    00179   csStringBase& Append (long v) { return AppendFmt ("%ld", v); }
    00180   csStringBase& Append (unsigned long v) { return AppendFmt ("%lu", v); }
    00181   csStringBase& Append (float v) { return AppendFmt ("%g", v); }
    00182   csStringBase& Append (double v) { return AppendFmt ("%g", v); }
    00183 #ifndef __STRICT_ANSI__
    00184   csStringBase& Append (longlong v) { return AppendFmt ("%lld", v); }
    00185   csStringBase& Append (ulonglong v) { return AppendFmt ("%llu", v); }
    00186 #endif
    00187
    00193   csStringBase () : Data (0), Size (0), MaxSize (0), GrowBy (DEFAULT_GROW_BY)
    00194   {}
    00195
    00202   csStringBase (size_t Length) : Data (0), Size (0), MaxSize (0),
    00203     GrowBy (DEFAULT_GROW_BY)
    00204   { SetCapacity (Length); }
    00205
    00211   csStringBase (const csStringBase& copy) : Data (0), Size (0), MaxSize (0),
    00212     GrowBy (DEFAULT_GROW_BY)
    00213   { Append (copy); }
    00214
    00220   csStringBase (const char* src) : Data (0), Size (0), MaxSize (0),
    00221     GrowBy (DEFAULT_GROW_BY)
    00222   { Append (src); }
    00223
    00230   csStringBase (const wchar_t* src) : Data (0), Size (0), MaxSize (0),
    00231     GrowBy (DEFAULT_GROW_BY)
    00232   { Append (src); }
    00233
    00239   csStringBase (const char* src, size_t _length) : Data (0), Size (0),
    00240         MaxSize (0), GrowBy (DEFAULT_GROW_BY)
    00241   { Append (src, _length); }
    00242
    00249   csStringBase (const wchar_t* src, size_t _length) : Data (0), Size (0),
    00250         MaxSize (0), GrowBy (DEFAULT_GROW_BY)
    00251   { Append (src, _length); }
    00252
    00254   csStringBase (char c) : Data (0), Size (0), MaxSize (0),
    00255     GrowBy (DEFAULT_GROW_BY)
    00256   { Append (c); }
    00257
    00259   csStringBase (unsigned char c) : Data(0), Size (0), MaxSize (0),
    00260     GrowBy (DEFAULT_GROW_BY)
    00261   { Append ((char) c); }
    00262
    00264   virtual ~csStringBase ();
    00265
    00278   void SetGrowsBy(size_t);
    00279
    00285   size_t GetGrowsBy() const
    00286   { return GrowBy; }
    00287
    00292   CS_DEPRECATED_METHOD_MSG("Use SetGrowsBy(0) instead.")
    00293   void SetGrowsExponentially(bool b)
    00294   { SetGrowsBy(b ? 0 : DEFAULT_GROW_BY); }
    00295
    00300   CS_DEPRECATED_METHOD_MSG("Use GetGrowsBy() instead.")
    00301   bool GetGrowsExponentially() const
    00302   { return GetGrowsBy() == 0; }
    00303
    00310   virtual void Free ();
    00311
    00328   csStringBase& Truncate (size_t Len);
    00329
    00335   csStringBase& Empty() { return Truncate (0); }
    00336
    00346   virtual void ShrinkBestFit ();
    00347
    00357   csStringBase& Reclaim () { ShrinkBestFit(); return *this; }
    00358
    00365   csStringBase& Clear () { return Empty(); }
    00366
    00374   CS_VISIBILITY_DEFAULT // <- @@@ FIXME: needed for gcc 4.1.0
    00375   virtual char const* GetData () const
    00376   { return Data; }
    00377
    00387    char const* GetDataSafe() const
    00388    { char const* p = GetData(); return p != 0 ? p : ""; }
    00389
    00395   size_t Length () const
    00396   { return Size; }
    00397
    00403   bool IsEmpty () const
    00404   { return (Size == 0); }
    00405
    00407   char& operator [] (size_t n)
    00408   {
    00409     CS_ASSERT (n < Size);
    00410     return GetDataMutable()[n];
    00411   }
    00412
    00414   char operator [] (size_t n) const
    00415   {
    00416     CS_ASSERT (n < Size);
    00417     return GetData()[n];
    00418   }
    00419
    00426   void SetAt (size_t n, const char c)
    00427   {
    00428     CS_ASSERT (n < Size);
    00429     GetDataMutable() [n] = c;
    00430   }
    00431
    00433   char GetAt (size_t n) const
    00434   {
    00435     CS_ASSERT (n < Size);
    00436     return GetData() [n];
    00437   }
    00438
    00445   csStringBase& DeleteAt (size_t Pos, size_t Count = 1);
    00446
    00453   csStringBase& Insert (size_t Pos, const csStringBase& Str);
    00454
    00461   csStringBase& Insert (size_t Pos, const char* Str);
    00462
    00469   csStringBase& Insert (size_t Pos, char C);
    00470
    00479   csStringBase& Overwrite (size_t Pos, const csStringBase& Str);
    00480
    00487   csStringBase Slice (size_t start, size_t len = (size_t)-1) const;
    00488
    00499   void SubString (csStringBase& sub, size_t start,
    00500     size_t len = (size_t)-1) const;
    00501
    00508   size_t FindFirst (char c, size_t pos = 0) const;
    00509
    00516   size_t FindFirst (const char *c, size_t pos = 0) const;
    00517
    00525   size_t FindLast (char c, size_t pos = (size_t)-1) const;
    00526
    00534   size_t FindLast (const char *c, size_t pos = (size_t)-1) const;
    00535
    00542   size_t Find (const char* search, size_t pos = 0) const;
    00543
    00551   /* CS_DEPRECATED_METHOD_MSG("Use Find() instead.") */
    00552   size_t FindStr (const char* search, size_t pos = 0) const
    00553   { return Find(search, pos); }
    00554
    00559   void ReplaceAll (const char* search, const char* replacement);
    00560
    00566   /* CS_DEPRECATED_METHOD_MSG("Use ReplaceAll() instead.") */
    00567   void FindReplace (const char* search, const char* replacement)
    00568   { ReplaceAll(search, replacement); }
    00569
    00577   csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3);
    00578
    00586   csStringBase& FormatV (const char* format, va_list args);
    00587
    00597   csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1);
    00598
    00608   csStringBase& Replace (const char* Str, size_t Count = (size_t)-1);
    00609
    00614   template<typename T>
    00615   csStringBase& Replace (T const& val) { Truncate (0); return Append (val); }
    00616
    00623   bool Compare (const csStringBase& iStr) const
    00624   {
    00625     if (&iStr == this)
    00626       return true;
    00627     size_t const n = iStr.Length();
    00628     if (Size != n)
    00629       return false;
    00630     if (Size == 0 && n == 0)
    00631       return true;
    00632     return (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0);
    00633   }
    00634
    00641   bool Compare (const char* iStr) const
    00642   { return (strcmp (GetDataSafe(), iStr) == 0); }
    00643
    00650   bool CompareNoCase (const csStringBase& iStr) const
    00651   {
    00652     if (&iStr == this)
    00653       return true;
    00654     size_t const n = iStr.Length();
    00655     if (Size != n)
    00656       return false;
    00657     if (Size == 0 && n == 0)
    00658       return true;
    00659     return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0);
    00660   }
    00661
    00668   bool CompareNoCase (const char* iStr) const
    00669   { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); }
    00670
    00677   bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const
    00678   {
    00679     char const* p = GetDataSafe();
    00680     if (&iStr == this)
    00681       return true;
    00682     size_t const n = iStr.Length();
    00683     if (n == 0)
    00684       return true;
    00685     if (n > Size)
    00686       return false;
    00687     CS_ASSERT(p != 0);
    00688     if (ignore_case)
    00689       return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0);
    00690     else
    00691       return (strncmp (p, iStr.GetDataSafe (), n) == 0);
    00692   }
    00693
    00700   bool StartsWith (const char* iStr, bool ignore_case = false) const
    00701   {
    00702     char const* p = GetDataSafe();
    00703     if (iStr == 0)
    00704       return false;
    00705     size_t const n = strlen (iStr);
    00706     if (n == 0)
    00707       return true;
    00708     if (n > Size)
    00709       return false;
    00710     CS_ASSERT(p != 0);
    00711     if (ignore_case)
    00712       return (csStrNCaseCmp (p, iStr, n) == 0);
    00713     else
    00714       return (strncmp (p, iStr, n) == 0);
    00715   }
    00716
    00722   csStringBase Clone () const
    00723   { return csStringBase (*this); }
    00724
    00732   csStringBase& LTrim();
    00733
    00741   csStringBase& RTrim();
    00742
    00748   csStringBase& Trim();
    00749
    00755   csStringBase& Collapse();
    00756
    00765   csStringBase& PadLeft (size_t NewSize, char PadChar = ' ');
    00766
    00775   csStringBase& PadRight (size_t NewSize, char PadChar = ' ');
    00776
    00788   csStringBase& PadCenter (size_t NewSize, char PadChar = ' ');
    00789
    00793   template<typename T>
    00794   const csStringBase& operator = (T const& s) { return Replace (s); }
    00795
    00797   const csStringBase& operator = (const csStringBase& copy)
    00798   { Replace(copy); return *this; }
    00799
    00803   template<typename T>
    00804   csStringBase &operator += (T const& s) { return Append (s); }
    00805
    00806   // Specialization which prevents gcc from barfing on strings allocated via
    00807   // CS_ALLOC_STACK_ARRAY().
    00808   csStringBase &operator += (char const* s)
    00809   { return Append(s); }
    00810
    00812   csStringBase operator + (const csStringBase &iStr) const
    00813   { return Clone ().Append (iStr); }
    00814
    00822   operator const char* () const
    00823   { return GetData(); }
    00824
    00831   bool operator == (const csStringBase& Str) const
    00832   { return Compare (Str); }
    00839   bool operator == (const char* Str) const
    00840   { return Compare (Str); }
    00847   bool operator < (const csStringBase& Str) const
    00848   {
    00849     return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0;
    00850   }
    00857   bool operator < (const char* Str) const
    00858   {
    00859     return strcmp (GetDataSafe (), Str) < 0;
    00860   }
    00867   bool operator > (const csStringBase& Str) const
    00868   {
    00869     return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0;
    00870   }
    00877   bool operator > (const char* Str) const
    00878   {
    00879     return strcmp (GetDataSafe (), Str) > 0;
    00880   }
    00887   bool operator != (const csStringBase& Str) const
    00888   { return !Compare (Str); }
    00895   bool operator != (const char* Str) const
    00896   { return !Compare (Str); }
    00897
    00905   template <typename T>
    00906   csStringBase &operator << (T const& v)
    00907   { return Append (v); }
    00908
    00909   // Specialization which prevents gcc from barfing on strings allocated via
    00910   // CS_ALLOC_STACK_ARRAY().
    00911   csStringBase &operator << (char const* v)
    00912   { return Append(v); }
    00913
    00922   csStringBase& Downcase ();
    00931   csStringBase& Upcase ();
    00932
    00943   virtual char* Detach ()
    00944   { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; }
    00949   uint GetHash() const;
    00950 };
    00951
    00953 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2)
    00954 {
    00955   return csStringBase (iStr1).Append (iStr2);
    00956 }
    00957
    00959 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2)
    00960 {
    00961   return iStr1.Clone ().Append (iStr2);
    00962 }
    00963
    00968 template<int LEN = 36>
    00969 class csStringFast : public csStringBase
    00970 {
    00971 protected:
    00973   char minibuff[LEN];
    00982   size_t miniused;
    00983
    00984   virtual void SetCapacityInternal (size_t NewSize, bool soft)
    00985   {
    00986     if (Data != 0) // If dynamic buffer already allocated, just re-use it.
    00987       csStringBase::SetCapacityInternal(NewSize, soft);
    00988     else
    00989     {
    00990       NewSize++; // Plus one for implicit null byte.
    00991       if (NewSize <= LEN)
    00992         miniused = NewSize;
    00993       else
    00994       {
    00995         CS_ASSERT(MaxSize == 0);
    00996         if (soft)
    00997           NewSize = ComputeNewSize (NewSize);
    00998         Data = new char[NewSize];
    00999         MaxSize = NewSize;
    01000         if (Size == 0)
    01001           Data[0] = '\0';
    01002         else
    01003           memcpy(Data, minibuff, Size + 1);
    01004       }
    01005     }
    01006   }
    01007
    01008   virtual char* GetDataMutable ()
    01009   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
    01010
    01011 public:
    01015   csStringFast () : csStringBase(), miniused(0) { }
    01020   csStringFast (size_t Length) : csStringBase(), miniused(0)
    01021   { SetCapacity (Length); }
    01025   csStringFast (const csStringBase& copy) : csStringBase (), miniused(0)
    01026   { Append (copy); }
    01030   csStringFast (const csStringFast& copy) : csStringBase (), miniused(0)
    01031   { Append (copy); }
    01035   csStringFast (const char* src) : csStringBase(), miniused(0)
    01036   { Append (src); }
    01040   csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0)
    01041   { Append (src, _length); }
    01042
    01043
    01045   csStringFast (char c) : csStringBase(), miniused(0)
    01046   { Append (c); }
    01048   csStringFast (unsigned char c) : csStringBase(), miniused(0)
    01049   { Append ((char)c); }
    01051   virtual ~csStringFast () { }
    01052
    01054   const csStringFast& operator = (const csStringBase& copy)
    01055   { Replace(copy); return *this; }
    01056
    01058   template<typename T>
    01059   const csStringFast& operator = (T const& s) { Replace (s); return *this; }
    01060
    01061   virtual char const* GetData () const
    01062   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
    01063
    01064   virtual size_t GetCapacity() const
    01065   { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; }
    01066
    01067   virtual void ShrinkBestFit ()
    01068   {
    01069     if (Size == 0)
    01070     {
    01071       csStringBase::ShrinkBestFit();
    01072       miniused = 0;
    01073     }
    01074     else
    01075     {
    01076       size_t needed = Size + 1;
    01077       if (needed > LEN)
    01078         csStringBase::ShrinkBestFit();
    01079       else
    01080       {
    01081         miniused = needed;
    01082         if (Data != 0)
    01083         {
    01084           memcpy(minibuff, Data, needed); // Includes implicit null byte.
    01085           csStringBase::Free();
    01086         }
    01087       }
    01088     }
    01089   }
    01090
    01091   virtual void Free () { miniused = 0; csStringBase::Free(); }
    01092
    01093   virtual char* Detach ()
    01094   {
    01095     if (Data != 0)
    01096       return csStringBase::Detach();
    01097     else if (miniused == 0)
    01098       return 0; // Emulate NULL return of csStringBase in this case.
    01099     else
    01100     {
    01101       CS_ASSERT(MaxSize == 0);
    01102       char* d = csStrNew (minibuff);
    01103       Size = 0; miniused = 0;
    01104       return d;
    01105     }
    01106   }
    01107 };
    01108
    01109 template<>
    01110 class csStringFast<0> : public csStringBase
    01111 {
    01112 public:
    01113   csStringFast () : csStringBase() { }
    01114   csStringFast (size_t Length) : csStringBase(Length) { }
    01115   csStringFast (const csStringBase& copy) : csStringBase (copy) { }
    01116   csStringFast (const char* src) : csStringBase(src) { }
    01117   csStringFast (const char* src, size_t _length) : csStringBase(src, _length)
    01118   { }
    01119   csStringFast (char c) : csStringBase(c) { }
    01120   csStringFast (unsigned char c) : csStringBase(c) { }
    01121   const csStringFast& operator = (const csStringBase& copy)
    01122   { Replace(copy); return *this; }
    01123   const csStringFast& operator = (const char* copy)
    01124   { Replace(copy); return *this; }
    01125   const csStringFast& operator = (char x)
    01126   { Replace(x); return *this; }
    01127   const csStringFast& operator = (unsigned char x)
    01128   { Replace(x); return *this; }
    01129   const csStringFast& operator = (bool x)
    01130   { Replace(x); return *this; }
    01131   const csStringFast& operator = (short x)
    01132   { Replace(x); return *this; }
    01133   const csStringFast& operator = (unsigned short x)
    01134   { Replace(x); return *this; }
    01135   const csStringFast& operator = (int x)
    01136   { Replace(x); return *this; }
    01137   const csStringFast& operator = (unsigned int x)
    01138   { Replace(x); return *this; }
    01139   const csStringFast& operator = (long x)
    01140   { Replace(x); return *this; }
    01141   const csStringFast& operator = (unsigned long x)
    01142   { Replace(x); return *this; }
    01143   const csStringFast& operator = (float x)
    01144   { Replace(x); return *this; }
    01145   const csStringFast& operator = (double x)
    01146   { Replace(x); return *this; }
    01147 #ifndef __STRICT_ANSI__
    01148   const csStringFast& operator = (longlong x)
    01149   { Replace(x); return *this; }
    01150   const csStringFast& operator = (ulonglong x)
    01151   { Replace(x); return *this; }
    01152 #endif
    01153 };
    01154
    01155 #ifndef SWIG
    01156
    01161 typedef csStringFast<> csStringFastDefault;
    01162 #else
    01163 #define csStringFastDefault csStringFast<36>
    01164 %template(csStringParent) csStringFast<36>;
    01165 #endif
    01166
    01170 class csString : public csStringFastDefault
    01171 {
    01172 public:
    01174   csString () : csStringFast<> () { }
    01179   csString (size_t Length) : csStringFast<> (Length) { }
    01181
    01182   csString (const csString& copy) :
    01183     csStringFast<> ((const csStringBase&)copy) { }
    01184   csString (const csStringBase& copy) : csStringFast<> (copy) { }
    01186
    01187   csString (const char* src) : csStringFast<> (src) { }
    01189   csString (const char* src, size_t _length) : csStringFast<> (src, _length) { }
    01191   csString (char c) : csStringFast<> (c) { }
    01193   csString (unsigned char c) : csStringFast<> (c) { }
    01194
    01196
    01197   const csString& operator = (const csString& copy)
    01198   { Replace(copy); return *this; }
    01199   const csString& operator = (const csStringBase& copy)
    01200   { Replace(copy); return *this; }
    01201   const csString& operator = (const char* copy)
    01202   { Replace(copy); return *this; }
    01203   const csString& operator = (char x)
    01204   { Replace(x); return *this; }
    01205   const csString& operator = (unsigned char x)
    01206   { Replace(x); return *this; }
    01207   const csString& operator = (bool x)
    01208   { Replace(x); return *this; }
    01209   const csString& operator = (short x)
    01210   { Replace(x); return *this; }
    01211   const csString& operator = (unsigned short x)
    01212   { Replace(x); return *this; }
    01213   const csString& operator = (int x)
    01214   { Replace(x); return *this; }
    01215   const csString& operator = (unsigned int x)
    01216   { Replace(x); return *this; }
    01217   const csString& operator = (long x)
    01218   { Replace(x); return *this; }
    01219   const csString& operator = (unsigned long x)
    01220   { Replace(x); return *this; }
    01221   const csString& operator = (float x)
    01222   { Replace(x); return *this; }
    01223   const csString& operator = (double x)
    01224   { Replace(x); return *this; }
    01225 #ifndef __STRICT_ANSI__
    01226   const csString& operator = (longlong x)
    01227   { Replace(x); return *this; }
    01228   const csString& operator = (ulonglong x)
    01229   { Replace(x); return *this; }
    01230 #endif
    01231
    01232 };
    01233
    01234 #endif // __CS_CSSTRING_H__