CrystalSpace

Public API Reference

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__

Generated for Crystal Space 1.0.2 by doxygen 1.4.7