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 00292 CS_DEPRECATED_METHOD_MSG("Use SetGrowsBy(0) instead.") 00293 void SetGrowsExponentially(bool b) 00294 { SetGrowsBy(b ? 0 : DEFAULT_GROW_BY); } 00295 00300 CS_DEPRECATED_METHOD_MSG("Use GetGrowsBy() instead.") 00301 bool GetGrowsExponentially() const 00302 { return GetGrowsBy() == 0; } 00303 00310 virtual void Free (); 00311 00328 csStringBase& Truncate (size_t Len); 00329 00335 csStringBase& Empty() { return Truncate (0); } 00336 00346 virtual void ShrinkBestFit (); 00347 00357 csStringBase& Reclaim () { ShrinkBestFit(); return *this; } 00358 00365 csStringBase& Clear () { return Empty(); } 00366 00374 CS_VISIBILITY_DEFAULT // <- @@@ FIXME: needed for gcc 4.1.0 00375 virtual char const* GetData () const 00376 { return Data; } 00377 00387 char const* GetDataSafe() const 00388 { char const* p = GetData(); return p != 0 ? p : ""; } 00389 00395 size_t Length () const 00396 { return Size; } 00397 00403 bool IsEmpty () const 00404 { return (Size == 0); } 00405 00407 char& operator [] (size_t n) 00408 { 00409 CS_ASSERT (n < Size); 00410 return GetDataMutable()[n]; 00411 } 00412 00414 char operator [] (size_t n) const 00415 { 00416 CS_ASSERT (n < Size); 00417 return GetData()[n]; 00418 } 00419 00426 void SetAt (size_t n, const char c) 00427 { 00428 CS_ASSERT (n < Size); 00429 GetDataMutable() [n] = c; 00430 } 00431 00433 char GetAt (size_t n) const 00434 { 00435 CS_ASSERT (n < Size); 00436 return GetData() [n]; 00437 } 00438 00445 csStringBase& DeleteAt (size_t Pos, size_t Count = 1); 00446 00453 csStringBase& Insert (size_t Pos, const csStringBase& Str); 00454 00461 csStringBase& Insert (size_t Pos, const char* Str); 00462 00469 csStringBase& Insert (size_t Pos, char C); 00470 00479 csStringBase& Overwrite (size_t Pos, const csStringBase& Str); 00480 00487 csStringBase Slice (size_t start, size_t len = (size_t)-1) const; 00488 00499 void SubString (csStringBase& sub, size_t start, 00500 size_t len = (size_t)-1) const; 00501 00508 size_t FindFirst (char c, size_t pos = 0) const; 00509 00516 size_t FindFirst (const char *c, size_t pos = 0) const; 00517 00525 size_t FindLast (char c, size_t pos = (size_t)-1) const; 00526 00534 size_t FindLast (const char *c, size_t pos = (size_t)-1) const; 00535 00542 size_t Find (const char* search, size_t pos = 0) const; 00543 00551 /* CS_DEPRECATED_METHOD_MSG("Use Find() instead.") */ 00552 size_t FindStr (const char* search, size_t pos = 0) const 00553 { return Find(search, pos); } 00554 00559 void ReplaceAll (const char* search, const char* replacement); 00560 00566 /* CS_DEPRECATED_METHOD_MSG("Use ReplaceAll() instead.") */ 00567 void FindReplace (const char* search, const char* replacement) 00568 { ReplaceAll(search, replacement); } 00569 00577 csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3); 00578 00586 csStringBase& FormatV (const char* format, va_list args); 00587 00597 csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1); 00598 00608 csStringBase& Replace (const char* Str, size_t Count = (size_t)-1); 00609 00614 template<typename T> 00615 csStringBase& Replace (T const& val) { Truncate (0); return Append (val); } 00616 00623 bool Compare (const csStringBase& iStr) const 00624 { 00625 if (&iStr == this) 00626 return true; 00627 size_t const n = iStr.Length(); 00628 if (Size != n) 00629 return false; 00630 if (Size == 0 && n == 0) 00631 return true; 00632 return (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0); 00633 } 00634 00641 bool Compare (const char* iStr) const 00642 { return (strcmp (GetDataSafe(), iStr) == 0); } 00643 00650 bool CompareNoCase (const csStringBase& iStr) const 00651 { 00652 if (&iStr == this) 00653 return true; 00654 size_t const n = iStr.Length(); 00655 if (Size != n) 00656 return false; 00657 if (Size == 0 && n == 0) 00658 return true; 00659 return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0); 00660 } 00661 00668 bool CompareNoCase (const char* iStr) const 00669 { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); } 00670 00677 bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const 00678 { 00679 char const* p = GetDataSafe(); 00680 if (&iStr == this) 00681 return true; 00682 size_t const n = iStr.Length(); 00683 if (n == 0) 00684 return true; 00685 if (n > Size) 00686 return false; 00687 CS_ASSERT(p != 0); 00688 if (ignore_case) 00689 return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0); 00690 else 00691 return (strncmp (p, iStr.GetDataSafe (), n) == 0); 00692 } 00693 00700 bool StartsWith (const char* iStr, bool ignore_case = false) const 00701 { 00702 char const* p = GetDataSafe(); 00703 if (iStr == 0) 00704 return false; 00705 size_t const n = strlen (iStr); 00706 if (n == 0) 00707 return true; 00708 if (n > Size) 00709 return false; 00710 CS_ASSERT(p != 0); 00711 if (ignore_case) 00712 return (csStrNCaseCmp (p, iStr, n) == 0); 00713 else 00714 return (strncmp (p, iStr, n) == 0); 00715 } 00716 00722 csStringBase Clone () const 00723 { return csStringBase (*this); } 00724 00732 csStringBase& LTrim(); 00733 00741 csStringBase& RTrim(); 00742 00748 csStringBase& Trim(); 00749 00755 csStringBase& Collapse(); 00756 00765 csStringBase& PadLeft (size_t NewSize, char PadChar = ' '); 00766 00775 csStringBase& PadRight (size_t NewSize, char PadChar = ' '); 00776 00788 csStringBase& PadCenter (size_t NewSize, char PadChar = ' '); 00789 00793 template<typename T> 00794 const csStringBase& operator = (T const& s) { return Replace (s); } 00795 00797 const csStringBase& operator = (const csStringBase& copy) 00798 { Replace(copy); return *this; } 00799 00803 template<typename T> 00804 csStringBase &operator += (T const& s) { return Append (s); } 00805 00806 // Specialization which prevents gcc from barfing on strings allocated via 00807 // CS_ALLOC_STACK_ARRAY(). 00808 csStringBase &operator += (char const* s) 00809 { return Append(s); } 00810 00812 csStringBase operator + (const csStringBase &iStr) const 00813 { return Clone ().Append (iStr); } 00814 00822 operator const char* () const 00823 { return GetData(); } 00824 00831 bool operator == (const csStringBase& Str) const 00832 { return Compare (Str); } 00839 bool operator == (const char* Str) const 00840 { return Compare (Str); } 00847 bool operator < (const csStringBase& Str) const 00848 { 00849 return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0; 00850 } 00857 bool operator < (const char* Str) const 00858 { 00859 return strcmp (GetDataSafe (), Str) < 0; 00860 } 00867 bool operator > (const csStringBase& Str) const 00868 { 00869 return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0; 00870 } 00877 bool operator > (const char* Str) const 00878 { 00879 return strcmp (GetDataSafe (), Str) > 0; 00880 } 00887 bool operator != (const csStringBase& Str) const 00888 { return !Compare (Str); } 00895 bool operator != (const char* Str) const 00896 { return !Compare (Str); } 00897 00905 template <typename T> 00906 csStringBase &operator << (T const& v) 00907 { return Append (v); } 00908 00909 // Specialization which prevents gcc from barfing on strings allocated via 00910 // CS_ALLOC_STACK_ARRAY(). 00911 csStringBase &operator << (char const* v) 00912 { return Append(v); } 00913 00922 csStringBase& Downcase (); 00931 csStringBase& Upcase (); 00932 00943 virtual char* Detach () 00944 { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; } 00949 uint GetHash() const; 00950 }; 00951 00953 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2) 00954 { 00955 return csStringBase (iStr1).Append (iStr2); 00956 } 00957 00959 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2) 00960 { 00961 return iStr1.Clone ().Append (iStr2); 00962 } 00963 00968 template<int LEN = 36> 00969 class csStringFast : public csStringBase 00970 { 00971 protected: 00973 char minibuff[LEN]; 00982 size_t miniused; 00983 00984 virtual void SetCapacityInternal (size_t NewSize, bool soft) 00985 { 00986 if (Data != 0) // If dynamic buffer already allocated, just re-use it. 00987 csStringBase::SetCapacityInternal(NewSize, soft); 00988 else 00989 { 00990 NewSize++; // Plus one for implicit null byte. 00991 if (NewSize <= LEN) 00992 miniused = NewSize; 00993 else 00994 { 00995 CS_ASSERT(MaxSize == 0); 00996 if (soft) 00997 NewSize = ComputeNewSize (NewSize); 00998 Data = new char[NewSize]; 00999 MaxSize = NewSize; 01000 if (Size == 0) 01001 Data[0] = '\0'; 01002 else 01003 memcpy(Data, minibuff, Size + 1); 01004 } 01005 } 01006 } 01007 01008 virtual char* GetDataMutable () 01009 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 01010 01011 public: 01015 csStringFast () : csStringBase(), miniused(0) { } 01020 csStringFast (size_t Length) : csStringBase(), miniused(0) 01021 { SetCapacity (Length); } 01025 csStringFast (const csStringBase& copy) : csStringBase (), miniused(0) 01026 { Append (copy); } 01030 csStringFast (const csStringFast& copy) : csStringBase (), miniused(0) 01031 { Append (copy); } 01035 csStringFast (const char* src) : csStringBase(), miniused(0) 01036 { Append (src); } 01040 csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0) 01041 { Append (src, _length); } 01042 01043 01045 csStringFast (char c) : csStringBase(), miniused(0) 01046 { Append (c); } 01048 csStringFast (unsigned char c) : csStringBase(), miniused(0) 01049 { Append ((char)c); } 01051 virtual ~csStringFast () { } 01052 01054 const csStringFast& operator = (const csStringBase& copy) 01055 { Replace(copy); return *this; } 01056 01058 template<typename T> 01059 const csStringFast& operator = (T const& s) { Replace (s); return *this; } 01060 01061 virtual char const* GetData () const 01062 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 01063 01064 virtual size_t GetCapacity() const 01065 { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; } 01066 01067 virtual void ShrinkBestFit () 01068 { 01069 if (Size == 0) 01070 { 01071 csStringBase::ShrinkBestFit(); 01072 miniused = 0; 01073 } 01074 else 01075 { 01076 size_t needed = Size + 1; 01077 if (needed > LEN) 01078 csStringBase::ShrinkBestFit(); 01079 else 01080 { 01081 miniused = needed; 01082 if (Data != 0) 01083 { 01084 memcpy(minibuff, Data, needed); // Includes implicit null byte. 01085 csStringBase::Free(); 01086 } 01087 } 01088 } 01089 } 01090 01091 virtual void Free () { miniused = 0; csStringBase::Free(); } 01092 01093 virtual char* Detach () 01094 { 01095 if (Data != 0) 01096 return csStringBase::Detach(); 01097 else if (miniused == 0) 01098 return 0; // Emulate NULL return of csStringBase in this case. 01099 else 01100 { 01101 CS_ASSERT(MaxSize == 0); 01102 char* d = csStrNew (minibuff); 01103 Size = 0; miniused = 0; 01104 return d; 01105 } 01106 } 01107 }; 01108 01109 template<> 01110 class csStringFast<0> : public csStringBase 01111 { 01112 public: 01113 csStringFast () : csStringBase() { } 01114 csStringFast (size_t Length) : csStringBase(Length) { } 01115 csStringFast (const csStringBase& copy) : csStringBase (copy) { } 01116 csStringFast (const char* src) : csStringBase(src) { } 01117 csStringFast (const char* src, size_t _length) : csStringBase(src, _length) 01118 { } 01119 csStringFast (char c) : csStringBase(c) { } 01120 csStringFast (unsigned char c) : csStringBase(c) { } 01121 const csStringFast& operator = (const csStringBase& copy) 01122 { Replace(copy); return *this; } 01123 const csStringFast& operator = (const char* copy) 01124 { Replace(copy); return *this; } 01125 const csStringFast& operator = (char x) 01126 { Replace(x); return *this; } 01127 const csStringFast& operator = (unsigned char x) 01128 { Replace(x); return *this; } 01129 const csStringFast& operator = (bool x) 01130 { Replace(x); return *this; } 01131 const csStringFast& operator = (short x) 01132 { Replace(x); return *this; } 01133 const csStringFast& operator = (unsigned short x) 01134 { Replace(x); return *this; } 01135 const csStringFast& operator = (int x) 01136 { Replace(x); return *this; } 01137 const csStringFast& operator = (unsigned int x) 01138 { Replace(x); return *this; } 01139 const csStringFast& operator = (long x) 01140 { Replace(x); return *this; } 01141 const csStringFast& operator = (unsigned long x) 01142 { Replace(x); return *this; } 01143 const csStringFast& operator = (float x) 01144 { Replace(x); return *this; } 01145 const csStringFast& operator = (double x) 01146 { Replace(x); return *this; } 01147 #ifndef __STRICT_ANSI__ 01148 const csStringFast& operator = (longlong x) 01149 { Replace(x); return *this; } 01150 const csStringFast& operator = (ulonglong x) 01151 { Replace(x); return *this; } 01152 #endif 01153 }; 01154 01155 #ifndef SWIG 01156 01161 typedef csStringFast<> csStringFastDefault; 01162 #else 01163 #define csStringFastDefault csStringFast<36> 01164 %template(csStringParent) csStringFast<36>; 01165 #endif 01166 01170 class csString : public csStringFastDefault 01171 { 01172 public: 01174 csString () : csStringFast<> () { } 01179 csString (size_t Length) : csStringFast<> (Length) { } 01181 01182 csString (const csString& copy) : 01183 csStringFast<> ((const csStringBase&)copy) { } 01184 csString (const csStringBase& copy) : csStringFast<> (copy) { } 01186 01187 csString (const char* src) : csStringFast<> (src) { } 01189 csString (const char* src, size_t _length) : csStringFast<> (src, _length) { } 01191 csString (char c) : csStringFast<> (c) { } 01193 csString (unsigned char c) : csStringFast<> (c) { } 01194 01196 01197 const csString& operator = (const csString& copy) 01198 { Replace(copy); return *this; } 01199 const csString& operator = (const csStringBase& copy) 01200 { Replace(copy); return *this; } 01201 const csString& operator = (const char* copy) 01202 { Replace(copy); return *this; } 01203 const csString& operator = (char x) 01204 { Replace(x); return *this; } 01205 const csString& operator = (unsigned char x) 01206 { Replace(x); return *this; } 01207 const csString& operator = (bool x) 01208 { Replace(x); return *this; } 01209 const csString& operator = (short x) 01210 { Replace(x); return *this; } 01211 const csString& operator = (unsigned short x) 01212 { Replace(x); return *this; } 01213 const csString& operator = (int x) 01214 { Replace(x); return *this; } 01215 const csString& operator = (unsigned int x) 01216 { Replace(x); return *this; } 01217 const csString& operator = (long x) 01218 { Replace(x); return *this; } 01219 const csString& operator = (unsigned long x) 01220 { Replace(x); return *this; } 01221 const csString& operator = (float x) 01222 { Replace(x); return *this; } 01223 const csString& operator = (double x) 01224 { Replace(x); return *this; } 01225 #ifndef __STRICT_ANSI__ 01226 const csString& operator = (longlong x) 01227 { Replace(x); return *this; } 01228 const csString& operator = (ulonglong x) 01229 { Replace(x); return *this; } 01230 #endif 01231 01232 }; 01233 01234 #endif // __CS_CSSTRING_H__
Generated for Crystal Space 1.0.2 by doxygen 1.4.7