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 
00544   csStringBase& ReplaceAll (const char* search, const char* replacement);
00545 
00551   /* CS_DEPRECATED_METHOD_MSG("Use ReplaceAll() instead.") */
00552   void FindReplace (const char* search, const char* replacement)
00553   { ReplaceAll(search, replacement); }
00554 
00562   csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3);
00563 
00571   csStringBase& FormatV (const char* format, va_list args);
00572 
00582   csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1);
00583 
00593   csStringBase& Replace (const char* Str, size_t Count = (size_t)-1);
00594 
00599   template<typename T>
00600   csStringBase& Replace (T const& val) { Truncate (0); return Append (val); }
00601 
00608   bool Compare (const csStringBase& iStr) const
00609   {
00610     if (&iStr == this)
00611       return true;
00612     size_t const n = iStr.Length();
00613     if (Size != n)
00614       return false;
00615     if (Size == 0 && n == 0)
00616       return true;
00617     return (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0);
00618   }
00619 
00626   bool Compare (const char* iStr) const
00627   { return (strcmp (GetDataSafe(), iStr) == 0); }
00628 
00635   bool CompareNoCase (const csStringBase& iStr) const
00636   {
00637     if (&iStr == this)
00638       return true;
00639     size_t const n = iStr.Length();
00640     if (Size != n)
00641       return false;
00642     if (Size == 0 && n == 0)
00643       return true;
00644     return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0);
00645   }
00646 
00653   bool CompareNoCase (const char* iStr) const
00654   { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); }
00655 
00662   bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const
00663   {
00664     char const* p = GetDataSafe();
00665     if (&iStr == this)
00666       return true;
00667     size_t const n = iStr.Length();
00668     if (n == 0)
00669       return true;
00670     if (n > Size)
00671       return false;
00672     CS_ASSERT(p != 0);
00673     if (ignore_case)
00674       return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0);
00675     else
00676       return (strncmp (p, iStr.GetDataSafe (), n) == 0);
00677   }
00678 
00685   bool StartsWith (const char* iStr, bool ignore_case = false) const
00686   {
00687     char const* p = GetDataSafe();
00688     if (iStr == 0)
00689       return false;
00690     size_t const n = strlen (iStr);
00691     if (n == 0)
00692       return true;
00693     if (n > Size)
00694       return false;
00695     CS_ASSERT(p != 0);
00696     if (ignore_case)
00697       return (csStrNCaseCmp (p, iStr, n) == 0);
00698     else
00699       return (strncmp (p, iStr, n) == 0);
00700   }
00701 
00707   csStringBase Clone () const
00708   { return csStringBase (*this); }
00709 
00717   csStringBase& LTrim();
00718 
00726   csStringBase& RTrim();
00727 
00733   csStringBase& Trim();
00734 
00740   csStringBase& Collapse();
00741 
00750   csStringBase& PadLeft (size_t NewSize, char PadChar = ' ');
00751 
00760   csStringBase& PadRight (size_t NewSize, char PadChar = ' ');
00761 
00773   csStringBase& PadCenter (size_t NewSize, char PadChar = ' ');
00774 
00778   template<typename T>
00779   const csStringBase& operator = (T const& s) { return Replace (s); }
00780 
00782   const csStringBase& operator = (const csStringBase& copy)
00783   { Replace(copy); return *this; }
00784 
00788   template<typename T>
00789   csStringBase &operator += (T const& s) { return Append (s); }
00790 
00791   // Specialization which prevents gcc from barfing on strings allocated via
00792   // CS_ALLOC_STACK_ARRAY().
00793   csStringBase &operator += (char const* s)
00794   { return Append(s); }
00795 
00797   csStringBase operator + (const csStringBase &iStr) const
00798   { return Clone ().Append (iStr); }
00799 
00807   operator const char* () const
00808   { return GetData(); }
00809 
00816   bool operator == (const csStringBase& Str) const
00817   { return Compare (Str); }
00824   bool operator == (const char* Str) const
00825   { return Compare (Str); }
00832   bool operator < (const csStringBase& Str) const
00833   {
00834     return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0;
00835   }
00842   bool operator < (const char* Str) const
00843   {
00844     return strcmp (GetDataSafe (), Str) < 0;
00845   }
00852   bool operator > (const csStringBase& Str) const
00853   {
00854     return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0;
00855   }
00862   bool operator > (const char* Str) const
00863   {
00864     return strcmp (GetDataSafe (), Str) > 0;
00865   }
00872   bool operator != (const csStringBase& Str) const
00873   { return !Compare (Str); }
00880   bool operator != (const char* Str) const
00881   { return !Compare (Str); }
00882 
00890   template <typename T>
00891   csStringBase &operator << (T const& v)
00892   { return Append (v); }
00893 
00894   // Specialization which prevents gcc from barfing on strings allocated via
00895   // CS_ALLOC_STACK_ARRAY().
00896   csStringBase &operator << (char const* v)
00897   { return Append(v); }
00898 
00909   csStringBase& Downcase (uint flags = csUcMapSimple);
00920   csStringBase& Upcase (uint flags = csUcMapSimple);
00921 
00932   virtual char* Detach ()
00933   { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; }
00938   uint GetHash() const;
00939 };
00940 
00942 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2)
00943 {
00944   return csStringBase (iStr1).Append (iStr2);
00945 }
00946 
00948 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2)
00949 {
00950   return iStr1.Clone ().Append (iStr2);
00951 }
00952 
00957 template<int LEN = 36>
00958 class csStringFast : public csStringBase
00959 {
00960 protected:
00962   char minibuff[LEN];
00971   size_t miniused;
00972 
00973   virtual void SetCapacityInternal (size_t NewSize, bool soft)
00974   {
00975     if (Data != 0) // If dynamic buffer already allocated, just re-use it.
00976       csStringBase::SetCapacityInternal(NewSize, soft);
00977     else
00978     {
00979       NewSize++; // Plus one for implicit null byte.
00980       if (NewSize <= LEN)
00981       {
00982         // minibuff may still be wholly uninitialized, so ensure a null terminator
00983         if (miniused == 0) minibuff[0] = 0;
00984         miniused = NewSize;
00985       }
00986       else
00987       {
00988         CS_ASSERT(MaxSize == 0);
00989         if (soft)
00990           NewSize = ComputeNewSize (NewSize);
00991         Data = new char[NewSize];
00992         MaxSize = NewSize;
00993         if (Size == 0)
00994           Data[0] = '\0';
00995         else
00996           memcpy(Data, minibuff, Size + 1);
00997       }
00998     }
00999   }
01000 
01001   virtual char* GetDataMutable ()
01002   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
01003 
01004 public:
01008   csStringFast () : csStringBase(), miniused(0) { }
01013   csStringFast (size_t Length) : csStringBase(), miniused(0)
01014   { SetCapacity (Length); }
01018   csStringFast (const csStringBase& copy) : csStringBase (), miniused(0) 
01019   { Append (copy); }
01023   csStringFast (const csStringFast& copy) : csStringBase (), miniused(0)
01024   { Append (copy); }
01028   csStringFast (const char* src) : csStringBase(), miniused(0)
01029   { Append (src); }
01033   csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0)
01034   { Append (src, _length); }
01035 
01037   csStringFast (const wchar_t* src) : csStringBase (), miniused(0)
01038   { Append (src); }
01040   csStringFast (const wchar_t* src, size_t _length) : csStringBase (), miniused(0)
01041   { Append (src, _length); }
01042   
01044   csStringFast (char c) : csStringBase(), miniused(0)
01045   { Append (c); }
01047   csStringFast (unsigned char c) : csStringBase(), miniused(0)
01048   { Append ((char)c); }
01050   virtual ~csStringFast () { }
01051 
01053   const csStringFast& operator = (const csStringBase& copy)
01054   { Replace(copy); return *this; }
01055 
01057   template<typename T>
01058   const csStringFast& operator = (T const& s) { Replace (s); return *this; }
01059 
01060   virtual char const* GetData () const
01061   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
01062 
01063   virtual size_t GetCapacity() const
01064   { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; }
01065 
01066   virtual void ShrinkBestFit ()
01067   {
01068     if (Size == 0)
01069     {
01070       csStringBase::ShrinkBestFit();
01071       miniused = 0;
01072     }
01073     else
01074     {
01075       size_t needed = Size + 1;
01076       if (needed > LEN)
01077         csStringBase::ShrinkBestFit();
01078       else
01079       {
01080         miniused = needed;
01081         if (Data != 0)
01082         {
01083           memcpy(minibuff, Data, needed); // Includes implicit null byte.
01084           csStringBase::Free();
01085         }
01086       }
01087     }
01088   }
01089 
01090   virtual void Free () { miniused = 0; csStringBase::Free(); }
01091 
01092   virtual char* Detach ()
01093   { 
01094     if (Data != 0)
01095       return csStringBase::Detach();
01096     else if (miniused == 0)
01097       return 0; // Emulate NULL return of csStringBase in this case.
01098     else
01099     {
01100       CS_ASSERT(MaxSize == 0);
01101       char* d = csStrNew (minibuff);
01102       Size = 0; miniused = 0;
01103       return d;
01104     }
01105   }
01106 };
01107 
01108 template<>
01109 class csStringFast<0> : public csStringBase
01110 {
01111 public:
01112   csStringFast () : csStringBase() { }
01113   csStringFast (size_t Length) : csStringBase(Length) { }
01114   csStringFast (const csStringBase& copy) : csStringBase (copy) { }
01115   csStringFast (const char* src) : csStringBase(src) { }
01116   csStringFast (const char* src, size_t _length) : csStringBase(src, _length)
01117   { }
01118   csStringFast (const wchar_t* src) : csStringBase (src) {}
01119   csStringFast (const wchar_t* src, size_t _length) : csStringBase (src, _length) { }
01120   csStringFast (char c) : csStringBase(c) { }
01121   csStringFast (unsigned char c) : csStringBase(c) { }
01122   const csStringFast& operator = (const csStringBase& copy)
01123   { Replace(copy); return *this; }
01124   const csStringFast& operator = (const char* copy)
01125   { Replace(copy); return *this; }
01126   const csStringFast& operator = (char x)
01127   { Replace(x); return *this; }
01128   const csStringFast& operator = (unsigned char x)
01129   { Replace(x); return *this; }
01130   const csStringFast& operator = (bool x)
01131   { Replace(x); return *this; }
01132   const csStringFast& operator = (short x)
01133   { Replace(x); return *this; }
01134   const csStringFast& operator = (unsigned short x)
01135   { Replace(x); return *this; }
01136   const csStringFast& operator = (int x)
01137   { Replace(x); return *this; }
01138   const csStringFast& operator = (unsigned int x)
01139   { Replace(x); return *this; }
01140   const csStringFast& operator = (long x)
01141   { Replace(x); return *this; }
01142   const csStringFast& operator = (unsigned long x)
01143   { Replace(x); return *this; }
01144   const csStringFast& operator = (float x)
01145   { Replace(x); return *this; }
01146   const csStringFast& operator = (double x)
01147   { Replace(x); return *this; }
01148 #ifndef __STRICT_ANSI__
01149   const csStringFast& operator = (longlong x)
01150   { Replace(x); return *this; }
01151   const csStringFast& operator = (ulonglong x)
01152   { Replace(x); return *this; }
01153 #endif
01154 };
01155 
01156 #ifndef SWIG
01157 
01162 typedef csStringFast<> csStringFastDefault;
01163 #else
01164 #define csStringFastDefault csStringFast<36>
01165 %template(csStringParent) csStringFast<36>;
01166 #endif
01167 
01171 class csString : public csStringFastDefault
01172 {
01173 public:
01175   csString () : csStringFast<> () { }
01180   csString (size_t Length) : csStringFast<> (Length) { }
01182 
01183   csString (const csString& copy) :
01184     csStringFast<> ((const csStringBase&)copy) { }
01185   csString (const csStringBase& copy) : csStringFast<> (copy) { }
01187 
01188   csString (const char* src) : csStringFast<> (src) { }
01190   csString (const char* src, size_t _length) : csStringFast<> (src, _length) { }
01192   csString (const wchar_t* src) : csStringFast<> (src) {}
01194   csString (const wchar_t* src, size_t _length) : csStringFast<> (src, _length) { }
01195 
01197   csString (char c) : csStringFast<> (c) { }
01199   csString (unsigned char c) : csStringFast<> (c) { }
01200 
01202 
01203   const csString& operator = (const csString& copy)
01204   { Replace(copy); return *this; }
01205   const csString& operator = (const csStringBase& copy)
01206   { Replace(copy); return *this; }
01207   const csString& operator = (const char* copy)
01208   { Replace(copy); return *this; }
01209   const csString& operator = (char x)
01210   { Replace(x); return *this; }
01211   const csString& operator = (unsigned char x)
01212   { Replace(x); return *this; }
01213   const csString& operator = (bool x)
01214   { Replace(x); return *this; }
01215   const csString& operator = (short x)
01216   { Replace(x); return *this; }
01217   const csString& operator = (unsigned short x)
01218   { Replace(x); return *this; }
01219   const csString& operator = (int x)
01220   { Replace(x); return *this; }
01221   const csString& operator = (unsigned int x)
01222   { Replace(x); return *this; }
01223   const csString& operator = (long x)
01224   { Replace(x); return *this; }
01225   const csString& operator = (unsigned long x)
01226   { Replace(x); return *this; }
01227   const csString& operator = (float x)
01228   { Replace(x); return *this; }
01229   const csString& operator = (double x)
01230   { Replace(x); return *this; }
01231 #ifndef __STRICT_ANSI__
01232   const csString& operator = (longlong x)
01233   { Replace(x); return *this; }
01234   const csString& operator = (ulonglong x)
01235   { Replace(x); return *this; }
01236 #endif
01237 
01238 };
01239 
01240 #endif // __CS_CSSTRING_H__

Generated for Crystal Space 2.0 by doxygen 1.7.6.1