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 
00294   virtual void Free ();
00295 
00312   csStringBase& Truncate (size_t Len);
00313 
00319   csStringBase& Empty() { return Truncate (0); }
00320 
00330   virtual void ShrinkBestFit ();
00331 
00341   csStringBase& Reclaim () { ShrinkBestFit(); return *this; }
00342 
00349   csStringBase& Clear () { return Empty(); }
00350 
00358   CS_VISIBILITY_DEFAULT // <- @@@ FIXME: needed for gcc 4.1.0
00359   virtual char const* GetData () const
00360   { return Data; }
00361 
00371    char const* GetDataSafe() const
00372    { char const* p = GetData(); return p != 0 ? p : ""; }
00373 
00379   size_t Length () const
00380   { return Size; }
00381 
00387   bool IsEmpty () const
00388   { return (Size == 0); }
00389 
00391   char& operator [] (size_t n)
00392   {
00393     CS_ASSERT (n < Size);
00394     return GetDataMutable()[n];
00395   }
00396 
00398   char operator [] (size_t n) const
00399   {
00400     CS_ASSERT (n < Size);
00401     return GetData()[n];
00402   }
00403 
00410   void SetAt (size_t n, const char c)
00411   {
00412     CS_ASSERT (n < Size);
00413     GetDataMutable() [n] = c;
00414   }
00415 
00417   char GetAt (size_t n) const
00418   {
00419     CS_ASSERT (n < Size);
00420     return GetData() [n];
00421   }
00422 
00429   csStringBase& DeleteAt (size_t Pos, size_t Count = 1);
00430 
00437   csStringBase& Insert (size_t Pos, const csStringBase& Str);
00438 
00445   csStringBase& Insert (size_t Pos, const char* Str);
00446 
00453   csStringBase& Insert (size_t Pos, char C);
00454 
00463   csStringBase& Overwrite (size_t Pos, const csStringBase& Str);
00464 
00471   csStringBase Slice (size_t start, size_t len = (size_t)-1) const;
00472 
00483   void SubString (csStringBase& sub, size_t start, 
00484     size_t len = (size_t)-1) const;
00485 
00492   size_t FindFirst (char c, size_t pos = 0) const;
00493 
00500   size_t FindFirst (const char *c, size_t pos = 0) const;
00501 
00509   size_t FindLast (char c, size_t pos = (size_t)-1) const;
00510   
00518   size_t FindLast (const char *c, size_t pos = (size_t)-1) const;
00519 
00526   size_t Find (const char* search, size_t pos = 0) const;
00527 
00535   /* CS_DEPRECATED_METHOD_MSG("Use Find() instead.") */
00536   size_t FindStr (const char* search, size_t pos = 0) const
00537   { return Find(search, pos); }
00538 
00543   void ReplaceAll (const char* search, const char* replacement);
00544 
00550   /* CS_DEPRECATED_METHOD_MSG("Use ReplaceAll() instead.") */
00551   void FindReplace (const char* search, const char* replacement)
00552   { ReplaceAll(search, replacement); }
00553 
00561   csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3);
00562 
00570   csStringBase& FormatV (const char* format, va_list args);
00571 
00581   csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1);
00582 
00592   csStringBase& Replace (const char* Str, size_t Count = (size_t)-1);
00593 
00598   template<typename T>
00599   csStringBase& Replace (T const& val) { Truncate (0); return Append (val); }
00600 
00607   bool Compare (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 (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0);
00617   }
00618 
00625   bool Compare (const char* iStr) const
00626   { return (strcmp (GetDataSafe(), iStr) == 0); }
00627 
00634   bool CompareNoCase (const csStringBase& iStr) const
00635   {
00636     if (&iStr == this)
00637       return true;
00638     size_t const n = iStr.Length();
00639     if (Size != n)
00640       return false;
00641     if (Size == 0 && n == 0)
00642       return true;
00643     return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0);
00644   }
00645 
00652   bool CompareNoCase (const char* iStr) const
00653   { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); }
00654 
00661   bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const
00662   {
00663     char const* p = GetDataSafe();
00664     if (&iStr == this)
00665       return true;
00666     size_t const n = iStr.Length();
00667     if (n == 0)
00668       return true;
00669     if (n > Size)
00670       return false;
00671     CS_ASSERT(p != 0);
00672     if (ignore_case)
00673       return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0);
00674     else
00675       return (strncmp (p, iStr.GetDataSafe (), n) == 0);
00676   }
00677 
00684   bool StartsWith (const char* iStr, bool ignore_case = false) const
00685   {
00686     char const* p = GetDataSafe();
00687     if (iStr == 0)
00688       return false;
00689     size_t const n = strlen (iStr);
00690     if (n == 0)
00691       return true;
00692     if (n > Size)
00693       return false;
00694     CS_ASSERT(p != 0);
00695     if (ignore_case)
00696       return (csStrNCaseCmp (p, iStr, n) == 0);
00697     else
00698       return (strncmp (p, iStr, n) == 0);
00699   }
00700 
00706   csStringBase Clone () const
00707   { return csStringBase (*this); }
00708 
00716   csStringBase& LTrim();
00717 
00725   csStringBase& RTrim();
00726 
00732   csStringBase& Trim();
00733 
00739   csStringBase& Collapse();
00740 
00749   csStringBase& PadLeft (size_t NewSize, char PadChar = ' ');
00750 
00759   csStringBase& PadRight (size_t NewSize, char PadChar = ' ');
00760 
00772   csStringBase& PadCenter (size_t NewSize, char PadChar = ' ');
00773 
00777   template<typename T>
00778   const csStringBase& operator = (T const& s) { return Replace (s); }
00779 
00781   const csStringBase& operator = (const csStringBase& copy)
00782   { Replace(copy); return *this; }
00783 
00787   template<typename T>
00788   csStringBase &operator += (T const& s) { return Append (s); }
00789 
00790   // Specialization which prevents gcc from barfing on strings allocated via
00791   // CS_ALLOC_STACK_ARRAY().
00792   csStringBase &operator += (char const* s)
00793   { return Append(s); }
00794 
00796   csStringBase operator + (const csStringBase &iStr) const
00797   { return Clone ().Append (iStr); }
00798 
00806   operator const char* () const
00807   { return GetData(); }
00808 
00815   bool operator == (const csStringBase& Str) const
00816   { return Compare (Str); }
00823   bool operator == (const char* Str) const
00824   { return Compare (Str); }
00831   bool operator < (const csStringBase& Str) const
00832   {
00833     return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0;
00834   }
00841   bool operator < (const char* Str) const
00842   {
00843     return strcmp (GetDataSafe (), Str) < 0;
00844   }
00851   bool operator > (const csStringBase& Str) const
00852   {
00853     return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0;
00854   }
00861   bool operator > (const char* Str) const
00862   {
00863     return strcmp (GetDataSafe (), Str) > 0;
00864   }
00871   bool operator != (const csStringBase& Str) const
00872   { return !Compare (Str); }
00879   bool operator != (const char* Str) const
00880   { return !Compare (Str); }
00881 
00889   template <typename T>
00890   csStringBase &operator << (T const& v)
00891   { return Append (v); }
00892 
00893   // Specialization which prevents gcc from barfing on strings allocated via
00894   // CS_ALLOC_STACK_ARRAY().
00895   csStringBase &operator << (char const* v)
00896   { return Append(v); }
00897 
00908   csStringBase& Downcase (uint flags = csUcMapSimple);
00919   csStringBase& Upcase (uint flags = csUcMapSimple);
00920 
00931   virtual char* Detach ()
00932   { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; }
00937   uint GetHash() const;
00938 };
00939 
00941 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2)
00942 {
00943   return csStringBase (iStr1).Append (iStr2);
00944 }
00945 
00947 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2)
00948 {
00949   return iStr1.Clone ().Append (iStr2);
00950 }
00951 
00956 template<int LEN = 36>
00957 class csStringFast : public csStringBase
00958 {
00959 protected:
00961   char minibuff[LEN];
00970   size_t miniused;
00971 
00972   virtual void SetCapacityInternal (size_t NewSize, bool soft)
00973   {
00974     if (Data != 0) // If dynamic buffer already allocated, just re-use it.
00975       csStringBase::SetCapacityInternal(NewSize, soft);
00976     else
00977     {
00978       NewSize++; // Plus one for implicit null byte.
00979       if (NewSize <= LEN)
00980         miniused = NewSize;
00981       else
00982       {
00983         CS_ASSERT(MaxSize == 0);
00984         if (soft)
00985           NewSize = ComputeNewSize (NewSize);
00986         Data = new char[NewSize];
00987         MaxSize = NewSize;
00988         if (Size == 0)
00989           Data[0] = '\0';
00990         else
00991           memcpy(Data, minibuff, Size + 1);
00992       }
00993     }
00994   }
00995 
00996   virtual char* GetDataMutable ()
00997   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
00998 
00999 public:
01003   csStringFast () : csStringBase(), miniused(0) { }
01008   csStringFast (size_t Length) : csStringBase(), miniused(0)
01009   { SetCapacity (Length); }
01013   csStringFast (const csStringBase& copy) : csStringBase (), miniused(0) 
01014   { Append (copy); }
01018   csStringFast (const csStringFast& copy) : csStringBase (), miniused(0)
01019   { Append (copy); }
01023   csStringFast (const char* src) : csStringBase(), miniused(0)
01024   { Append (src); }
01028   csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0)
01029   { Append (src, _length); }
01030 
01031   
01033   csStringFast (char c) : csStringBase(), miniused(0)
01034   { Append (c); }
01036   csStringFast (unsigned char c) : csStringBase(), miniused(0)
01037   { Append ((char)c); }
01039   virtual ~csStringFast () { }
01040 
01042   const csStringFast& operator = (const csStringBase& copy)
01043   { Replace(copy); return *this; }
01044 
01046   template<typename T>
01047   const csStringFast& operator = (T const& s) { Replace (s); return *this; }
01048 
01049   virtual char const* GetData () const
01050   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
01051 
01052   virtual size_t GetCapacity() const
01053   { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; }
01054 
01055   virtual void ShrinkBestFit ()
01056   {
01057     if (Size == 0)
01058     {
01059       csStringBase::ShrinkBestFit();
01060       miniused = 0;
01061     }
01062     else
01063     {
01064       size_t needed = Size + 1;
01065       if (needed > LEN)
01066         csStringBase::ShrinkBestFit();
01067       else
01068       {
01069         miniused = needed;
01070         if (Data != 0)
01071         {
01072           memcpy(minibuff, Data, needed); // Includes implicit null byte.
01073           csStringBase::Free();
01074         }
01075       }
01076     }
01077   }
01078 
01079   virtual void Free () { miniused = 0; csStringBase::Free(); }
01080 
01081   virtual char* Detach ()
01082   { 
01083     if (Data != 0)
01084       return csStringBase::Detach();
01085     else if (miniused == 0)
01086       return 0; // Emulate NULL return of csStringBase in this case.
01087     else
01088     {
01089       CS_ASSERT(MaxSize == 0);
01090       char* d = csStrNew (minibuff);
01091       Size = 0; miniused = 0;
01092       return d;
01093     }
01094   }
01095 };
01096 
01097 template<>
01098 class csStringFast<0> : public csStringBase
01099 {
01100 public:
01101   csStringFast () : csStringBase() { }
01102   csStringFast (size_t Length) : csStringBase(Length) { }
01103   csStringFast (const csStringBase& copy) : csStringBase (copy) { }
01104   csStringFast (const char* src) : csStringBase(src) { }
01105   csStringFast (const char* src, size_t _length) : csStringBase(src, _length)
01106   { }
01107   csStringFast (char c) : csStringBase(c) { }
01108   csStringFast (unsigned char c) : csStringBase(c) { }
01109   const csStringFast& operator = (const csStringBase& copy)
01110   { Replace(copy); return *this; }
01111   const csStringFast& operator = (const char* copy)
01112   { Replace(copy); return *this; }
01113   const csStringFast& operator = (char x)
01114   { Replace(x); return *this; }
01115   const csStringFast& operator = (unsigned char x)
01116   { Replace(x); return *this; }
01117   const csStringFast& operator = (bool x)
01118   { Replace(x); return *this; }
01119   const csStringFast& operator = (short x)
01120   { Replace(x); return *this; }
01121   const csStringFast& operator = (unsigned short x)
01122   { Replace(x); return *this; }
01123   const csStringFast& operator = (int x)
01124   { Replace(x); return *this; }
01125   const csStringFast& operator = (unsigned int x)
01126   { Replace(x); return *this; }
01127   const csStringFast& operator = (long x)
01128   { Replace(x); return *this; }
01129   const csStringFast& operator = (unsigned long x)
01130   { Replace(x); return *this; }
01131   const csStringFast& operator = (float x)
01132   { Replace(x); return *this; }
01133   const csStringFast& operator = (double x)
01134   { Replace(x); return *this; }
01135 #ifndef __STRICT_ANSI__
01136   const csStringFast& operator = (longlong x)
01137   { Replace(x); return *this; }
01138   const csStringFast& operator = (ulonglong x)
01139   { Replace(x); return *this; }
01140 #endif
01141 };
01142 
01143 #ifndef SWIG
01144 
01149 typedef csStringFast<> csStringFastDefault;
01150 #else
01151 #define csStringFastDefault csStringFast<36>
01152 %template(csStringParent) csStringFast<36>;
01153 #endif
01154 
01158 class csString : public csStringFastDefault
01159 {
01160 public:
01162   csString () : csStringFast<> () { }
01167   csString (size_t Length) : csStringFast<> (Length) { }
01169 
01170   csString (const csString& copy) :
01171     csStringFast<> ((const csStringBase&)copy) { }
01172   csString (const csStringBase& copy) : csStringFast<> (copy) { }
01174 
01175   csString (const char* src) : csStringFast<> (src) { }
01177   csString (const char* src, size_t _length) : csStringFast<> (src, _length) { }
01179   csString (char c) : csStringFast<> (c) { }
01181   csString (unsigned char c) : csStringFast<> (c) { }
01182 
01184 
01185   const csString& operator = (const csString& copy)
01186   { Replace(copy); return *this; }
01187   const csString& operator = (const csStringBase& copy)
01188   { Replace(copy); return *this; }
01189   const csString& operator = (const char* copy)
01190   { Replace(copy); return *this; }
01191   const csString& operator = (char x)
01192   { Replace(x); return *this; }
01193   const csString& operator = (unsigned char x)
01194   { Replace(x); return *this; }
01195   const csString& operator = (bool x)
01196   { Replace(x); return *this; }
01197   const csString& operator = (short x)
01198   { Replace(x); return *this; }
01199   const csString& operator = (unsigned short x)
01200   { Replace(x); return *this; }
01201   const csString& operator = (int x)
01202   { Replace(x); return *this; }
01203   const csString& operator = (unsigned int x)
01204   { Replace(x); return *this; }
01205   const csString& operator = (long x)
01206   { Replace(x); return *this; }
01207   const csString& operator = (unsigned long x)
01208   { Replace(x); return *this; }
01209   const csString& operator = (float x)
01210   { Replace(x); return *this; }
01211   const csString& operator = (double x)
01212   { Replace(x); return *this; }
01213 #ifndef __STRICT_ANSI__
01214   const csString& operator = (longlong x)
01215   { Replace(x); return *this; }
01216   const csString& operator = (ulonglong x)
01217   { Replace(x); return *this; }
01218 #endif
01219 
01220 };
01221 
01222 #endif // __CS_CSSTRING_H__

Generated for Crystal Space 1.2.1 by doxygen 1.5.3