CrystalSpace

Public API Reference

Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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 
00053 class CS_CRYSTALSPACE_EXPORT csStringBase
00054 {
00055 protected:
00060   enum { DEFAULT_GROW_BY = 64 };
00061 
00063   char* Data;
00065   size_t Size;
00067   size_t MaxSize;
00072   size_t GrowBy;
00073 
00079   void ExpandIfNeeded (size_t NewSize);
00080 
00085   virtual void SetCapacityInternal (size_t NewSize, bool soft);
00086 
00088   size_t ComputeNewSize (size_t NewSize);
00089 
00101   virtual char* GetDataMutable ()
00102   { return Data; }
00103 
00104 public:
00112   void SetCapacity (size_t NewSize);
00113 
00118   virtual size_t GetCapacity() const
00119   { return MaxSize > 0 ? MaxSize - 1 : 0; }
00120 
00128   csStringBase& Append (const char* Str, size_t Count = (size_t)-1);
00129 
00137   csStringBase& Append (const csStringBase& Str, size_t Count = (size_t)-1);
00138 
00143   csStringBase& Append (char c);
00144 
00149   /*csStringBase& Append (unsigned char c)
00150   { return Append(char(c)); }*/
00151 
00153   csStringBase& Append (bool b) { return Append (b ? "1" : "0"); }
00154 
00160   csStringBase& AppendFmt (const char* format, ...) CS_GNUC_PRINTF (2, 3);
00161   csStringBase& AppendFmtV (const char* format, va_list args);
00165 
00166   csStringBase& Append (short v) { return AppendFmt ("%hd", v); }
00167   csStringBase& Append (unsigned short v) { return AppendFmt ("%hu", v); }
00168   csStringBase& Append (int v) { return AppendFmt ("%d", v); }
00169   csStringBase& Append (unsigned int v) { return AppendFmt ("%u", v); }
00170   csStringBase& Append (long v) { return AppendFmt ("%ld", v); }
00171   csStringBase& Append (unsigned long v) { return AppendFmt ("%lu", v); }
00172   csStringBase& Append (float v) { return AppendFmt ("%g", v); }
00173   csStringBase& Append (double v) { return AppendFmt ("%g", v); }
00174 #ifndef __STRICT_ANSI__
00175   csStringBase& Append (longlong v) { return AppendFmt ("%lld", v); }
00176   csStringBase& Append (ulonglong v) { return AppendFmt ("%llu", v); }
00177 #endif
00178 
00184   csStringBase () : Data (0), Size (0), MaxSize (0), GrowBy (DEFAULT_GROW_BY)
00185   {}
00186 
00193   csStringBase (size_t Length) : Data (0), Size (0), MaxSize (0),
00194     GrowBy (DEFAULT_GROW_BY)
00195   { SetCapacity (Length); }
00196 
00202   csStringBase (const csStringBase& copy) : Data (0), Size (0), MaxSize (0),
00203     GrowBy (DEFAULT_GROW_BY)
00204   { Append (copy); }
00205 
00211   csStringBase (const char* src) : Data (0), Size (0), MaxSize (0),
00212     GrowBy (DEFAULT_GROW_BY)
00213   { Append (src); }
00214 
00220   csStringBase (const char* src, size_t _length) : Data (0), Size (0), MaxSize (0),
00221     GrowBy (DEFAULT_GROW_BY)
00222   { Append (src, _length); }
00223 
00225   csStringBase (char c) : Data (0), Size (0), MaxSize (0),
00226     GrowBy (DEFAULT_GROW_BY)
00227   { Append (c); }
00228 
00230   csStringBase (unsigned char c) : Data(0), Size (0), MaxSize (0),
00231     GrowBy (DEFAULT_GROW_BY)
00232   { Append ((char) c); }
00233 
00235   virtual ~csStringBase ();
00236 
00249   void SetGrowsBy(size_t);
00250 
00256   size_t GetGrowsBy() const
00257   { return GrowBy; }
00258 
00263   CS_DEPRECATED_METHOD void SetGrowsExponentially(bool b)
00264   { SetGrowsBy(b ? 0 : DEFAULT_GROW_BY); }
00265 
00270   CS_DEPRECATED_METHOD bool GetGrowsExponentially() const
00271   { return GetGrowsBy() == 0; }
00272 
00279   virtual void Free ();
00280 
00297   csStringBase& Truncate (size_t Len);
00298 
00304   csStringBase& Empty() { return Truncate (0); }
00305 
00315   virtual void ShrinkBestFit ();
00316 
00326   csStringBase& Reclaim () { ShrinkBestFit(); return *this; }
00327 
00334   csStringBase& Clear () { return Empty(); }
00335 
00343   virtual char const* GetData () const
00344   { return Data; }
00345 
00355    char const* GetDataSafe() const
00356    { char const* p = GetData(); return p != 0 ? p : ""; }
00357 
00363   size_t Length () const
00364   { return Size; }
00365 
00371   bool IsEmpty () const
00372   { return (Size == 0); }
00373 
00375   char& operator [] (size_t n)
00376   {
00377     CS_ASSERT (n < Size);
00378     return GetDataMutable()[n];
00379   }
00380 
00382   char operator [] (size_t n) const
00383   {
00384     CS_ASSERT (n < Size);
00385     return GetData()[n];
00386   }
00387 
00394   void SetAt (size_t n, const char c)
00395   {
00396     CS_ASSERT (n < Size);
00397     GetDataMutable() [n] = c;
00398   }
00399 
00401   char GetAt (size_t n) const
00402   {
00403     CS_ASSERT (n < Size);
00404     return GetData() [n];
00405   }
00406 
00413   csStringBase& DeleteAt (size_t Pos, size_t Count = 1);
00414 
00421   csStringBase& Insert (size_t Pos, const csStringBase& Str);
00422 
00429   csStringBase& Insert (size_t Pos, const char* Str);
00430 
00437   csStringBase& Insert (size_t Pos, char C);
00438 
00447   csStringBase& Overwrite (size_t Pos, const csStringBase& Str);
00448 
00455   csStringBase Slice (size_t start, size_t len = (size_t)-1) const;
00456 
00467   void SubString (csStringBase& sub, size_t start, 
00468     size_t len = (size_t)-1) const;
00469 
00476   size_t FindFirst (char c, size_t pos = 0) const;
00477 
00484   size_t FindFirst (const char *c, size_t pos = 0) const;
00485 
00493   size_t FindLast (char c, size_t pos = (size_t)-1) const;
00494   
00501   size_t Find (const char* search, size_t pos = 0) const;
00502 
00510   /* CS_DEPRECATED_METHOD */
00511   size_t FindStr (const char* search, size_t pos = 0) const
00512   { return Find(search, pos); }
00513 
00518   void ReplaceAll (const char* search, const char* replacement);
00519 
00525   /* CS_DEPRECATED_METHOD */
00526   void FindReplace (const char* search, const char* replacement)
00527   { ReplaceAll(search, replacement); }
00528 
00536   csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3);
00537 
00545   csStringBase& FormatV (const char* format, va_list args);
00546 
00556   csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1);
00557 
00567   csStringBase& Replace (const char* Str, size_t Count = (size_t)-1);
00568 
00573   template<typename T>
00574   csStringBase& Replace (T const& val) { Truncate (0); return Append (val); }
00575 
00582   bool Compare (const csStringBase& iStr) const
00583   {
00584     if (&iStr == this)
00585       return true;
00586     size_t const n = iStr.Length();
00587     if (Size != n)
00588       return false;
00589     if (Size == 0 && n == 0)
00590       return true;
00591     return (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0);
00592   }
00593 
00600   bool Compare (const char* iStr) const
00601   { return (strcmp (GetDataSafe(), iStr) == 0); }
00602 
00609   bool CompareNoCase (const csStringBase& iStr) const
00610   {
00611     if (&iStr == this)
00612       return true;
00613     size_t const n = iStr.Length();
00614     if (Size != n)
00615       return false;
00616     if (Size == 0 && n == 0)
00617       return true;
00618     return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0);
00619   }
00620 
00627   bool CompareNoCase (const char* iStr) const
00628   { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); }
00629 
00636   bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const
00637   {
00638     char const* p = GetDataSafe();
00639     if (&iStr == this)
00640       return true;
00641     size_t const n = iStr.Length();
00642     if (n == 0)
00643       return true;
00644     if (n > Size)
00645       return false;
00646     CS_ASSERT(p != 0);
00647     if (ignore_case)
00648       return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0);
00649     else
00650       return (strncmp (p, iStr.GetDataSafe (), n) == 0);
00651   }
00652 
00659   bool StartsWith (const char* iStr, bool ignore_case = false) const
00660   {
00661     char const* p = GetDataSafe();
00662     if (iStr == 0)
00663       return false;
00664     size_t const n = strlen (iStr);
00665     if (n == 0)
00666       return true;
00667     if (n > Size)
00668       return false;
00669     CS_ASSERT(p != 0);
00670     if (ignore_case)
00671       return (csStrNCaseCmp (p, iStr, n) == 0);
00672     else
00673       return (strncmp (p, iStr, n) == 0);
00674   }
00675 
00681   csStringBase Clone () const
00682   { return csStringBase (*this); }
00683 
00691   csStringBase& LTrim();
00692 
00700   csStringBase& RTrim();
00701 
00707   csStringBase& Trim();
00708 
00714   csStringBase& Collapse();
00715 
00724   csStringBase& PadLeft (size_t NewSize, char PadChar = ' ');
00725 
00734   csStringBase& PadRight (size_t NewSize, char PadChar = ' ');
00735 
00747   csStringBase& PadCenter (size_t NewSize, char PadChar = ' ');
00748 
00752   template<typename T>
00753   const csStringBase& operator = (T const& s) { return Replace (s); }
00754 
00758   template<typename T>
00759   csStringBase &operator += (T const& s) { return Append (s); }
00760 
00761   // Specialization which prevents gcc from barfing on strings allocated via
00762   // CS_ALLOC_STACK_ARRAY().
00763   csStringBase &operator += (char const* s)
00764   { return Append(s); }
00765 
00767   csStringBase operator + (const csStringBase &iStr) const
00768   { return Clone ().Append (iStr); }
00769 
00777   operator const char* () const
00778   { return GetData(); }
00779 
00786   bool operator == (const csStringBase& Str) const
00787   { return Compare (Str); }
00794   bool operator == (const char* Str) const
00795   { return Compare (Str); }
00802   bool operator < (const csStringBase& Str) const
00803   {
00804     return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0;
00805   }
00812   bool operator < (const char* Str) const
00813   {
00814     return strcmp (GetDataSafe (), Str) < 0;
00815   }
00822   bool operator > (const csStringBase& Str) const
00823   {
00824     return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0;
00825   }
00832   bool operator > (const char* Str) const
00833   {
00834     return strcmp (GetDataSafe (), Str) > 0;
00835   }
00842   bool operator != (const csStringBase& Str) const
00843   { return !Compare (Str); }
00850   bool operator != (const char* Str) const
00851   { return !Compare (Str); }
00852 
00860   template <typename T>
00861   csStringBase &operator << (T const& v)
00862   { return Append (v); }
00863 
00864   // Specialization which prevents gcc from barfing on strings allocated via
00865   // CS_ALLOC_STACK_ARRAY().
00866   csStringBase &operator << (char const* v)
00867   { return Append(v); }
00868 
00873   csStringBase& Downcase();
00878   csStringBase& Upcase();
00879 
00890   virtual char* Detach ()
00891   { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; }
00896   uint GetHash() const;
00897 };
00898 
00900 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2)
00901 {
00902   return csStringBase (iStr1).Append (iStr2);
00903 }
00904 
00906 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2)
00907 {
00908   return iStr1.Clone ().Append (iStr2);
00909 }
00910 
00915 template<int LEN = 36>
00916 class csStringFast : public csStringBase
00917 {
00918 protected:
00920   char minibuff[LEN];
00929   size_t miniused;
00930 
00931   virtual void SetCapacityInternal (size_t NewSize, bool soft)
00932   {
00933     if (Data != 0) // If dynamic buffer already allocated, just re-use it.
00934       csStringBase::SetCapacityInternal(NewSize, soft);
00935     else
00936     {
00937       NewSize++; // Plus one for implicit null byte.
00938       if (NewSize <= LEN)
00939         miniused = NewSize;
00940       else
00941       {
00942         CS_ASSERT(MaxSize == 0);
00943         if (soft)
00944           NewSize = ComputeNewSize (NewSize);
00945         Data = new char[NewSize];
00946         MaxSize = NewSize;
00947         if (Size == 0)
00948           Data[0] = '\0';
00949         else
00950           memcpy(Data, minibuff, Size + 1);
00951       }
00952     }
00953   }
00954 
00955   virtual char* GetDataMutable ()
00956   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
00957 
00958 public:
00962   csStringFast () : csStringBase(), miniused(0) { }
00967   csStringFast (size_t Length) : csStringBase(), miniused(0)
00968   { SetCapacity (Length); }
00972   csStringFast (const csStringBase& copy) : csStringBase (), miniused(0) 
00973   { Append (copy); }
00977   csStringFast (const csStringFast& copy) : csStringBase (), miniused(0)
00978   { Append (copy); }
00982   csStringFast (const char* src) : csStringBase(), miniused(0)
00983   { Append (src); }
00987   csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0)
00988   { Append (src, _length); }
00989 
00990   
00992   csStringFast (char c) : csStringBase(), miniused(0)
00993   { Append (c); }
00995   csStringFast (unsigned char c) : csStringBase(), miniused(0)
00996   { Append ((char)c); }
00998   virtual ~csStringFast () { }
00999 
01001   const csStringFast& operator = (const csStringBase& copy)
01002   { Replace(copy); return *this; }
01003 
01005   template<typename T>
01006   const csStringFast& operator = (T const& s) { Replace (s); return *this; }
01007 
01008   virtual char const* GetData () const
01009   { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); }
01010 
01011   virtual size_t GetCapacity() const
01012   { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; }
01013 
01014   virtual void ShrinkBestFit ()
01015   {
01016     if (Size == 0)
01017     {
01018       csStringBase::ShrinkBestFit();
01019       miniused = 0;
01020     }
01021     else
01022     {
01023       size_t needed = Size + 1;
01024       if (needed > LEN)
01025         csStringBase::ShrinkBestFit();
01026       else
01027       {
01028         miniused = needed;
01029         if (Data != 0)
01030         {
01031           memcpy(minibuff, Data, needed); // Includes implicit null byte.
01032           csStringBase::Free();
01033         }
01034       }
01035     }
01036   }
01037 
01038   virtual void Free () { miniused = 0; csStringBase::Free(); }
01039 
01040   virtual char* Detach ()
01041   { 
01042     if (Data != 0)
01043       return csStringBase::Detach();
01044     else if (miniused == 0)
01045       return 0; // Emulate NULL return of csStringBase in this case.
01046     else
01047     {
01048       CS_ASSERT(MaxSize == 0);
01049       char* d = csStrNew (minibuff);
01050       Size = 0; miniused = 0;
01051       return d;
01052     }
01053   }
01054 };
01055 
01056 CS_SPECIALIZE_TEMPLATE
01057 class csStringFast<0> : public csStringBase
01058 {
01059 public:
01060   csStringFast () : csStringBase() { }
01061   csStringFast (size_t Length) : csStringBase(Length) { }
01062   csStringFast (const csStringBase& copy) : csStringBase (copy) { }
01063   csStringFast (const char* src) : csStringBase(src) { }
01064   csStringFast (const char* src, size_t _length) : csStringBase(src, _length) { }
01065   csStringFast (char c) : csStringBase(c) { }
01066   csStringFast (unsigned char c) : csStringBase(c) { }
01067   const csStringFast& operator = (const csStringBase& copy)
01068   { Replace(copy); return *this; }
01069   const csStringFast& operator = (const char* copy)
01070   { Replace(copy); return *this; }
01071   const csStringFast& operator = (char x)
01072   { Replace(x); return *this; }
01073   const csStringFast& operator = (unsigned char x)
01074   { Replace(x); return *this; }
01075   const csStringFast& operator = (bool x)
01076   { Replace(x); return *this; }
01077   const csStringFast& operator = (short x)
01078   { Replace(x); return *this; }
01079   const csStringFast& operator = (unsigned short x)
01080   { Replace(x); return *this; }
01081   const csStringFast& operator = (int x)
01082   { Replace(x); return *this; }
01083   const csStringFast& operator = (unsigned int x)
01084   { Replace(x); return *this; }
01085   const csStringFast& operator = (long x)
01086   { Replace(x); return *this; }
01087   const csStringFast& operator = (unsigned long x)
01088   { Replace(x); return *this; }
01089   const csStringFast& operator = (float x)
01090   { Replace(x); return *this; }
01091   const csStringFast& operator = (double x)
01092   { Replace(x); return *this; }
01093 #ifndef __STRICT_ANSI__
01094   const csStringFast& operator = (longlong x)
01095   { Replace(x); return *this; }
01096   const csStringFast& operator = (ulonglong x)
01097   { Replace(x); return *this; }
01098 #endif
01099 };
01100 
01101 #ifndef SWIG
01102 
01107 typedef csStringFast<> csStringFastDefault;
01108 #else
01109 #define csStringFastDefault csStringFast<36>
01110 %template(csStringParent) csStringFast<36>;
01111 #endif
01112 
01116 class csString : public csStringFastDefault
01117 {
01118 public:
01120   csString () : csStringFast<> () { }
01125   csString (size_t Length) : csStringFast<> (Length) { }
01127 
01128   csString (const csString& copy) :
01129     csStringFast<> ((const csStringBase&)copy) { }
01130   csString (const csStringBase& copy) : csStringFast<> (copy) { }
01132 
01133   csString (const char* src) : csStringFast<> (src) { }
01135   csString (const char* src, size_t _length) : csStringFast<> (src, _length) { }
01137   csString (char c) : csStringFast<> (c) { }
01139   csString (unsigned char c) : csStringFast<> (c) { }
01140 
01142 
01143   const csString& operator = (const csString& copy)
01144   { Replace(copy); return *this; }
01145   const csString& operator = (const csStringBase& copy)
01146   { Replace(copy); return *this; }
01147   const csString& operator = (const char* copy)
01148   { Replace(copy); return *this; }
01149   const csString& operator = (char x)
01150   { Replace(x); return *this; }
01151   const csString& operator = (unsigned char x)
01152   { Replace(x); return *this; }
01153   const csString& operator = (bool x)
01154   { Replace(x); return *this; }
01155   const csString& operator = (short x)
01156   { Replace(x); return *this; }
01157   const csString& operator = (unsigned short x)
01158   { Replace(x); return *this; }
01159   const csString& operator = (int x)
01160   { Replace(x); return *this; }
01161   const csString& operator = (unsigned int x)
01162   { Replace(x); return *this; }
01163   const csString& operator = (long x)
01164   { Replace(x); return *this; }
01165   const csString& operator = (unsigned long x)
01166   { Replace(x); return *this; }
01167   const csString& operator = (float x)
01168   { Replace(x); return *this; }
01169   const csString& operator = (double x)
01170   { Replace(x); return *this; }
01171 #ifndef __STRICT_ANSI__
01172   const csString& operator = (longlong x)
01173   { Replace(x); return *this; }
01174   const csString& operator = (ulonglong x)
01175   { Replace(x); return *this; }
01176 #endif
01177 
01178 };
01179 
01180 #endif // __CS_CSSTRING_H__

Generated for Crystal Space by doxygen 1.4.4