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/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 00135 csStringBase& Append (const csStringBase& Str, size_t Count = (size_t)-1); 00136 00141 csStringBase& Append (char c); 00142 00147 /*csStringBase& Append (unsigned char c) 00148 { return Append(char(c)); }*/ 00149 00151 csStringBase& Append (bool b) { return Append (b ? "1" : "0"); } 00152 00158 csStringBase& AppendFmt (const char* format, ...) CS_GNUC_PRINTF (2, 3); 00159 csStringBase& AppendFmtV (const char* format, va_list args); 00163 00164 csStringBase& Append (short v) { return AppendFmt ("%hd", v); } 00165 csStringBase& Append (unsigned short v) { return AppendFmt ("%hu", v); } 00166 csStringBase& Append (int v) { return AppendFmt ("%d", v); } 00167 csStringBase& Append (unsigned int v) { return AppendFmt ("%u", v); } 00168 csStringBase& Append (long v) { return AppendFmt ("%ld", v); } 00169 csStringBase& Append (unsigned long v) { return AppendFmt ("%lu", v); } 00170 csStringBase& Append (float v) { return AppendFmt ("%g", v); } 00171 csStringBase& Append (double v) { return AppendFmt ("%g", v); } 00172 #ifndef __STRICT_ANSI__ 00173 csStringBase& Append (longlong v) { return AppendFmt ("%lld", v); } 00174 csStringBase& Append (ulonglong v) { return AppendFmt ("%llu", v); } 00175 #endif 00176 00182 csStringBase () : Data (0), Size (0), MaxSize (0), GrowBy (DEFAULT_GROW_BY) 00183 {} 00184 00191 csStringBase (size_t Length) : Data (0), Size (0), MaxSize (0), 00192 GrowBy (DEFAULT_GROW_BY) 00193 { SetCapacity (Length); } 00194 00200 csStringBase (const csStringBase& copy) : Data (0), Size (0), MaxSize (0), 00201 GrowBy (DEFAULT_GROW_BY) 00202 { Append (copy); } 00203 00209 csStringBase (const char* src) : Data (0), Size (0), MaxSize (0), 00210 GrowBy (DEFAULT_GROW_BY) 00211 { Append (src); } 00212 00218 csStringBase (const char* src, size_t _length) : Data (0), Size (0), 00219 MaxSize (0), GrowBy (DEFAULT_GROW_BY) 00220 { Append (src, _length); } 00221 00223 csStringBase (char c) : Data (0), Size (0), MaxSize (0), 00224 GrowBy (DEFAULT_GROW_BY) 00225 { Append (c); } 00226 00228 csStringBase (unsigned char c) : Data(0), Size (0), MaxSize (0), 00229 GrowBy (DEFAULT_GROW_BY) 00230 { Append ((char) c); } 00231 00233 virtual ~csStringBase (); 00234 00247 void SetGrowsBy(size_t); 00248 00254 size_t GetGrowsBy() const 00255 { return GrowBy; } 00256 00261 CS_DEPRECATED_METHOD void SetGrowsExponentially(bool b) 00262 { SetGrowsBy(b ? 0 : DEFAULT_GROW_BY); } 00263 00268 CS_DEPRECATED_METHOD bool GetGrowsExponentially() const 00269 { return GetGrowsBy() == 0; } 00270 00277 virtual void Free (); 00278 00295 csStringBase& Truncate (size_t Len); 00296 00302 csStringBase& Empty() { return Truncate (0); } 00303 00313 virtual void ShrinkBestFit (); 00314 00324 csStringBase& Reclaim () { ShrinkBestFit(); return *this; } 00325 00332 csStringBase& Clear () { return Empty(); } 00333 00341 virtual char const* GetData () const 00342 { return Data; } 00343 00353 char const* GetDataSafe() const 00354 { char const* p = GetData(); return p != 0 ? p : ""; } 00355 00361 size_t Length () const 00362 { return Size; } 00363 00369 bool IsEmpty () const 00370 { return (Size == 0); } 00371 00373 char& operator [] (size_t n) 00374 { 00375 CS_ASSERT (n < Size); 00376 return GetDataMutable()[n]; 00377 } 00378 00380 char operator [] (size_t n) const 00381 { 00382 CS_ASSERT (n < Size); 00383 return GetData()[n]; 00384 } 00385 00392 void SetAt (size_t n, const char c) 00393 { 00394 CS_ASSERT (n < Size); 00395 GetDataMutable() [n] = c; 00396 } 00397 00399 char GetAt (size_t n) const 00400 { 00401 CS_ASSERT (n < Size); 00402 return GetData() [n]; 00403 } 00404 00411 csStringBase& DeleteAt (size_t Pos, size_t Count = 1); 00412 00419 csStringBase& Insert (size_t Pos, const csStringBase& Str); 00420 00427 csStringBase& Insert (size_t Pos, const char* Str); 00428 00435 csStringBase& Insert (size_t Pos, char C); 00436 00445 csStringBase& Overwrite (size_t Pos, const csStringBase& Str); 00446 00453 csStringBase Slice (size_t start, size_t len = (size_t)-1) const; 00454 00465 void SubString (csStringBase& sub, size_t start, 00466 size_t len = (size_t)-1) const; 00467 00474 size_t FindFirst (char c, size_t pos = 0) const; 00475 00482 size_t FindFirst (const char *c, size_t pos = 0) const; 00483 00491 size_t FindLast (char c, size_t pos = (size_t)-1) const; 00492 00499 size_t Find (const char* search, size_t pos = 0) const; 00500 00508 /* CS_DEPRECATED_METHOD */ 00509 size_t FindStr (const char* search, size_t pos = 0) const 00510 { return Find(search, pos); } 00511 00516 void ReplaceAll (const char* search, const char* replacement); 00517 00523 /* CS_DEPRECATED_METHOD */ 00524 void FindReplace (const char* search, const char* replacement) 00525 { ReplaceAll(search, replacement); } 00526 00534 csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3); 00535 00543 csStringBase& FormatV (const char* format, va_list args); 00544 00554 csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1); 00555 00565 csStringBase& Replace (const char* Str, size_t Count = (size_t)-1); 00566 00571 template<typename T> 00572 csStringBase& Replace (T const& val) { Truncate (0); return Append (val); } 00573 00580 bool Compare (const csStringBase& iStr) const 00581 { 00582 if (&iStr == this) 00583 return true; 00584 size_t const n = iStr.Length(); 00585 if (Size != n) 00586 return false; 00587 if (Size == 0 && n == 0) 00588 return true; 00589 return (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0); 00590 } 00591 00598 bool Compare (const char* iStr) const 00599 { return (strcmp (GetDataSafe(), iStr) == 0); } 00600 00607 bool CompareNoCase (const csStringBase& iStr) const 00608 { 00609 if (&iStr == this) 00610 return true; 00611 size_t const n = iStr.Length(); 00612 if (Size != n) 00613 return false; 00614 if (Size == 0 && n == 0) 00615 return true; 00616 return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0); 00617 } 00618 00625 bool CompareNoCase (const char* iStr) const 00626 { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); } 00627 00634 bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const 00635 { 00636 char const* p = GetDataSafe(); 00637 if (&iStr == this) 00638 return true; 00639 size_t const n = iStr.Length(); 00640 if (n == 0) 00641 return true; 00642 if (n > Size) 00643 return false; 00644 CS_ASSERT(p != 0); 00645 if (ignore_case) 00646 return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0); 00647 else 00648 return (strncmp (p, iStr.GetDataSafe (), n) == 0); 00649 } 00650 00657 bool StartsWith (const char* iStr, bool ignore_case = false) const 00658 { 00659 char const* p = GetDataSafe(); 00660 if (iStr == 0) 00661 return false; 00662 size_t const n = strlen (iStr); 00663 if (n == 0) 00664 return true; 00665 if (n > Size) 00666 return false; 00667 CS_ASSERT(p != 0); 00668 if (ignore_case) 00669 return (csStrNCaseCmp (p, iStr, n) == 0); 00670 else 00671 return (strncmp (p, iStr, n) == 0); 00672 } 00673 00679 csStringBase Clone () const 00680 { return csStringBase (*this); } 00681 00689 csStringBase& LTrim(); 00690 00698 csStringBase& RTrim(); 00699 00705 csStringBase& Trim(); 00706 00712 csStringBase& Collapse(); 00713 00722 csStringBase& PadLeft (size_t NewSize, char PadChar = ' '); 00723 00732 csStringBase& PadRight (size_t NewSize, char PadChar = ' '); 00733 00745 csStringBase& PadCenter (size_t NewSize, char PadChar = ' '); 00746 00750 template<typename T> 00751 const csStringBase& operator = (T const& s) { return Replace (s); } 00752 00754 const csStringBase& operator = (const csStringBase& copy) 00755 { Replace(copy); return *this; } 00756 00760 template<typename T> 00761 csStringBase &operator += (T const& s) { return Append (s); } 00762 00763 // Specialization which prevents gcc from barfing on strings allocated via 00764 // CS_ALLOC_STACK_ARRAY(). 00765 csStringBase &operator += (char const* s) 00766 { return Append(s); } 00767 00769 csStringBase operator + (const csStringBase &iStr) const 00770 { return Clone ().Append (iStr); } 00771 00779 operator const char* () const 00780 { return GetData(); } 00781 00788 bool operator == (const csStringBase& Str) const 00789 { return Compare (Str); } 00796 bool operator == (const char* Str) const 00797 { return Compare (Str); } 00804 bool operator < (const csStringBase& Str) const 00805 { 00806 return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0; 00807 } 00814 bool operator < (const char* Str) const 00815 { 00816 return strcmp (GetDataSafe (), Str) < 0; 00817 } 00824 bool operator > (const csStringBase& Str) const 00825 { 00826 return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0; 00827 } 00834 bool operator > (const char* Str) const 00835 { 00836 return strcmp (GetDataSafe (), Str) > 0; 00837 } 00844 bool operator != (const csStringBase& Str) const 00845 { return !Compare (Str); } 00852 bool operator != (const char* Str) const 00853 { return !Compare (Str); } 00854 00862 template <typename T> 00863 csStringBase &operator << (T const& v) 00864 { return Append (v); } 00865 00866 // Specialization which prevents gcc from barfing on strings allocated via 00867 // CS_ALLOC_STACK_ARRAY(). 00868 csStringBase &operator << (char const* v) 00869 { return Append(v); } 00870 00875 csStringBase& Downcase(); 00880 csStringBase& Upcase(); 00881 00892 virtual char* Detach () 00893 { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; } 00898 uint GetHash() const; 00899 }; 00900 00902 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2) 00903 { 00904 return csStringBase (iStr1).Append (iStr2); 00905 } 00906 00908 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2) 00909 { 00910 return iStr1.Clone ().Append (iStr2); 00911 } 00912 00917 template<int LEN = 36> 00918 class csStringFast : public csStringBase 00919 { 00920 protected: 00922 char minibuff[LEN]; 00931 size_t miniused; 00932 00933 virtual void SetCapacityInternal (size_t NewSize, bool soft) 00934 { 00935 if (Data != 0) // If dynamic buffer already allocated, just re-use it. 00936 csStringBase::SetCapacityInternal(NewSize, soft); 00937 else 00938 { 00939 NewSize++; // Plus one for implicit null byte. 00940 if (NewSize <= LEN) 00941 miniused = NewSize; 00942 else 00943 { 00944 CS_ASSERT(MaxSize == 0); 00945 if (soft) 00946 NewSize = ComputeNewSize (NewSize); 00947 Data = new char[NewSize]; 00948 MaxSize = NewSize; 00949 if (Size == 0) 00950 Data[0] = '\0'; 00951 else 00952 memcpy(Data, minibuff, Size + 1); 00953 } 00954 } 00955 } 00956 00957 virtual char* GetDataMutable () 00958 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 00959 00960 public: 00964 csStringFast () : csStringBase(), miniused(0) { } 00969 csStringFast (size_t Length) : csStringBase(), miniused(0) 00970 { SetCapacity (Length); } 00974 csStringFast (const csStringBase& copy) : csStringBase (), miniused(0) 00975 { Append (copy); } 00979 csStringFast (const csStringFast& copy) : csStringBase (), miniused(0) 00980 { Append (copy); } 00984 csStringFast (const char* src) : csStringBase(), miniused(0) 00985 { Append (src); } 00989 csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0) 00990 { Append (src, _length); } 00991 00992 00994 csStringFast (char c) : csStringBase(), miniused(0) 00995 { Append (c); } 00997 csStringFast (unsigned char c) : csStringBase(), miniused(0) 00998 { Append ((char)c); } 01000 virtual ~csStringFast () { } 01001 01003 const csStringFast& operator = (const csStringBase& copy) 01004 { Replace(copy); return *this; } 01005 01007 template<typename T> 01008 const csStringFast& operator = (T const& s) { Replace (s); return *this; } 01009 01010 virtual char const* GetData () const 01011 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 01012 01013 virtual size_t GetCapacity() const 01014 { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; } 01015 01016 virtual void ShrinkBestFit () 01017 { 01018 if (Size == 0) 01019 { 01020 csStringBase::ShrinkBestFit(); 01021 miniused = 0; 01022 } 01023 else 01024 { 01025 size_t needed = Size + 1; 01026 if (needed > LEN) 01027 csStringBase::ShrinkBestFit(); 01028 else 01029 { 01030 miniused = needed; 01031 if (Data != 0) 01032 { 01033 memcpy(minibuff, Data, needed); // Includes implicit null byte. 01034 csStringBase::Free(); 01035 } 01036 } 01037 } 01038 } 01039 01040 virtual void Free () { miniused = 0; csStringBase::Free(); } 01041 01042 virtual char* Detach () 01043 { 01044 if (Data != 0) 01045 return csStringBase::Detach(); 01046 else if (miniused == 0) 01047 return 0; // Emulate NULL return of csStringBase in this case. 01048 else 01049 { 01050 CS_ASSERT(MaxSize == 0); 01051 char* d = csStrNew (minibuff); 01052 Size = 0; miniused = 0; 01053 return d; 01054 } 01055 } 01056 }; 01057 01058 CS_SPECIALIZE_TEMPLATE 01059 class csStringFast<0> : public csStringBase 01060 { 01061 public: 01062 csStringFast () : csStringBase() { } 01063 csStringFast (size_t Length) : csStringBase(Length) { } 01064 csStringFast (const csStringBase& copy) : csStringBase (copy) { } 01065 csStringFast (const char* src) : csStringBase(src) { } 01066 csStringFast (const char* src, size_t _length) : csStringBase(src, _length) 01067 { } 01068 csStringFast (char c) : csStringBase(c) { } 01069 csStringFast (unsigned char c) : csStringBase(c) { } 01070 const csStringFast& operator = (const csStringBase& copy) 01071 { Replace(copy); return *this; } 01072 const csStringFast& operator = (const char* copy) 01073 { Replace(copy); return *this; } 01074 const csStringFast& operator = (char x) 01075 { Replace(x); return *this; } 01076 const csStringFast& operator = (unsigned char x) 01077 { Replace(x); return *this; } 01078 const csStringFast& operator = (bool x) 01079 { Replace(x); return *this; } 01080 const csStringFast& operator = (short x) 01081 { Replace(x); return *this; } 01082 const csStringFast& operator = (unsigned short x) 01083 { Replace(x); return *this; } 01084 const csStringFast& operator = (int x) 01085 { Replace(x); return *this; } 01086 const csStringFast& operator = (unsigned int x) 01087 { Replace(x); return *this; } 01088 const csStringFast& operator = (long x) 01089 { Replace(x); return *this; } 01090 const csStringFast& operator = (unsigned long x) 01091 { Replace(x); return *this; } 01092 const csStringFast& operator = (float x) 01093 { Replace(x); return *this; } 01094 const csStringFast& operator = (double x) 01095 { Replace(x); return *this; } 01096 #ifndef __STRICT_ANSI__ 01097 const csStringFast& operator = (longlong x) 01098 { Replace(x); return *this; } 01099 const csStringFast& operator = (ulonglong x) 01100 { Replace(x); return *this; } 01101 #endif 01102 }; 01103 01104 #ifndef SWIG 01105 01110 typedef csStringFast<> csStringFastDefault; 01111 #else 01112 #define csStringFastDefault csStringFast<36> 01113 %template(csStringParent) csStringFast<36>; 01114 #endif 01115 01119 class csString : public csStringFastDefault 01120 { 01121 public: 01123 csString () : csStringFast<> () { } 01128 csString (size_t Length) : csStringFast<> (Length) { } 01130 01131 csString (const csString& copy) : 01132 csStringFast<> ((const csStringBase&)copy) { } 01133 csString (const csStringBase& copy) : csStringFast<> (copy) { } 01135 01136 csString (const char* src) : csStringFast<> (src) { } 01138 csString (const char* src, size_t _length) : csStringFast<> (src, _length) { } 01140 csString (char c) : csStringFast<> (c) { } 01142 csString (unsigned char c) : csStringFast<> (c) { } 01143 01145 01146 const csString& operator = (const csString& copy) 01147 { Replace(copy); return *this; } 01148 const csString& operator = (const csStringBase& copy) 01149 { Replace(copy); return *this; } 01150 const csString& operator = (const char* copy) 01151 { Replace(copy); return *this; } 01152 const csString& operator = (char x) 01153 { Replace(x); return *this; } 01154 const csString& operator = (unsigned char x) 01155 { Replace(x); return *this; } 01156 const csString& operator = (bool x) 01157 { Replace(x); return *this; } 01158 const csString& operator = (short x) 01159 { Replace(x); return *this; } 01160 const csString& operator = (unsigned short x) 01161 { Replace(x); return *this; } 01162 const csString& operator = (int x) 01163 { Replace(x); return *this; } 01164 const csString& operator = (unsigned int x) 01165 { Replace(x); return *this; } 01166 const csString& operator = (long x) 01167 { Replace(x); return *this; } 01168 const csString& operator = (unsigned long x) 01169 { Replace(x); return *this; } 01170 const csString& operator = (float x) 01171 { Replace(x); return *this; } 01172 const csString& operator = (double x) 01173 { Replace(x); return *this; } 01174 #ifndef __STRICT_ANSI__ 01175 const csString& operator = (longlong x) 01176 { Replace(x); return *this; } 01177 const csString& operator = (ulonglong x) 01178 { Replace(x); return *this; } 01179 #endif 01180 01181 }; 01182 01183 #endif // __CS_CSSTRING_H__
Generated for Crystal Space by doxygen 1.4.6