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/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__

Generated for Crystal Space by doxygen 1.4.6