Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages
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 00053 class CS_CRYSTALSPACE_EXPORT csStringBase 00054 { 00055 protected: 00060 enum { DEFAULT_GROW_BY = 64 }; 00061 00063 char* Data; 00065 size_t Size; 00067 size_t MaxSize; 00072 size_t GrowBy; 00073 00079 void ExpandIfNeeded (size_t NewSize); 00080 00085 virtual void SetCapacityInternal (size_t NewSize, bool soft); 00086 00088 size_t ComputeNewSize (size_t NewSize); 00089 00101 virtual char* GetDataMutable () 00102 { return Data; } 00103 00104 public: 00112 void SetCapacity (size_t NewSize); 00113 00118 virtual size_t GetCapacity() const 00119 { return MaxSize > 0 ? MaxSize - 1 : 0; } 00120 00128 csStringBase& Append (const char* Str, size_t Count = (size_t)-1); 00129 00137 csStringBase& Append (const csStringBase& Str, size_t Count = (size_t)-1); 00138 00143 csStringBase& Append (char c); 00144 00149 /*csStringBase& Append (unsigned char c) 00150 { return Append(char(c)); }*/ 00151 00153 csStringBase& Append (bool b) { return Append (b ? "1" : "0"); } 00154 00160 csStringBase& AppendFmt (const char* format, ...) CS_GNUC_PRINTF (2, 3); 00161 csStringBase& AppendFmtV (const char* format, va_list args); 00165 00166 csStringBase& Append (short v) { return AppendFmt ("%hd", v); } 00167 csStringBase& Append (unsigned short v) { return AppendFmt ("%hu", v); } 00168 csStringBase& Append (int v) { return AppendFmt ("%d", v); } 00169 csStringBase& Append (unsigned int v) { return AppendFmt ("%u", v); } 00170 csStringBase& Append (long v) { return AppendFmt ("%ld", v); } 00171 csStringBase& Append (unsigned long v) { return AppendFmt ("%lu", v); } 00172 csStringBase& Append (float v) { return AppendFmt ("%g", v); } 00173 csStringBase& Append (double v) { return AppendFmt ("%g", v); } 00174 #ifndef __STRICT_ANSI__ 00175 csStringBase& Append (longlong v) { return AppendFmt ("%lld", v); } 00176 csStringBase& Append (ulonglong v) { return AppendFmt ("%llu", v); } 00177 #endif 00178 00184 csStringBase () : Data (0), Size (0), MaxSize (0), GrowBy (DEFAULT_GROW_BY) 00185 {} 00186 00193 csStringBase (size_t Length) : Data (0), Size (0), MaxSize (0), 00194 GrowBy (DEFAULT_GROW_BY) 00195 { SetCapacity (Length); } 00196 00202 csStringBase (const csStringBase& copy) : Data (0), Size (0), MaxSize (0), 00203 GrowBy (DEFAULT_GROW_BY) 00204 { Append (copy); } 00205 00211 csStringBase (const char* src) : Data (0), Size (0), MaxSize (0), 00212 GrowBy (DEFAULT_GROW_BY) 00213 { Append (src); } 00214 00220 csStringBase (const char* src, size_t _length) : Data (0), Size (0), MaxSize (0), 00221 GrowBy (DEFAULT_GROW_BY) 00222 { Append (src, _length); } 00223 00225 csStringBase (char c) : Data (0), Size (0), MaxSize (0), 00226 GrowBy (DEFAULT_GROW_BY) 00227 { Append (c); } 00228 00230 csStringBase (unsigned char c) : Data(0), Size (0), MaxSize (0), 00231 GrowBy (DEFAULT_GROW_BY) 00232 { Append ((char) c); } 00233 00235 virtual ~csStringBase (); 00236 00249 void SetGrowsBy(size_t); 00250 00256 size_t GetGrowsBy() const 00257 { return GrowBy; } 00258 00263 CS_DEPRECATED_METHOD void SetGrowsExponentially(bool b) 00264 { SetGrowsBy(b ? 0 : DEFAULT_GROW_BY); } 00265 00270 CS_DEPRECATED_METHOD bool GetGrowsExponentially() const 00271 { return GetGrowsBy() == 0; } 00272 00279 virtual void Free (); 00280 00297 csStringBase& Truncate (size_t Len); 00298 00304 csStringBase& Empty() { return Truncate (0); } 00305 00315 virtual void ShrinkBestFit (); 00316 00326 csStringBase& Reclaim () { ShrinkBestFit(); return *this; } 00327 00334 csStringBase& Clear () { return Empty(); } 00335 00343 virtual char const* GetData () const 00344 { return Data; } 00345 00355 char const* GetDataSafe() const 00356 { char const* p = GetData(); return p != 0 ? p : ""; } 00357 00363 size_t Length () const 00364 { return Size; } 00365 00371 bool IsEmpty () const 00372 { return (Size == 0); } 00373 00375 char& operator [] (size_t n) 00376 { 00377 CS_ASSERT (n < Size); 00378 return GetDataMutable()[n]; 00379 } 00380 00382 char operator [] (size_t n) const 00383 { 00384 CS_ASSERT (n < Size); 00385 return GetData()[n]; 00386 } 00387 00394 void SetAt (size_t n, const char c) 00395 { 00396 CS_ASSERT (n < Size); 00397 GetDataMutable() [n] = c; 00398 } 00399 00401 char GetAt (size_t n) const 00402 { 00403 CS_ASSERT (n < Size); 00404 return GetData() [n]; 00405 } 00406 00413 csStringBase& DeleteAt (size_t Pos, size_t Count = 1); 00414 00421 csStringBase& Insert (size_t Pos, const csStringBase& Str); 00422 00429 csStringBase& Insert (size_t Pos, const char* Str); 00430 00437 csStringBase& Insert (size_t Pos, char C); 00438 00447 csStringBase& Overwrite (size_t Pos, const csStringBase& Str); 00448 00455 csStringBase Slice (size_t start, size_t len = (size_t)-1) const; 00456 00467 void SubString (csStringBase& sub, size_t start, 00468 size_t len = (size_t)-1) const; 00469 00476 size_t FindFirst (char c, size_t pos = 0) const; 00477 00484 size_t FindFirst (const char *c, size_t pos = 0) const; 00485 00493 size_t FindLast (char c, size_t pos = (size_t)-1) const; 00494 00501 size_t Find (const char* search, size_t pos = 0) const; 00502 00510 /* CS_DEPRECATED_METHOD */ 00511 size_t FindStr (const char* search, size_t pos = 0) const 00512 { return Find(search, pos); } 00513 00518 void ReplaceAll (const char* search, const char* replacement); 00519 00525 /* CS_DEPRECATED_METHOD */ 00526 void FindReplace (const char* search, const char* replacement) 00527 { ReplaceAll(search, replacement); } 00528 00536 csStringBase& Format (const char* format, ...) CS_GNUC_PRINTF (2, 3); 00537 00545 csStringBase& FormatV (const char* format, va_list args); 00546 00556 csStringBase& Replace (const csStringBase& Str, size_t Count = (size_t)-1); 00557 00567 csStringBase& Replace (const char* Str, size_t Count = (size_t)-1); 00568 00573 template<typename T> 00574 csStringBase& Replace (T const& val) { Truncate (0); return Append (val); } 00575 00582 bool Compare (const csStringBase& iStr) const 00583 { 00584 if (&iStr == this) 00585 return true; 00586 size_t const n = iStr.Length(); 00587 if (Size != n) 00588 return false; 00589 if (Size == 0 && n == 0) 00590 return true; 00591 return (memcmp (GetDataSafe(), iStr.GetDataSafe (), Size) == 0); 00592 } 00593 00600 bool Compare (const char* iStr) const 00601 { return (strcmp (GetDataSafe(), iStr) == 0); } 00602 00609 bool CompareNoCase (const csStringBase& iStr) const 00610 { 00611 if (&iStr == this) 00612 return true; 00613 size_t const n = iStr.Length(); 00614 if (Size != n) 00615 return false; 00616 if (Size == 0 && n == 0) 00617 return true; 00618 return (csStrNCaseCmp (GetDataSafe(), iStr.GetDataSafe(), Size) == 0); 00619 } 00620 00627 bool CompareNoCase (const char* iStr) const 00628 { return (csStrCaseCmp (GetDataSafe(), iStr) == 0); } 00629 00636 bool StartsWith (const csStringBase& iStr, bool ignore_case = false) const 00637 { 00638 char const* p = GetDataSafe(); 00639 if (&iStr == this) 00640 return true; 00641 size_t const n = iStr.Length(); 00642 if (n == 0) 00643 return true; 00644 if (n > Size) 00645 return false; 00646 CS_ASSERT(p != 0); 00647 if (ignore_case) 00648 return (csStrNCaseCmp (p, iStr.GetDataSafe (), n) == 0); 00649 else 00650 return (strncmp (p, iStr.GetDataSafe (), n) == 0); 00651 } 00652 00659 bool StartsWith (const char* iStr, bool ignore_case = false) const 00660 { 00661 char const* p = GetDataSafe(); 00662 if (iStr == 0) 00663 return false; 00664 size_t const n = strlen (iStr); 00665 if (n == 0) 00666 return true; 00667 if (n > Size) 00668 return false; 00669 CS_ASSERT(p != 0); 00670 if (ignore_case) 00671 return (csStrNCaseCmp (p, iStr, n) == 0); 00672 else 00673 return (strncmp (p, iStr, n) == 0); 00674 } 00675 00681 csStringBase Clone () const 00682 { return csStringBase (*this); } 00683 00691 csStringBase& LTrim(); 00692 00700 csStringBase& RTrim(); 00701 00707 csStringBase& Trim(); 00708 00714 csStringBase& Collapse(); 00715 00724 csStringBase& PadLeft (size_t NewSize, char PadChar = ' '); 00725 00734 csStringBase& PadRight (size_t NewSize, char PadChar = ' '); 00735 00747 csStringBase& PadCenter (size_t NewSize, char PadChar = ' '); 00748 00752 template<typename T> 00753 const csStringBase& operator = (T const& s) { return Replace (s); } 00754 00758 template<typename T> 00759 csStringBase &operator += (T const& s) { return Append (s); } 00760 00761 // Specialization which prevents gcc from barfing on strings allocated via 00762 // CS_ALLOC_STACK_ARRAY(). 00763 csStringBase &operator += (char const* s) 00764 { return Append(s); } 00765 00767 csStringBase operator + (const csStringBase &iStr) const 00768 { return Clone ().Append (iStr); } 00769 00777 operator const char* () const 00778 { return GetData(); } 00779 00786 bool operator == (const csStringBase& Str) const 00787 { return Compare (Str); } 00794 bool operator == (const char* Str) const 00795 { return Compare (Str); } 00802 bool operator < (const csStringBase& Str) const 00803 { 00804 return strcmp (GetDataSafe (), Str.GetDataSafe ()) < 0; 00805 } 00812 bool operator < (const char* Str) const 00813 { 00814 return strcmp (GetDataSafe (), Str) < 0; 00815 } 00822 bool operator > (const csStringBase& Str) const 00823 { 00824 return strcmp (GetDataSafe (), Str.GetDataSafe ()) > 0; 00825 } 00832 bool operator > (const char* Str) const 00833 { 00834 return strcmp (GetDataSafe (), Str) > 0; 00835 } 00842 bool operator != (const csStringBase& Str) const 00843 { return !Compare (Str); } 00850 bool operator != (const char* Str) const 00851 { return !Compare (Str); } 00852 00860 template <typename T> 00861 csStringBase &operator << (T const& v) 00862 { return Append (v); } 00863 00864 // Specialization which prevents gcc from barfing on strings allocated via 00865 // CS_ALLOC_STACK_ARRAY(). 00866 csStringBase &operator << (char const* v) 00867 { return Append(v); } 00868 00873 csStringBase& Downcase(); 00878 csStringBase& Upcase(); 00879 00890 virtual char* Detach () 00891 { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; } 00896 uint GetHash() const; 00897 }; 00898 00900 inline csStringBase operator + (const char* iStr1, const csStringBase &iStr2) 00901 { 00902 return csStringBase (iStr1).Append (iStr2); 00903 } 00904 00906 inline csStringBase operator + (const csStringBase& iStr1, const char* iStr2) 00907 { 00908 return iStr1.Clone ().Append (iStr2); 00909 } 00910 00915 template<int LEN = 36> 00916 class csStringFast : public csStringBase 00917 { 00918 protected: 00920 char minibuff[LEN]; 00929 size_t miniused; 00930 00931 virtual void SetCapacityInternal (size_t NewSize, bool soft) 00932 { 00933 if (Data != 0) // If dynamic buffer already allocated, just re-use it. 00934 csStringBase::SetCapacityInternal(NewSize, soft); 00935 else 00936 { 00937 NewSize++; // Plus one for implicit null byte. 00938 if (NewSize <= LEN) 00939 miniused = NewSize; 00940 else 00941 { 00942 CS_ASSERT(MaxSize == 0); 00943 if (soft) 00944 NewSize = ComputeNewSize (NewSize); 00945 Data = new char[NewSize]; 00946 MaxSize = NewSize; 00947 if (Size == 0) 00948 Data[0] = '\0'; 00949 else 00950 memcpy(Data, minibuff, Size + 1); 00951 } 00952 } 00953 } 00954 00955 virtual char* GetDataMutable () 00956 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 00957 00958 public: 00962 csStringFast () : csStringBase(), miniused(0) { } 00967 csStringFast (size_t Length) : csStringBase(), miniused(0) 00968 { SetCapacity (Length); } 00972 csStringFast (const csStringBase& copy) : csStringBase (), miniused(0) 00973 { Append (copy); } 00977 csStringFast (const csStringFast& copy) : csStringBase (), miniused(0) 00978 { Append (copy); } 00982 csStringFast (const char* src) : csStringBase(), miniused(0) 00983 { Append (src); } 00987 csStringFast (const char* src, size_t _length) : csStringBase(), miniused(0) 00988 { Append (src, _length); } 00989 00990 00992 csStringFast (char c) : csStringBase(), miniused(0) 00993 { Append (c); } 00995 csStringFast (unsigned char c) : csStringBase(), miniused(0) 00996 { Append ((char)c); } 00998 virtual ~csStringFast () { } 00999 01001 const csStringFast& operator = (const csStringBase& copy) 01002 { Replace(copy); return *this; } 01003 01005 template<typename T> 01006 const csStringFast& operator = (T const& s) { Replace (s); return *this; } 01007 01008 virtual char const* GetData () const 01009 { return (miniused == 0 && Data == 0 ? 0 : (Data != 0 ? Data : minibuff)); } 01010 01011 virtual size_t GetCapacity() const 01012 { return Data != 0 ? csStringBase::GetCapacity() : miniused - 1; } 01013 01014 virtual void ShrinkBestFit () 01015 { 01016 if (Size == 0) 01017 { 01018 csStringBase::ShrinkBestFit(); 01019 miniused = 0; 01020 } 01021 else 01022 { 01023 size_t needed = Size + 1; 01024 if (needed > LEN) 01025 csStringBase::ShrinkBestFit(); 01026 else 01027 { 01028 miniused = needed; 01029 if (Data != 0) 01030 { 01031 memcpy(minibuff, Data, needed); // Includes implicit null byte. 01032 csStringBase::Free(); 01033 } 01034 } 01035 } 01036 } 01037 01038 virtual void Free () { miniused = 0; csStringBase::Free(); } 01039 01040 virtual char* Detach () 01041 { 01042 if (Data != 0) 01043 return csStringBase::Detach(); 01044 else if (miniused == 0) 01045 return 0; // Emulate NULL return of csStringBase in this case. 01046 else 01047 { 01048 CS_ASSERT(MaxSize == 0); 01049 char* d = csStrNew (minibuff); 01050 Size = 0; miniused = 0; 01051 return d; 01052 } 01053 } 01054 }; 01055 01056 CS_SPECIALIZE_TEMPLATE 01057 class csStringFast<0> : public csStringBase 01058 { 01059 public: 01060 csStringFast () : csStringBase() { } 01061 csStringFast (size_t Length) : csStringBase(Length) { } 01062 csStringFast (const csStringBase& copy) : csStringBase (copy) { } 01063 csStringFast (const char* src) : csStringBase(src) { } 01064 csStringFast (const char* src, size_t _length) : csStringBase(src, _length) { } 01065 csStringFast (char c) : csStringBase(c) { } 01066 csStringFast (unsigned char c) : csStringBase(c) { } 01067 const csStringFast& operator = (const csStringBase& copy) 01068 { Replace(copy); return *this; } 01069 const csStringFast& operator = (const char* copy) 01070 { Replace(copy); return *this; } 01071 const csStringFast& operator = (char x) 01072 { Replace(x); return *this; } 01073 const csStringFast& operator = (unsigned char x) 01074 { Replace(x); return *this; } 01075 const csStringFast& operator = (bool x) 01076 { Replace(x); return *this; } 01077 const csStringFast& operator = (short x) 01078 { Replace(x); return *this; } 01079 const csStringFast& operator = (unsigned short x) 01080 { Replace(x); return *this; } 01081 const csStringFast& operator = (int x) 01082 { Replace(x); return *this; } 01083 const csStringFast& operator = (unsigned int x) 01084 { Replace(x); return *this; } 01085 const csStringFast& operator = (long x) 01086 { Replace(x); return *this; } 01087 const csStringFast& operator = (unsigned long x) 01088 { Replace(x); return *this; } 01089 const csStringFast& operator = (float x) 01090 { Replace(x); return *this; } 01091 const csStringFast& operator = (double x) 01092 { Replace(x); return *this; } 01093 #ifndef __STRICT_ANSI__ 01094 const csStringFast& operator = (longlong x) 01095 { Replace(x); return *this; } 01096 const csStringFast& operator = (ulonglong x) 01097 { Replace(x); return *this; } 01098 #endif 01099 }; 01100 01101 #ifndef SWIG 01102 01107 typedef csStringFast<> csStringFastDefault; 01108 #else 01109 #define csStringFastDefault csStringFast<36> 01110 %template(csStringParent) csStringFast<36>; 01111 #endif 01112 01116 class csString : public csStringFastDefault 01117 { 01118 public: 01120 csString () : csStringFast<> () { } 01125 csString (size_t Length) : csStringFast<> (Length) { } 01127 01128 csString (const csString& copy) : 01129 csStringFast<> ((const csStringBase&)copy) { } 01130 csString (const csStringBase& copy) : csStringFast<> (copy) { } 01132 01133 csString (const char* src) : csStringFast<> (src) { } 01135 csString (const char* src, size_t _length) : csStringFast<> (src, _length) { } 01137 csString (char c) : csStringFast<> (c) { } 01139 csString (unsigned char c) : csStringFast<> (c) { } 01140 01142 01143 const csString& operator = (const csString& copy) 01144 { Replace(copy); return *this; } 01145 const csString& operator = (const csStringBase& copy) 01146 { Replace(copy); return *this; } 01147 const csString& operator = (const char* copy) 01148 { Replace(copy); return *this; } 01149 const csString& operator = (char x) 01150 { Replace(x); return *this; } 01151 const csString& operator = (unsigned char x) 01152 { Replace(x); return *this; } 01153 const csString& operator = (bool x) 01154 { Replace(x); return *this; } 01155 const csString& operator = (short x) 01156 { Replace(x); return *this; } 01157 const csString& operator = (unsigned short x) 01158 { Replace(x); return *this; } 01159 const csString& operator = (int x) 01160 { Replace(x); return *this; } 01161 const csString& operator = (unsigned int x) 01162 { Replace(x); return *this; } 01163 const csString& operator = (long x) 01164 { Replace(x); return *this; } 01165 const csString& operator = (unsigned long x) 01166 { Replace(x); return *this; } 01167 const csString& operator = (float x) 01168 { Replace(x); return *this; } 01169 const csString& operator = (double x) 01170 { Replace(x); return *this; } 01171 #ifndef __STRICT_ANSI__ 01172 const csString& operator = (longlong x) 01173 { Replace(x); return *this; } 01174 const csString& operator = (ulonglong x) 01175 { Replace(x); return *this; } 01176 #endif 01177 01178 }; 01179 01180 #endif // __CS_CSSTRING_H__
Generated for Crystal Space by doxygen 1.4.4