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 00543 void ReplaceAll (const char* search, const char* replacement); 00544 00550 /* CS_DEPRECATED_METHOD_MSG("Use ReplaceAll() instead.") */ 00551 void FindReplace (const char* search, const char* replacement) 00552 { ReplaceAll(search, replacement); } 00553 00561 csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3); 00562 00570 csStringBase& FormatV (const char* format, va_list args); 00571 00581 csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1); 00582 00592 csStringBase& Replace (const char* Str, size_t Count = (size_t)-1); 00593 00598 template<typename T> 00599 csStringBase& Replace (T const& val) { Truncate (0); return Append (val); } 00600 00607 bool Compare (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 (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0); 00617 } 00618 00625 bool Compare (const char* iStr) const 00626 { return (strcmp (GetDataSafe(), iStr) == 0); } 00627 00634 bool CompareNoCase (const csStringBase& iStr) const 00635 { 00636 if (&iStr == this) 00637 return true; 00638 size_t const n = iStr.Length(); 00639 if (Size != n) 00640 return false; 00641 if (Size == 0 && n == 0) 00642 return true; 00643 return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0); 00644 } 00645 00652 bool CompareNoCase (const char* iStr) const 00653 { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); } 00654 00661 bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const 00662 { 00663 char const* p = GetDataSafe(); 00664 if (&iStr == this) 00665 return true; 00666 size_t const n = iStr.Length(); 00667 if (n == 0) 00668 return true; 00669 if (n > Size) 00670 return false; 00671 CS_ASSERT(p != 0); 00672 if (ignore_case) 00673 return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0); 00674 else 00675 return (strncmp (p, iStr.GetDataSafe (), n) == 0); 00676 } 00677 00684 bool StartsWith (const char* iStr, bool ignore_case = false) const 00685 { 00686 char const* p = GetDataSafe(); 00687 if (iStr == 0) 00688 return false; 00689 size_t const n = strlen (iStr); 00690 if (n == 0) 00691 return true; 00692 if (n > Size) 00693 return false; 00694 CS_ASSERT(p != 0); 00695 if (ignore_case) 00696 return (csStrNCaseCmp (p, iStr, n) == 0); 00697 else 00698 return (strncmp (p, iStr, n) == 0); 00699 } 00700 00706 csStringBase Clone () const 00707 { return csStringBase (*this); } 00708 00716 csStringBase& LTrim(); 00717 00725 csStringBase& RTrim(); 00726 00732 csStringBase& Trim(); 00733 00739 csStringBase& Collapse(); 00740 00749 csStringBase& PadLeft (size_t NewSize, char PadChar = ' '); 00750 00759 csStringBase& PadRight (size_t NewSize, char PadChar = ' '); 00760 00772 csStringBase& PadCenter (size_t NewSize, char PadChar = ' '); 00773 00777 template<typename T> 00778 const csStringBase& operator = (T const& s) { return Replace (s); } 00779 00781 const csStringBase& operator = (const csStringBase& copy) 00782 { Replace(copy); return *this; } 00783 00787 template<typename T> 00788 csStringBase &operator += (T const& s) { return Append (s); } 00789 00790 // Specialization which prevents gcc from barfing on strings allocated via 00791 // CS_ALLOC_STACK_ARRAY(). 00792 csStringBase &operator += (char const* s) 00793 { return Append(s); } 00794 00796 csStringBase operator + (const csStringBase &iStr) const 00797 { return Clone ().Append (iStr); } 00798 00806 operator const char* () const 00807 { return GetData(); } 00808 00815 bool operator == (const csStringBase& Str) const 00816 { return Compare (Str); } 00823 bool operator == (const char* Str) const 00824 { return Compare (Str); } 00831 bool operator < (const csStringBase& Str) const 00832 { 00833 return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0; 00834 } 00841 bool operator < (const char* Str) const 00842 { 00843 return strcmp (GetDataSafe (), Str) < 0; 00844 } 00851 bool operator > (const csStringBase& Str) const 00852 { 00853 return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0; 00854 } 00861 bool operator > (const char* Str) const 00862 { 00863 return strcmp (GetDataSafe (), Str) > 0; 00864 } 00871 bool operator != (const csStringBase& Str) const 00872 { return !Compare (Str); } 00879 bool operator != (const char* Str) const 00880 { return !Compare (Str); } 00881 00889 template <typename T> 00890 csStringBase &operator << (T const& v) 00891 { return Append (v); } 00892 00893 // Specialization which prevents gcc from barfing on strings allocated via 00894 // CS_ALLOC_STACK_ARRAY(). 00895 csStringBase &operator << (char const* v) 00896 { return Append(v); } 00897 00908 csStringBase& Downcase (uint flags = csUcMapSimple); 00919 csStringBase& Upcase (uint flags = csUcMapSimple); 00920 00931 virtual char* Detach () 00932 { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; } 00937 uint GetHash() const; 00938 }; 00939 00941 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2) 00942 { 00943 return csStringBase (iStr1).Append (iStr2); 00944 } 00945 00947 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2) 00948 { 00949 return iStr1.Clone ().Append (iStr2); 00950 } 00951 00956 template<int LEN = 36> 00957 class csStringFast : public csStringBase 00958 { 00959 protected: 00961 char minibuff[LEN]; 00970 size_t miniused; 00971 00972 virtual void SetCapacityInternal (size_t NewSize, bool soft) 00973 { 00974 if (Data != 0) // If dynamic buffer already allocated, just re-use it. 00975 csStringBase::SetCapacityInternal(NewSize, soft); 00976 else 00977 { 00978 NewSize++; // Plus one for implicit null byte. 00979 if (NewSize <= LEN) 00980 miniused = NewSize; 00981 else 00982 { 00983 CS_ASSERT(MaxSize == 0); 00984 if (soft) 00985 NewSize = ComputeNewSize (NewSize); 00986 Data = new char[NewSize]; 00987 MaxSize = NewSize; 00988 if (Size == 0) 00989 Data[0] = '\0'; 00990 else 00991 memcpy(Data, minibuff, Size + 1); 00992 } 00993 } 00994 } 00995 00996 virtual char* GetDataMutable () 00997 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 00998 00999 public: 01003 csStringFast () : csStringBase(), miniused(0) { } 01008 csStringFast (size_t Length) : csStringBase(), miniused(0) 01009 { SetCapacity (Length); } 01013 csStringFast (const csStringBase& copy) : csStringBase (), miniused(0) 01014 { Append (copy); } 01018 csStringFast (const csStringFast& copy) : csStringBase (), miniused(0) 01019 { Append (copy); } 01023 csStringFast (const char* src) : csStringBase(), miniused(0) 01024 { Append (src); } 01028 csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0) 01029 { Append (src, _length); } 01030 01031 01033 csStringFast (char c) : csStringBase(), miniused(0) 01034 { Append (c); } 01036 csStringFast (unsigned char c) : csStringBase(), miniused(0) 01037 { Append ((char)c); } 01039 virtual ~csStringFast () { } 01040 01042 const csStringFast& operator = (const csStringBase& copy) 01043 { Replace(copy); return *this; } 01044 01046 template<typename T> 01047 const csStringFast& operator = (T const& s) { Replace (s); return *this; } 01048 01049 virtual char const* GetData () const 01050 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 01051 01052 virtual size_t GetCapacity() const 01053 { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; } 01054 01055 virtual void ShrinkBestFit () 01056 { 01057 if (Size == 0) 01058 { 01059 csStringBase::ShrinkBestFit(); 01060 miniused = 0; 01061 } 01062 else 01063 { 01064 size_t needed = Size + 1; 01065 if (needed > LEN) 01066 csStringBase::ShrinkBestFit(); 01067 else 01068 { 01069 miniused = needed; 01070 if (Data != 0) 01071 { 01072 memcpy(minibuff, Data, needed); // Includes implicit null byte. 01073 csStringBase::Free(); 01074 } 01075 } 01076 } 01077 } 01078 01079 virtual void Free () { miniused = 0; csStringBase::Free(); } 01080 01081 virtual char* Detach () 01082 { 01083 if (Data != 0) 01084 return csStringBase::Detach(); 01085 else if (miniused == 0) 01086 return 0; // Emulate NULL return of csStringBase in this case. 01087 else 01088 { 01089 CS_ASSERT(MaxSize == 0); 01090 char* d = csStrNew (minibuff); 01091 Size = 0; miniused = 0; 01092 return d; 01093 } 01094 } 01095 }; 01096 01097 template<> 01098 class csStringFast<0> : public csStringBase 01099 { 01100 public: 01101 csStringFast () : csStringBase() { } 01102 csStringFast (size_t Length) : csStringBase(Length) { } 01103 csStringFast (const csStringBase& copy) : csStringBase (copy) { } 01104 csStringFast (const char* src) : csStringBase(src) { } 01105 csStringFast (const char* src, size_t _length) : csStringBase(src, _length) 01106 { } 01107 csStringFast (char c) : csStringBase(c) { } 01108 csStringFast (unsigned char c) : csStringBase(c) { } 01109 const csStringFast& operator = (const csStringBase& copy) 01110 { Replace(copy); return *this; } 01111 const csStringFast& operator = (const char* copy) 01112 { Replace(copy); return *this; } 01113 const csStringFast& operator = (char x) 01114 { Replace(x); return *this; } 01115 const csStringFast& operator = (unsigned char x) 01116 { Replace(x); return *this; } 01117 const csStringFast& operator = (bool x) 01118 { Replace(x); return *this; } 01119 const csStringFast& operator = (short x) 01120 { Replace(x); return *this; } 01121 const csStringFast& operator = (unsigned short x) 01122 { Replace(x); return *this; } 01123 const csStringFast& operator = (int x) 01124 { Replace(x); return *this; } 01125 const csStringFast& operator = (unsigned int x) 01126 { Replace(x); return *this; } 01127 const csStringFast& operator = (long x) 01128 { Replace(x); return *this; } 01129 const csStringFast& operator = (unsigned long x) 01130 { Replace(x); return *this; } 01131 const csStringFast& operator = (float x) 01132 { Replace(x); return *this; } 01133 const csStringFast& operator = (double x) 01134 { Replace(x); return *this; } 01135 #ifndef __STRICT_ANSI__ 01136 const csStringFast& operator = (longlong x) 01137 { Replace(x); return *this; } 01138 const csStringFast& operator = (ulonglong x) 01139 { Replace(x); return *this; } 01140 #endif 01141 }; 01142 01143 #ifndef SWIG 01144 01149 typedef csStringFast<> csStringFastDefault; 01150 #else 01151 #define csStringFastDefault csStringFast<36> 01152 %template(csStringParent) csStringFast<36>; 01153 #endif 01154 01158 class csString : public csStringFastDefault 01159 { 01160 public: 01162 csString () : csStringFast<> () { } 01167 csString (size_t Length) : csStringFast<> (Length) { } 01169 01170 csString (const csString& copy) : 01171 csStringFast<> ((const csStringBase&)copy) { } 01172 csString (const csStringBase& copy) : csStringFast<> (copy) { } 01174 01175 csString (const char* src) : csStringFast<> (src) { } 01177 csString (const char* src, size_t _length) : csStringFast<> (src, _length) { } 01179 csString (char c) : csStringFast<> (c) { } 01181 csString (unsigned char c) : csStringFast<> (c) { } 01182 01184 01185 const csString& operator = (const csString& copy) 01186 { Replace(copy); return *this; } 01187 const csString& operator = (const csStringBase& copy) 01188 { Replace(copy); return *this; } 01189 const csString& operator = (const char* copy) 01190 { Replace(copy); return *this; } 01191 const csString& operator = (char x) 01192 { Replace(x); return *this; } 01193 const csString& operator = (unsigned char x) 01194 { Replace(x); return *this; } 01195 const csString& operator = (bool x) 01196 { Replace(x); return *this; } 01197 const csString& operator = (short x) 01198 { Replace(x); return *this; } 01199 const csString& operator = (unsigned short x) 01200 { Replace(x); return *this; } 01201 const csString& operator = (int x) 01202 { Replace(x); return *this; } 01203 const csString& operator = (unsigned int x) 01204 { Replace(x); return *this; } 01205 const csString& operator = (long x) 01206 { Replace(x); return *this; } 01207 const csString& operator = (unsigned long x) 01208 { Replace(x); return *this; } 01209 const csString& operator = (float x) 01210 { Replace(x); return *this; } 01211 const csString& operator = (double x) 01212 { Replace(x); return *this; } 01213 #ifndef __STRICT_ANSI__ 01214 const csString& operator = (longlong x) 01215 { Replace(x); return *this; } 01216 const csString& operator = (ulonglong x) 01217 { Replace(x); return *this; } 01218 #endif 01219 01220 }; 01221 01222 #endif // __CS_CSSTRING_H__
Generated for Crystal Space 1.2.1 by doxygen 1.5.3