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.6.1