csutil/csstring.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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__