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 <[email protected]> 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 00051 class CS_CRYSTALSPACE_EXPORT csStringBase 00052 { 00053 protected: 00058 enum { DEFAULT_GROW_BY = 64 }; 00059 00061 char* Data; 00063 size_t Size; 00065 size_t MaxSize; 00070 size_t GrowBy; 00071 00077 void ExpandIfNeeded (size_t NewSize); 00078 00083 virtual void SetCapacityInternal (size_t NewSize, bool soft); 00084 00086 size_t ComputeNewSize (size_t NewSize); 00087 00099 virtual char* GetDataMutable () 00100 { return Data; } 00101 00102 public: 00110 void SetCapacity (size_t NewSize); 00111 00116 virtual size_t GetCapacity() const 00117 { return MaxSize > 0 ? MaxSize - 1 : 0; } 00118 00126 csStringBase& Append (const char* Str, size_t Count = (size_t)-1); 00127 00136 csStringBase& Append (const wchar_t* Str, size_t Count = (size_t)-1); 00137 00145 csStringBase& Append (const csStringBase& Str, size_t Count = (size_t)-1); 00146 00151 csStringBase& Append (char c); 00152 00157 /*csStringBase& Append (unsigned char c) 00158 { return Append(char(c)); }*/ 00159 00161 csStringBase& Append (bool b) { return Append (b ? "1" : "0"); } 00162 00168 csStringBase& AppendFmt (const char* format, ...) CS_GNUC_PRINTF (2, 3); 00169 csStringBase& AppendFmtV (const char* format, va_list args); 00173 00174 csStringBase& Append (short v) { return AppendFmt ("%hd", v); } 00175 csStringBase& Append (unsigned short v) { return AppendFmt ("%hu", v); } 00176 csStringBase& Append (int v) { return AppendFmt ("%d", v); } 00177 csStringBase& Append (unsigned int v) { return AppendFmt ("%u", v); } 00178 csStringBase& Append (long v) { return AppendFmt ("%ld", v); } 00179 csStringBase& Append (unsigned long v) { return AppendFmt ("%lu", v); } 00180 csStringBase& Append (float v) { return AppendFmt ("%g", v); } 00181 csStringBase& Append (double v) { return AppendFmt ("%g", v); } 00182 #ifndef __STRICT_ANSI__ 00183 csStringBase& Append (longlong v) { return AppendFmt ("%lld", v); } 00184 csStringBase& Append (ulonglong v) { return AppendFmt ("%llu", v); } 00185 #endif 00186 00192 csStringBase () : Data (0), Size (0), MaxSize (0), GrowBy (DEFAULT_GROW_BY) 00193 {} 00194 00201 csStringBase (size_t Length) : Data (0), Size (0), MaxSize (0), 00202 GrowBy (DEFAULT_GROW_BY) 00203 { SetCapacity (Length); } 00204 00210 csStringBase (const csStringBase& copy) : Data (0), Size (0), MaxSize (0), 00211 GrowBy (DEFAULT_GROW_BY) 00212 { Append (copy); } 00213 00219 csStringBase (const char* src) : Data (0), Size (0), MaxSize (0), 00220 GrowBy (DEFAULT_GROW_BY) 00221 { Append (src); } 00222 00229 csStringBase (const wchar_t* src) : Data (0), Size (0), MaxSize (0), 00230 GrowBy (DEFAULT_GROW_BY) 00231 { Append (src); } 00232 00238 csStringBase (const char* src, size_t _length) : Data (0), Size (0), 00239 MaxSize (0), GrowBy (DEFAULT_GROW_BY) 00240 { Append (src, _length); } 00241 00248 csStringBase (const wchar_t* src, size_t _length) : Data (0), Size (0), 00249 MaxSize (0), GrowBy (DEFAULT_GROW_BY) 00250 { Append (src, _length); } 00251 00253 csStringBase (char c) : Data (0), Size (0), MaxSize (0), 00254 GrowBy (DEFAULT_GROW_BY) 00255 { Append (c); } 00256 00258 csStringBase (unsigned char c) : Data(0), Size (0), MaxSize (0), 00259 GrowBy (DEFAULT_GROW_BY) 00260 { Append ((char) c); } 00261 00263 virtual ~csStringBase (); 00264 00277 void SetGrowsBy(size_t); 00278 00284 size_t GetGrowsBy() const 00285 { return GrowBy; } 00286 00291 CS_DEPRECATED_METHOD_MSG("Use SetGrowsBy(0) instead.") 00292 void SetGrowsExponentially(bool b) 00293 { SetGrowsBy(b ? 0 : DEFAULT_GROW_BY); } 00294 00299 CS_DEPRECATED_METHOD_MSG("Use GetGrowsBy() instead.") 00300 bool GetGrowsExponentially() const 00301 { return GetGrowsBy() == 0; } 00302 00309 virtual void Free (); 00310 00327 csStringBase& Truncate (size_t Len); 00328 00334 csStringBase& Empty() { return Truncate (0); } 00335 00345 virtual void ShrinkBestFit (); 00346 00356 csStringBase& Reclaim () { ShrinkBestFit(); return *this; } 00357 00364 csStringBase& Clear () { return Empty(); } 00365 00373 CS_VISIBILITY_DEFAULT // <- @@@ FIXME: needed for gcc 4.1.0 00374 virtual char const* GetData () const 00375 { return Data; } 00376 00386 char const* GetDataSafe() const 00387 { char const* p = GetData(); return p != 0 ? p : ""; } 00388 00394 size_t Length () const 00395 { return Size; } 00396 00402 bool IsEmpty () const 00403 { return (Size == 0); } 00404 00406 char& operator [] (size_t n) 00407 { 00408 CS_ASSERT (n < Size); 00409 return GetDataMutable()[n]; 00410 } 00411 00413 char operator [] (size_t n) const 00414 { 00415 CS_ASSERT (n < Size); 00416 return GetData()[n]; 00417 } 00418 00425 void SetAt (size_t n, const char c) 00426 { 00427 CS_ASSERT (n < Size); 00428 GetDataMutable() [n] = c; 00429 } 00430 00432 char GetAt (size_t n) const 00433 { 00434 CS_ASSERT (n < Size); 00435 return GetData() [n]; 00436 } 00437 00444 csStringBase& DeleteAt (size_t Pos, size_t Count = 1); 00445 00452 csStringBase& Insert (size_t Pos, const csStringBase& Str); 00453 00460 csStringBase& Insert (size_t Pos, const char* Str); 00461 00468 csStringBase& Insert (size_t Pos, char C); 00469 00478 csStringBase& Overwrite (size_t Pos, const csStringBase& Str); 00479 00486 csStringBase Slice (size_t start, size_t len = (size_t)-1) const; 00487 00498 void SubString (csStringBase& sub, size_t start, 00499 size_t len = (size_t)-1) const; 00500 00507 size_t FindFirst (char c, size_t pos = 0) const; 00508 00515 size_t FindFirst (const char *c, size_t pos = 0) const; 00516 00524 size_t FindLast (char c, size_t pos = (size_t)-1) const; 00525 00533 size_t FindLast (const char *c, size_t pos = (size_t)-1) const; 00534 00541 size_t Find (const char* search, size_t pos = 0) const; 00542 00550 /* CS_DEPRECATED_METHOD_MSG("Use Find() instead.") */ 00551 size_t FindStr (const char* search, size_t pos = 0) const 00552 { return Find(search, pos); } 00553 00558 void ReplaceAll (const char* search, const char* replacement); 00559 00565 /* CS_DEPRECATED_METHOD_MSG("Use ReplaceAll() instead.") */ 00566 void FindReplace (const char* search, const char* replacement) 00567 { ReplaceAll(search, replacement); } 00568 00576 csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3); 00577 00585 csStringBase& FormatV (const char* format, va_list args); 00586 00596 csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1); 00597 00607 csStringBase& Replace (const char* Str, size_t Count = (size_t)-1); 00608 00613 template<typename T> 00614 csStringBase& Replace (T const& val) { Truncate (0); return Append (val); } 00615 00622 bool Compare (const csStringBase& iStr) const 00623 { 00624 if (&iStr == this) 00625 return true; 00626 size_t const n = iStr.Length(); 00627 if (Size != n) 00628 return false; 00629 if (Size == 0 && n == 0) 00630 return true; 00631 return (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0); 00632 } 00633 00640 bool Compare (const char* iStr) const 00641 { return (strcmp (GetDataSafe(), iStr) == 0); } 00642 00649 bool CompareNoCase (const csStringBase& iStr) const 00650 { 00651 if (&iStr == this) 00652 return true; 00653 size_t const n = iStr.Length(); 00654 if (Size != n) 00655 return false; 00656 if (Size == 0 && n == 0) 00657 return true; 00658 return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0); 00659 } 00660 00667 bool CompareNoCase (const char* iStr) const 00668 { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); } 00669 00676 bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const 00677 { 00678 char const* p = GetDataSafe(); 00679 if (&iStr == this) 00680 return true; 00681 size_t const n = iStr.Length(); 00682 if (n == 0) 00683 return true; 00684 if (n > Size) 00685 return false; 00686 CS_ASSERT(p != 0); 00687 if (ignore_case) 00688 return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0); 00689 else 00690 return (strncmp (p, iStr.GetDataSafe (), n) == 0); 00691 } 00692 00699 bool StartsWith (const char* iStr, bool ignore_case = false) const 00700 { 00701 char const* p = GetDataSafe(); 00702 if (iStr == 0) 00703 return false; 00704 size_t const n = strlen (iStr); 00705 if (n == 0) 00706 return true; 00707 if (n > Size) 00708 return false; 00709 CS_ASSERT(p != 0); 00710 if (ignore_case) 00711 return (csStrNCaseCmp (p, iStr, n) == 0); 00712 else 00713 return (strncmp (p, iStr, n) == 0); 00714 } 00715 00721 csStringBase Clone () const 00722 { return csStringBase (*this); } 00723 00731 csStringBase& LTrim(); 00732 00740 csStringBase& RTrim(); 00741 00747 csStringBase& Trim(); 00748 00754 csStringBase& Collapse(); 00755 00764 csStringBase& PadLeft (size_t NewSize, char PadChar = ' '); 00765 00774 csStringBase& PadRight (size_t NewSize, char PadChar = ' '); 00775 00787 csStringBase& PadCenter (size_t NewSize, char PadChar = ' '); 00788 00792 template<typename T> 00793 const csStringBase& operator = (T const& s) { return Replace (s); } 00794 00796 const csStringBase& operator = (const csStringBase& copy) 00797 { Replace(copy); return *this; } 00798 00802 template<typename T> 00803 csStringBase &operator += (T const& s) { return Append (s); } 00804 00805 // Specialization which prevents gcc from barfing on strings allocated via 00806 // CS_ALLOC_STACK_ARRAY(). 00807 csStringBase &operator += (char const* s) 00808 { return Append(s); } 00809 00811 csStringBase operator + (const csStringBase &iStr) const 00812 { return Clone ().Append (iStr); } 00813 00821 operator const char* () const 00822 { return GetData(); } 00823 00830 bool operator == (const csStringBase& Str) const 00831 { return Compare (Str); } 00838 bool operator == (const char* Str) const 00839 { return Compare (Str); } 00846 bool operator < (const csStringBase& Str) const 00847 { 00848 return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0; 00849 } 00856 bool operator < (const char* Str) const 00857 { 00858 return strcmp (GetDataSafe (), Str) < 0; 00859 } 00866 bool operator > (const csStringBase& Str) const 00867 { 00868 return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0; 00869 } 00876 bool operator > (const char* Str) const 00877 { 00878 return strcmp (GetDataSafe (), Str) > 0; 00879 } 00886 bool operator != (const csStringBase& Str) const 00887 { return !Compare (Str); } 00894 bool operator != (const char* Str) const 00895 { return !Compare (Str); } 00896 00904 template <typename T> 00905 csStringBase &operator << (T const& v) 00906 { return Append (v); } 00907 00908 // Specialization which prevents gcc from barfing on strings allocated via 00909 // CS_ALLOC_STACK_ARRAY(). 00910 csStringBase &operator << (char const* v) 00911 { return Append(v); } 00912 00917 csStringBase& Downcase(); 00922 csStringBase& Upcase(); 00923 00934 virtual char* Detach () 00935 { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; } 00940 uint GetHash() const; 00941 }; 00942 00944 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2) 00945 { 00946 return csStringBase (iStr1).Append (iStr2); 00947 } 00948 00950 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2) 00951 { 00952 return iStr1.Clone ().Append (iStr2); 00953 } 00954 00959 template<int LEN = 36> 00960 class csStringFast : public csStringBase 00961 { 00962 protected: 00964 char minibuff[LEN]; 00973 size_t miniused; 00974 00975 virtual void SetCapacityInternal (size_t NewSize, bool soft) 00976 { 00977 if (Data != 0) // If dynamic buffer already allocated, just re-use it. 00978 csStringBase::SetCapacityInternal(NewSize, soft); 00979 else 00980 { 00981 NewSize++; // Plus one for implicit null byte. 00982 if (NewSize <= LEN) 00983 miniused = NewSize; 00984 else 00985 { 00986 CS_ASSERT(MaxSize == 0); 00987 if (soft) 00988 NewSize = ComputeNewSize (NewSize); 00989 Data = new char[NewSize]; 00990 MaxSize = NewSize; 00991 if (Size == 0) 00992 Data[0] = '\0'; 00993 else 00994 memcpy(Data, minibuff, Size + 1); 00995 } 00996 } 00997 } 00998 00999 virtual char* GetDataMutable () 01000 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 01001 01002 public: 01006 csStringFast () : csStringBase(), miniused(0) { } 01011 csStringFast (size_t Length) : csStringBase(), miniused(0) 01012 { SetCapacity (Length); } 01016 csStringFast (const csStringBase& copy) : csStringBase (), miniused(0) 01017 { Append (copy); } 01021 csStringFast (const csStringFast& copy) : csStringBase (), miniused(0) 01022 { Append (copy); } 01026 csStringFast (const char* src) : csStringBase(), miniused(0) 01027 { Append (src); } 01031 csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0) 01032 { Append (src, _length); } 01033 01034 01036 csStringFast (char c) : csStringBase(), miniused(0) 01037 { Append (c); } 01039 csStringFast (unsigned char c) : csStringBase(), miniused(0) 01040 { Append ((char)c); } 01042 virtual ~csStringFast () { } 01043 01045 const csStringFast& operator = (const csStringBase& copy) 01046 { Replace(copy); return *this; } 01047 01049 template<typename T> 01050 const csStringFast& operator = (T const& s) { Replace (s); return *this; } 01051 01052 virtual char const* GetData () const 01053 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 01054 01055 virtual size_t GetCapacity() const 01056 { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; } 01057 01058 virtual void ShrinkBestFit () 01059 { 01060 if (Size == 0) 01061 { 01062 csStringBase::ShrinkBestFit(); 01063 miniused = 0; 01064 } 01065 else 01066 { 01067 size_t needed = Size + 1; 01068 if (needed > LEN) 01069 csStringBase::ShrinkBestFit(); 01070 else 01071 { 01072 miniused = needed; 01073 if (Data != 0) 01074 { 01075 memcpy(minibuff, Data, needed); // Includes implicit null byte. 01076 csStringBase::Free(); 01077 } 01078 } 01079 } 01080 } 01081 01082 virtual void Free () { miniused = 0; csStringBase::Free(); } 01083 01084 virtual char* Detach () 01085 { 01086 if (Data != 0) 01087 return csStringBase::Detach(); 01088 else if (miniused == 0) 01089 return 0; // Emulate NULL return of csStringBase in this case. 01090 else 01091 { 01092 CS_ASSERT(MaxSize == 0); 01093 char* d = csStrNew (minibuff); 01094 Size = 0; miniused = 0; 01095 return d; 01096 } 01097 } 01098 }; 01099 01100 template<> 01101 class csStringFast<0> : public csStringBase 01102 { 01103 public: 01104 csStringFast () : csStringBase() { } 01105 csStringFast (size_t Length) : csStringBase(Length) { } 01106 csStringFast (const csStringBase& copy) : csStringBase (copy) { } 01107 csStringFast (const char* src) : csStringBase(src) { } 01108 csStringFast (const char* src, size_t _length) : csStringBase(src, _length) 01109 { } 01110 csStringFast (char c) : csStringBase(c) { } 01111 csStringFast (unsigned char c) : csStringBase(c) { } 01112 const csStringFast& operator = (const csStringBase& copy) 01113 { Replace(copy); return *this; } 01114 const csStringFast& operator = (const char* copy) 01115 { Replace(copy); return *this; } 01116 const csStringFast& operator = (char x) 01117 { Replace(x); return *this; } 01118 const csStringFast& operator = (unsigned char x) 01119 { Replace(x); return *this; } 01120 const csStringFast& operator = (bool x) 01121 { Replace(x); return *this; } 01122 const csStringFast& operator = (short x) 01123 { Replace(x); return *this; } 01124 const csStringFast& operator = (unsigned short x) 01125 { Replace(x); return *this; } 01126 const csStringFast& operator = (int x) 01127 { Replace(x); return *this; } 01128 const csStringFast& operator = (unsigned int x) 01129 { Replace(x); return *this; } 01130 const csStringFast& operator = (long x) 01131 { Replace(x); return *this; } 01132 const csStringFast& operator = (unsigned long x) 01133 { Replace(x); return *this; } 01134 const csStringFast& operator = (float x) 01135 { Replace(x); return *this; } 01136 const csStringFast& operator = (double x) 01137 { Replace(x); return *this; } 01138 #ifndef __STRICT_ANSI__ 01139 const csStringFast& operator = (longlong x) 01140 { Replace(x); return *this; } 01141 const csStringFast& operator = (ulonglong x) 01142 { Replace(x); return *this; } 01143 #endif 01144 }; 01145 01146 #ifndef SWIG 01147 01152 typedef csStringFast<> csStringFastDefault; 01153 #else 01154 #define csStringFastDefault csStringFast<36> 01155 %template(csStringParent) csStringFast<36>; 01156 #endif 01157 01161 class csString : public csStringFastDefault 01162 { 01163 public: 01165 csString () : csStringFast<> () { } 01170 csString (size_t Length) : csStringFast<> (Length) { } 01172 01173 csString (const csString& copy) : 01174 csStringFast<> ((const csStringBase&)copy) { } 01175 csString (const csStringBase& copy) : csStringFast<> (copy) { } 01177 01178 csString (const char* src) : csStringFast<> (src) { } 01180 csString (const char* src, size_t _length) : csStringFast<> (src, _length) { } 01182 csString (char c) : csStringFast<> (c) { } 01184 csString (unsigned char c) : csStringFast<> (c) { } 01185 01187 01188 const csString& operator = (const csString& copy) 01189 { Replace(copy); return *this; } 01190 const csString& operator = (const csStringBase& copy) 01191 { Replace(copy); return *this; } 01192 const csString& operator = (const char* copy) 01193 { Replace(copy); return *this; } 01194 const csString& operator = (char x) 01195 { Replace(x); return *this; } 01196 const csString& operator = (unsigned char x) 01197 { Replace(x); return *this; } 01198 const csString& operator = (bool x) 01199 { Replace(x); return *this; } 01200 const csString& operator = (short x) 01201 { Replace(x); return *this; } 01202 const csString& operator = (unsigned short x) 01203 { Replace(x); return *this; } 01204 const csString& operator = (int x) 01205 { Replace(x); return *this; } 01206 const csString& operator = (unsigned int x) 01207 { Replace(x); return *this; } 01208 const csString& operator = (long x) 01209 { Replace(x); return *this; } 01210 const csString& operator = (unsigned long x) 01211 { Replace(x); return *this; } 01212 const csString& operator = (float x) 01213 { Replace(x); return *this; } 01214 const csString& operator = (double x) 01215 { Replace(x); return *this; } 01216 #ifndef __STRICT_ANSI__ 01217 const csString& operator = (longlong x) 01218 { Replace(x); return *this; } 01219 const csString& operator = (ulonglong x) 01220 { Replace(x); return *this; } 01221 #endif 01222 01223 }; 01224 01225 #endif // __CS_CSSTRING_H__
Generated for Crystal Space by doxygen 1.4.7