00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00159
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
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
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
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
00792
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
00895
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)
00976 csStringBase::SetCapacityInternal(NewSize, soft);
00977 else
00978 {
00979 NewSize++;
00980 if (NewSize <= LEN)
00981 {
00982
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);
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;
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__