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 <[email protected]>
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 
00136   csStringBase& Append (const wchar_t* Str, size_t Count = (size_t)-1);
00137 
00145   csStringBase& Append (const csStringBase& Str, size_t Count = (size_t)-1);
00146 
00151   csStringBase& Append (char c);
00152 
00157   /*csStringBase& Append (unsigned char c)
00158   { return Append(char(c)); }*/
00159 
00161   csStringBase& Append (bool b) { return Append (b ? "1" : "0"); }
00162 
00168   csStringBase& AppendFmt (const char* format, ...) CS_GNUC_PRINTF (2, 3);
00169   csStringBase& AppendFmtV (const char* format, va_list args);
00173 
00174   csStringBase& Append (short v) { return AppendFmt ("%hd", v); }
00175   csStringBase& Append (unsigned short v) { return AppendFmt ("%hu", v); }
00176   csStringBase& Append (int v) { return AppendFmt ("%d", v); }
00177   csStringBase& Append (unsigned int v) { return AppendFmt ("%u", v); }
00178   csStringBase& Append (long v) { return AppendFmt ("%ld", v); }
00179   csStringBase& Append (unsigned long v) { return AppendFmt ("%lu", v); }
00180   csStringBase& Append (float v) { return AppendFmt ("%g", v); }
00181   csStringBase& Append (double v) { return AppendFmt ("%g", v); }
00182 #ifndef __STRICT_ANSI__
00183   csStringBase& Append (longlong v) { return AppendFmt ("%lld", v); }
00184   csStringBase& Append (ulonglong v) { return AppendFmt ("%llu", v); }
00185 #endif
00186 
00192   csStringBase () : Data (0), Size (0), MaxSize (0), GrowBy (DEFAULT_GROW_BY)
00193   {}
00194 
00201   csStringBase (size_t Length) : Data (0), Size (0), MaxSize (0),
00202     GrowBy (DEFAULT_GROW_BY)
00203   { SetCapacity (Length); }
00204 
00210   csStringBase (const csStringBase& copy) : Data (0), Size (0), MaxSize (0),
00211     GrowBy (DEFAULT_GROW_BY)
00212   { Append (copy); }
00213 
00219   csStringBase (const char* src) : Data (0), Size (0), MaxSize (0),
00220     GrowBy (DEFAULT_GROW_BY)
00221   { Append (src); }
00222 
00229   csStringBase (const wchar_t* src) : Data (0), Size (0), MaxSize (0),
00230     GrowBy (DEFAULT_GROW_BY)
00231   { Append (src); }
00232 
00238   csStringBase (const char* src, size_t _length) : Data (0), Size (0),
00239         MaxSize (0), GrowBy (DEFAULT_GROW_BY)
00240   { Append (src, _length); }
00241 
00248   csStringBase (const wchar_t* src, size_t _length) : Data (0), Size (0),
00249         MaxSize (0), GrowBy (DEFAULT_GROW_BY)
00250   { Append (src, _length); }
00251 
00253   csStringBase (char c) : Data (0), Size (0), MaxSize (0),
00254     GrowBy (DEFAULT_GROW_BY)
00255   { Append (c); }
00256 
00258   csStringBase (unsigned char c) : Data(0), Size (0), MaxSize (0),
00259     GrowBy (DEFAULT_GROW_BY)
00260   { Append ((char) c); }
00261 
00263   virtual ~csStringBase ();
00264 
00277   void SetGrowsBy(size_t);
00278 
00284   size_t GetGrowsBy() const
00285   { return GrowBy; }
00286 
00291   CS_DEPRECATED_METHOD_MSG("Use SetGrowsBy(0) instead.") 
00292   void SetGrowsExponentially(bool b)
00293   { SetGrowsBy(b ? 0 : DEFAULT_GROW_BY); }
00294 
00299   CS_DEPRECATED_METHOD_MSG("Use GetGrowsBy() instead.") 
00300   bool GetGrowsExponentially() const
00301   { return GetGrowsBy() == 0; }
00302 
00309   virtual void Free ();
00310 
00327   csStringBase& Truncate (size_t Len);
00328 
00334   csStringBase& Empty() { return Truncate (0); }
00335 
00345   virtual void ShrinkBestFit ();
00346 
00356   csStringBase& Reclaim () { ShrinkBestFit(); return *this; }
00357 
00364   csStringBase& Clear () { return Empty(); }
00365 
00373   CS_VISIBILITY_DEFAULT // <- @@@ FIXME: needed for gcc 4.1.0
00374   virtual char const* GetData () const
00375   { return Data; }
00376 
00386    char const* GetDataSafe() const
00387    { char const* p = GetData(); return p != 0 ? p : ""; }
00388 
00394   size_t Length () const
00395   { return Size; }
00396 
00402   bool IsEmpty () const
00403   { return (Size == 0); }
00404 
00406   char& operator [] (size_t n)
00407   {
00408     CS_ASSERT (n < Size);
00409     return GetDataMutable()[n];
00410   }
00411 
00413   char operator [] (size_t n) const
00414   {
00415     CS_ASSERT (n < Size);
00416     return GetData()[n];
00417   }
00418 
00425   void SetAt (size_t n, const char c)
00426   {
00427     CS_ASSERT (n < Size);
00428     GetDataMutable() [n] = c;
00429   }
00430 
00432   char GetAt (size_t n) const
00433   {
00434     CS_ASSERT (n < Size);
00435     return GetData() [n];
00436   }
00437 
00444   csStringBase& DeleteAt (size_t Pos, size_t Count = 1);
00445 
00452   csStringBase& Insert (size_t Pos, const csStringBase& Str);
00453 
00460   csStringBase& Insert (size_t Pos, const char* Str);
00461 
00468   csStringBase& Insert (size_t Pos, char C);
00469 
00478   csStringBase& Overwrite (size_t Pos, const csStringBase& Str);
00479 
00486   csStringBase Slice (size_t start, size_t len = (size_t)-1) const;
00487 
00498   void SubString (csStringBase& sub, size_t start, 
00499     size_t len = (size_t)-1) const;
00500 
00507   size_t FindFirst (char c, size_t pos = 0) const;
00508 
00515   size_t FindFirst (const char *c, size_t pos = 0) const;
00516 
00524   size_t FindLast (char c, size_t pos = (size_t)-1) const;
00525   
00533   size_t FindLast (const char *c, size_t pos = (size_t)-1) const;
00534 
00541   size_t Find (const char* search, size_t pos = 0) const;
00542 
00550   /* CS_DEPRECATED_METHOD_MSG("Use Find() instead.") */
00551   size_t FindStr (const char* search, size_t pos = 0) const
00552   { return Find(search, pos); }
00553 
00558   void ReplaceAll (const char* search, const char* replacement);
00559 
00565   /* CS_DEPRECATED_METHOD_MSG("Use ReplaceAll() instead.") */
00566   void FindReplace (const char* search, const char* replacement)
00567   { ReplaceAll(search, replacement); }
00568 
00576   csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3);
00577 
00585   csStringBase& FormatV (const char* format, va_list args);
00586 
00596   csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1);
00597 
00607   csStringBase& Replace (const char* Str, size_t Count = (size_t)-1);
00608 
00613   template<typename T>
00614   csStringBase& Replace (T const& val) { Truncate (0); return Append (val); }
00615 
00622   bool Compare (const csStringBase& iStr) const
00623   {
00624     if (&iStr == this)
00625       return true;
00626     size_t const n = iStr.Length();
00627     if (Size != n)
00628       return false;
00629     if (Size == 0 && n == 0)
00630       return true;
00631     return (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0);
00632   }
00633 
00640   bool Compare (const char* iStr) const
00641   { return (strcmp (GetDataSafe(), iStr) == 0); }
00642 
00649   bool CompareNoCase (const csStringBase& iStr) const
00650   {
00651     if (&iStr == this)
00652       return true;
00653     size_t const n = iStr.Length();
00654     if (Size != n)
00655       return false;
00656     if (Size == 0 && n == 0)
00657       return true;
00658     return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0);
00659   }
00660 
00667   bool CompareNoCase (const char* iStr) const
00668   { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); }
00669 
00676   bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const
00677   {
00678     char const* p = GetDataSafe();
00679     if (&iStr == this)
00680       return true;
00681     size_t const n = iStr.Length();
00682     if (n == 0)
00683       return true;
00684     if (n > Size)
00685       return false;
00686     CS_ASSERT(p != 0);
00687     if (ignore_case)
00688       return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0);
00689     else
00690       return (strncmp (p, iStr.GetDataSafe (), n) == 0);
00691   }
00692 
00699   bool StartsWith (const char* iStr, bool ignore_case = false) const
00700   {
00701     char const* p = GetDataSafe();
00702     if (iStr == 0)
00703       return false;
00704     size_t const n = strlen (iStr);
00705     if (n == 0)
00706       return true;
00707     if (n > Size)
00708       return false;
00709     CS_ASSERT(p != 0);
00710     if (ignore_case)
00711       return (csStrNCaseCmp (p, iStr, n) == 0);
00712     else
00713       return (strncmp (p, iStr, n) == 0);
00714   }
00715 
00721   csStringBase Clone () const
00722   { return csStringBase (*this); }
00723 
00731   csStringBase& LTrim();
00732 
00740   csStringBase& RTrim();
00741 
00747   csStringBase& Trim();
00748 
00754   csStringBase& Collapse();
00755 
00764   csStringBase& PadLeft (size_t NewSize, char PadChar = ' ');
00765 
00774   csStringBase& PadRight (size_t NewSize, char PadChar = ' ');
00775 
00787   csStringBase& PadCenter (size_t NewSize, char PadChar = ' ');
00788 
00792   template<typename T>
00793   const csStringBase& operator = (T const& s) { return Replace (s); }
00794 
00796   const csStringBase& operator = (const csStringBase& copy)
00797   { Replace(copy); return *this; }
00798 
00802   template<typename T>
00803   csStringBase &operator += (T const& s) { return Append (s); }
00804 
00805   // Specialization which prevents gcc from barfing on strings allocated via
00806   // CS_ALLOC_STACK_ARRAY().
00807   csStringBase &operator += (char const* s)
00808   { return Append(s); }
00809 
00811   csStringBase operator + (const csStringBase &iStr) const
00812   { return Clone ().Append (iStr); }
00813 
00821   operator const char* () const
00822   { return GetData(); }
00823 
00830   bool operator == (const csStringBase& Str) const
00831   { return Compare (Str); }
00838   bool operator == (const char* Str) const
00839   { return Compare (Str); }
00846   bool operator < (const csStringBase& Str) const
00847   {
00848     return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0;
00849   }
00856   bool operator < (const char* Str) const
00857   {
00858     return strcmp (GetDataSafe (), Str) < 0;
00859   }
00866   bool operator > (const csStringBase& Str) const
00867   {
00868     return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0;
00869   }
00876   bool operator > (const char* Str) const
00877   {
00878     return strcmp (GetDataSafe (), Str) > 0;
00879   }
00886   bool operator != (const csStringBase& Str) const
00887   { return !Compare (Str); }
00894   bool operator != (const char* Str) const
00895   { return !Compare (Str); }
00896 
00904   template <typename T>
00905   csStringBase &operator << (T const& v)
00906   { return Append (v); }
00907 
00908   // Specialization which prevents gcc from barfing on strings allocated via
00909   // CS_ALLOC_STACK_ARRAY().
00910   csStringBase &operator << (char const* v)
00911   { return Append(v); }
00912 
00917   csStringBase& Downcase();
00922   csStringBase& Upcase();
00923 
00934   virtual char* Detach ()
00935   { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; }
00940   uint GetHash() const;
00941 };
00942 
00944 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2)
00945 {
00946   return csStringBase (iStr1).Append (iStr2);
00947 }
00948 
00950 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2)
00951 {
00952   return iStr1.Clone ().Append (iStr2);
00953 }
00954 
00959 template<int LEN = 36>
00960 class csStringFast : public csStringBase
00961 {
00962 protected:
00964   char minibuff[LEN];
00973   size_t miniused;
00974 
00975   virtual void SetCapacityInternal (size_t NewSize, bool soft)
00976   {
00977     if (Data != 0) // If dynamic buffer already allocated, just re-use it.
00978       csStringBase::SetCapacityInternal(NewSize, soft);
00979     else
00980     {
00981       NewSize++; // Plus one for implicit null byte.
00982       if (NewSize <= LEN)
00983         miniused = NewSize;
00984       else
00985       {
00986         CS_ASSERT(MaxSize == 0);
00987         if (soft)
00988           NewSize = ComputeNewSize (NewSize);
00989         Data = new char[NewSize];
00990         MaxSize = NewSize;
00991         if (Size == 0)
00992           Data[0] = '\0';
00993         else
00994           memcpy(Data, minibuff, Size + 1);
00995       }
00996     }
00997   }
00998 
00999   virtual char* GetDataMutable ()
01000   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
01001 
01002 public:
01006   csStringFast () : csStringBase(), miniused(0) { }
01011   csStringFast (size_t Length) : csStringBase(), miniused(0)
01012   { SetCapacity (Length); }
01016   csStringFast (const csStringBase& copy) : csStringBase (), miniused(0) 
01017   { Append (copy); }
01021   csStringFast (const csStringFast& copy) : csStringBase (), miniused(0)
01022   { Append (copy); }
01026   csStringFast (const char* src) : csStringBase(), miniused(0)
01027   { Append (src); }
01031   csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0)
01032   { Append (src, _length); }
01033 
01034   
01036   csStringFast (char c) : csStringBase(), miniused(0)
01037   { Append (c); }
01039   csStringFast (unsigned char c) : csStringBase(), miniused(0)
01040   { Append ((char)c); }
01042   virtual ~csStringFast () { }
01043 
01045   const csStringFast& operator = (const csStringBase& copy)
01046   { Replace(copy); return *this; }
01047 
01049   template<typename T>
01050   const csStringFast& operator = (T const& s) { Replace (s); return *this; }
01051 
01052   virtual char const* GetData () const
01053   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
01054 
01055   virtual size_t GetCapacity() const
01056   { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; }
01057 
01058   virtual void ShrinkBestFit ()
01059   {
01060     if (Size == 0)
01061     {
01062       csStringBase::ShrinkBestFit();
01063       miniused = 0;
01064     }
01065     else
01066     {
01067       size_t needed = Size + 1;
01068       if (needed > LEN)
01069         csStringBase::ShrinkBestFit();
01070       else
01071       {
01072         miniused = needed;
01073         if (Data != 0)
01074         {
01075           memcpy(minibuff, Data, needed); // Includes implicit null byte.
01076           csStringBase::Free();
01077         }
01078       }
01079     }
01080   }
01081 
01082   virtual void Free () { miniused = 0; csStringBase::Free(); }
01083 
01084   virtual char* Detach ()
01085   { 
01086     if (Data != 0)
01087       return csStringBase::Detach();
01088     else if (miniused == 0)
01089       return 0; // Emulate NULL return of csStringBase in this case.
01090     else
01091     {
01092       CS_ASSERT(MaxSize == 0);
01093       char* d = csStrNew (minibuff);
01094       Size = 0; miniused = 0;
01095       return d;
01096     }
01097   }
01098 };
01099 
01100 template<>
01101 class csStringFast<0> : public csStringBase
01102 {
01103 public:
01104   csStringFast () : csStringBase() { }
01105   csStringFast (size_t Length) : csStringBase(Length) { }
01106   csStringFast (const csStringBase& copy) : csStringBase (copy) { }
01107   csStringFast (const char* src) : csStringBase(src) { }
01108   csStringFast (const char* src, size_t _length) : csStringBase(src, _length)
01109   { }
01110   csStringFast (char c) : csStringBase(c) { }
01111   csStringFast (unsigned char c) : csStringBase(c) { }
01112   const csStringFast& operator = (const csStringBase& copy)
01113   { Replace(copy); return *this; }
01114   const csStringFast& operator = (const char* copy)
01115   { Replace(copy); return *this; }
01116   const csStringFast& operator = (char x)
01117   { Replace(x); return *this; }
01118   const csStringFast& operator = (unsigned char x)
01119   { Replace(x); return *this; }
01120   const csStringFast& operator = (bool x)
01121   { Replace(x); return *this; }
01122   const csStringFast& operator = (short x)
01123   { Replace(x); return *this; }
01124   const csStringFast& operator = (unsigned short x)
01125   { Replace(x); return *this; }
01126   const csStringFast& operator = (int x)
01127   { Replace(x); return *this; }
01128   const csStringFast& operator = (unsigned int x)
01129   { Replace(x); return *this; }
01130   const csStringFast& operator = (long x)
01131   { Replace(x); return *this; }
01132   const csStringFast& operator = (unsigned long x)
01133   { Replace(x); return *this; }
01134   const csStringFast& operator = (float x)
01135   { Replace(x); return *this; }
01136   const csStringFast& operator = (double x)
01137   { Replace(x); return *this; }
01138 #ifndef __STRICT_ANSI__
01139   const csStringFast& operator = (longlong x)
01140   { Replace(x); return *this; }
01141   const csStringFast& operator = (ulonglong x)
01142   { Replace(x); return *this; }
01143 #endif
01144 };
01145 
01146 #ifndef SWIG
01147 
01152 typedef csStringFast<> csStringFastDefault;
01153 #else
01154 #define csStringFastDefault csStringFast<36>
01155 %template(csStringParent) csStringFast<36>;
01156 #endif
01157 
01161 class csString : public csStringFastDefault
01162 {
01163 public:
01165   csString () : csStringFast<> () { }
01170   csString (size_t Length) : csStringFast<> (Length) { }
01172 
01173   csString (const csString& copy) :
01174     csStringFast<> ((const csStringBase&)copy) { }
01175   csString (const csStringBase& copy) : csStringFast<> (copy) { }
01177 
01178   csString (const char* src) : csStringFast<> (src) { }
01180   csString (const char* src, size_t _length) : csStringFast<> (src, _length) { }
01182   csString (char c) : csStringFast<> (c) { }
01184   csString (unsigned char c) : csStringFast<> (c) { }
01185 
01187 
01188   const csString& operator = (const csString& copy)
01189   { Replace(copy); return *this; }
01190   const csString& operator = (const csStringBase& copy)
01191   { Replace(copy); return *this; }
01192   const csString& operator = (const char* copy)
01193   { Replace(copy); return *this; }
01194   const csString& operator = (char x)
01195   { Replace(x); return *this; }
01196   const csString& operator = (unsigned char x)
01197   { Replace(x); return *this; }
01198   const csString& operator = (bool x)
01199   { Replace(x); return *this; }
01200   const csString& operator = (short x)
01201   { Replace(x); return *this; }
01202   const csString& operator = (unsigned short x)
01203   { Replace(x); return *this; }
01204   const csString& operator = (int x)
01205   { Replace(x); return *this; }
01206   const csString& operator = (unsigned int x)
01207   { Replace(x); return *this; }
01208   const csString& operator = (long x)
01209   { Replace(x); return *this; }
01210   const csString& operator = (unsigned long x)
01211   { Replace(x); return *this; }
01212   const csString& operator = (float x)
01213   { Replace(x); return *this; }
01214   const csString& operator = (double x)
01215   { Replace(x); return *this; }
01216 #ifndef __STRICT_ANSI__
01217   const csString& operator = (longlong x)
01218   { Replace(x); return *this; }
01219   const csString& operator = (ulonglong x)
01220   { Replace(x); return *this; }
01221 #endif
01222 
01223 };
01224 
01225 #endif // __CS_CSSTRING_H__

Generated for Crystal Space by doxygen 1.4.7