csutil/csstring.h
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 00022 #include <stdarg.h> 00023 #include <ctype.h> 00024 #include "snprintf.h" 00025 00034 class csString 00035 { 00036 protected: 00037 // Default number of bytes by which allocation should grow. 00038 // *** IMPORTANT *** This must be a power of two (i.e. 8, 16, 32, 64, etc.). 00039 enum { DEFAULT_GROW_BY = 64 }; 00040 00041 // String buffer. 00042 char* Data; 00043 // Length of string; not including null terminator. 00044 size_t Size; 00045 // Size in bytes of allocated string buffer. 00046 size_t MaxSize; 00047 // Size in bytes by which allocated buffer is increased when needed. 00048 size_t GrowBy; 00049 // Controls if allocated buffer grows exponentially (overrides GrowBy). 00050 bool GrowExponentially; 00051 00052 // If necessary, increase the buffer capacity enough to hold NewSize bytes. 00053 // Buffer capacity is increased in GrowBy increments or exponentially 00054 // depending upon configuration. 00055 void ExpandIfNeeded(size_t NewSize); 00056 00057 public: 00065 void SetCapacity (size_t NewSize); 00066 00068 size_t GetCapacity() const 00069 { return MaxSize; } 00070 00078 void SetGrowsBy(size_t); 00079 00081 size_t GetGrowsBy() const 00082 { return GrowBy; } 00083 00088 void SetGrowsExponentially(bool b) 00089 { GrowExponentially = b; } 00090 00092 bool GetGrowsExponentially() const 00093 { return GrowExponentially; } 00094 00096 void Free (); 00097 00099 csString& Truncate (size_t Len); 00100 00105 csString& Reclaim (); 00106 00111 csString& Clear () 00112 { return Truncate (0); } 00113 00115 char const* GetData () const 00116 { return Data; } 00117 00122 char* GetData () 00123 { return Data; } 00124 00126 size_t Length () const 00127 { return Size; } 00128 00130 bool IsEmpty () const 00131 { return (Size == 0); } 00132 00134 char& operator [] (size_t n) 00135 { 00136 CS_ASSERT (n < Size); 00137 return Data [n]; 00138 } 00139 00141 char operator [] (size_t n) const 00142 { 00143 CS_ASSERT (n < Size); 00144 return Data[n]; 00145 } 00146 00151 void SetAt (size_t n, const char c) 00152 { 00153 CS_ASSERT (n < Size); 00154 Data [n] = c; 00155 } 00156 00158 char GetAt (size_t n) const 00159 { 00160 CS_ASSERT (n < Size); 00161 return Data [n]; 00162 } 00163 00165 csString& DeleteAt (size_t Pos, size_t Count = 1); 00166 00171 csString& Insert (size_t Pos, const csString&); 00172 00177 csString& Insert (size_t iPos, const char *); 00178 00183 csString& Insert (size_t Pos, const char); 00184 00189 csString& Overwrite (size_t iPos, const csString&); 00190 00196 csString& Append (const char*, size_t Count = (size_t)-1); 00197 00203 csString& Append (const csString &iStr, size_t Count = (size_t)-1); 00204 00206 csString& Append (char c) 00207 { char s[2]; s[0] = c; s[1] = '\0'; return Append(s); } 00208 00213 csString& Append (unsigned char c) 00214 { return Append(char(c)); } 00215 00220 csString Slice (size_t start, size_t len) const; 00221 00230 void SubString (csString& sub, size_t start, size_t len) const; 00231 00236 size_t FindFirst (char c, size_t p = 0) const; 00237 00243 size_t FindLast (char c, size_t p = (size_t)-1) const; 00244 00245 #define STR_APPEND(TYPE,FMT,SZ) csString& Append(TYPE n) \ 00246 { char s[SZ]; cs_snprintf(s, SZ, #FMT, n); return Append(s); } 00247 STR_APPEND(short, %hd, 32) 00248 STR_APPEND(unsigned short, %hu, 32) 00249 STR_APPEND(int, %d, 32) 00250 STR_APPEND(unsigned int, %u, 32) 00251 STR_APPEND(long, %ld, 32) 00252 STR_APPEND(unsigned long, %lu, 32) 00253 STR_APPEND(float, %g, 64) 00254 STR_APPEND(double, %g, 64) 00255 #undef STR_APPEND 00256 00257 #if !defined(CS_USE_FAKE_BOOL_TYPE) 00258 00259 csString& Append (bool b) { return Append (b ? "1" : "0"); } 00260 #endif 00261 00267 csString& Replace (const csString& Str, size_t Count = (size_t)-1) 00268 { 00269 Size = 0; 00270 return Append (Str, Count); 00271 } 00272 00278 csString& Replace (const char* Str, size_t Count = (size_t)-1) 00279 { 00280 Size = 0; 00281 return Append (Str, Count); 00282 } 00283 00284 #define STR_REPLACE(TYPE) \ 00285 csString& Replace (TYPE s) { Size = 0; return Append(s); } 00286 STR_REPLACE(char) 00287 STR_REPLACE(unsigned char) 00288 STR_REPLACE(short) 00289 STR_REPLACE(unsigned short) 00290 STR_REPLACE(int) 00291 STR_REPLACE(unsigned int) 00292 STR_REPLACE(long) 00293 STR_REPLACE(unsigned long) 00294 STR_REPLACE(float) 00295 STR_REPLACE(double) 00296 #ifndef CS_USE_FAKE_BOOL_TYPE 00297 STR_REPLACE(bool) 00298 #endif 00299 #undef STR_REPLACE 00300 00302 bool Compare (const csString& iStr) const 00303 { 00304 if (&iStr == this) 00305 return true; 00306 size_t const n = iStr.Length(); 00307 if (Size != n) 00308 return false; 00309 if (Size == 0 && n == 0) 00310 return true; 00311 return (memcmp (Data, iStr.GetData (), Size) == 0); 00312 } 00313 00315 bool Compare (const char* iStr) const 00316 { return (strcmp (Data ? Data : "", iStr) == 0); } 00317 00319 bool CompareNoCase (const csString& iStr) const 00320 { 00321 if (&iStr == this) 00322 return true; 00323 size_t const n = iStr.Length(); 00324 if (Size != n) 00325 return false; 00326 if (Size == 0 && n == 0) 00327 return true; 00328 return (strncasecmp (Data, iStr.GetData (), Size) == 0); 00329 } 00330 00332 bool CompareNoCase (const char* iStr) const 00333 { return (strncasecmp (Data ? Data : "", iStr, Size) == 0); } 00334 00336 csString () : Data (0), Size (0), MaxSize (0), GrowBy (DEFAULT_GROW_BY), 00337 GrowExponentially (false) {} 00338 00343 csString (size_t Length) : Data (0), Size (0), MaxSize (0), 00344 GrowBy (DEFAULT_GROW_BY), GrowExponentially(false) 00345 { SetCapacity (Length); } 00346 00348 csString (const csString& copy) : Data (0), Size (0), MaxSize (0), 00349 GrowBy (DEFAULT_GROW_BY), GrowExponentially(false) 00350 { Append (copy); } 00351 00353 csString (const char* src) : Data (0), Size (0), MaxSize (0), 00354 GrowBy (DEFAULT_GROW_BY), GrowExponentially(false) 00355 { Append (src); } 00356 00358 csString (char c) : Data (0), Size (0), MaxSize (0), 00359 GrowBy (DEFAULT_GROW_BY), GrowExponentially(false) 00360 { Append (c); } 00361 00363 csString (unsigned char c) : Data(0), Size (0), MaxSize (0), 00364 GrowBy (DEFAULT_GROW_BY), GrowExponentially(false) 00365 { Append ((char) c); } 00366 00368 virtual ~csString (); 00369 00371 csString Clone () const 00372 { return csString (*this); } 00373 00375 csString& LTrim(); 00376 00378 csString& RTrim(); 00379 00381 csString& Trim(); 00382 00387 csString& Collapse(); 00388 00394 csString& Format(const char* format, ...) CS_GNUC_PRINTF (2, 3); 00395 00401 csString& FormatV(const char* format, va_list args); 00402 00403 #define STR_FORMAT(TYPE,FMT,SZ) \ 00404 static csString Format (TYPE v); 00405 STR_FORMAT(short, %hd, 32) 00406 STR_FORMAT(unsigned short, %hu, 32) 00407 STR_FORMAT(int, %d, 32) 00408 STR_FORMAT(unsigned int, %u, 32) 00409 STR_FORMAT(long, %ld, 32) 00410 STR_FORMAT(unsigned long, %lu, 32) 00411 STR_FORMAT(float, %g, 64) 00412 STR_FORMAT(double, %g, 64) 00413 #undef STR_FORMAT 00414 00415 #define STR_FORMAT_INT(TYPE,FMT) \ 00416 static csString Format (TYPE v, int width, int prec=0); 00417 STR_FORMAT_INT(short, hd) 00418 STR_FORMAT_INT(unsigned short, hu) 00419 STR_FORMAT_INT(int, d) 00420 STR_FORMAT_INT(unsigned int, u) 00421 STR_FORMAT_INT(long, ld) 00422 STR_FORMAT_INT(unsigned long, lu) 00423 #undef STR_FORMAT_INT 00424 00425 #define STR_FORMAT_FLOAT(TYPE) \ 00426 static csString Format (TYPE v, int width, int prec=6); 00427 STR_FORMAT_FLOAT(float) 00428 STR_FORMAT_FLOAT(double) 00429 #undef STR_FORMAT_FLOAT 00430 00435 csString& PadLeft (size_t iNewSize, char iChar=' '); 00436 00438 csString AsPadLeft (size_t iNewSize, char iChar=' ') const; 00439 00440 // Return a new left-padded string representation of a basic type. 00441 #define STR_PADLEFT(TYPE) \ 00442 static csString PadLeft (TYPE v, size_t iNewSize, char iChar=' '); 00443 STR_PADLEFT(const csString&) 00444 STR_PADLEFT(const char*) 00445 STR_PADLEFT(char) 00446 STR_PADLEFT(unsigned char) 00447 STR_PADLEFT(short) 00448 STR_PADLEFT(unsigned short) 00449 STR_PADLEFT(int) 00450 STR_PADLEFT(unsigned int) 00451 STR_PADLEFT(long) 00452 STR_PADLEFT(unsigned long) 00453 STR_PADLEFT(float) 00454 STR_PADLEFT(double) 00455 #if !defined(CS_USE_FAKE_BOOL_TYPE) 00456 STR_PADLEFT(bool) 00457 #endif 00458 #undef STR_PADLEFT 00459 00464 csString& PadRight (size_t iNewSize, char iChar=' '); 00465 00467 csString AsPadRight (size_t iNewSize, char iChar=' ') const; 00468 00469 // Return a new right-padded string representation of a basic type. 00470 #define STR_PADRIGHT(TYPE) \ 00471 static csString PadRight (TYPE v, size_t iNewSize, char iChar=' '); 00472 STR_PADRIGHT(const csString&) 00473 STR_PADRIGHT(const char*) 00474 STR_PADRIGHT(char) 00475 STR_PADRIGHT(unsigned char) 00476 STR_PADRIGHT(short) 00477 STR_PADRIGHT(unsigned short) 00478 STR_PADRIGHT(int) 00479 STR_PADRIGHT(unsigned int) 00480 STR_PADRIGHT(long) 00481 STR_PADRIGHT(unsigned long) 00482 STR_PADRIGHT(float) 00483 STR_PADRIGHT(double) 00484 #if !defined(CS_USE_FAKE_BOOL_TYPE) 00485 STR_PADRIGHT(bool) 00486 #endif 00487 #undef STR_PADRIGHT 00488 00493 csString& PadCenter (size_t iNewSize, char iChar=' '); 00494 00496 csString AsPadCenter (size_t iNewSize, char iChar=' ') const; 00497 00498 // Return a new left+right padded string representation of a basic type. 00499 #define STR_PADCENTER(TYPE) \ 00500 static csString PadCenter (TYPE v, size_t iNewSize, char iChar=' '); 00501 STR_PADCENTER(const csString&) 00502 STR_PADCENTER(const char*) 00503 STR_PADCENTER(char) 00504 STR_PADCENTER(unsigned char) 00505 STR_PADCENTER(short) 00506 STR_PADCENTER(unsigned short) 00507 STR_PADCENTER(int) 00508 STR_PADCENTER(unsigned int) 00509 STR_PADCENTER(long) 00510 STR_PADCENTER(unsigned long) 00511 STR_PADCENTER(float) 00512 STR_PADCENTER(double) 00513 #if !defined(CS_USE_FAKE_BOOL_TYPE) 00514 STR_PADCENTER(bool) 00515 #endif 00516 #undef STR_PADCENTER 00517 00518 // Assign a string to another. 00519 #define STR_ASSIGN(TYPE) \ 00520 const csString& operator = (TYPE s) { return Replace (s); } 00521 STR_ASSIGN(const csString&) 00522 STR_ASSIGN(const char*) 00523 STR_ASSIGN(char) 00524 STR_ASSIGN(unsigned char) 00525 STR_ASSIGN(short) 00526 STR_ASSIGN(unsigned short) 00527 STR_ASSIGN(int) 00528 STR_ASSIGN(unsigned int) 00529 STR_ASSIGN(long) 00530 STR_ASSIGN(unsigned long) 00531 STR_ASSIGN(float) 00532 STR_ASSIGN(double) 00533 #ifndef CS_USE_FAKE_BOOL_TYPE 00534 STR_ASSIGN(bool) 00535 #endif 00536 #undef STR_ASSIGN 00537 00538 #define STR_APPEND(TYPE) csString &operator += (TYPE s) { return Append (s); } 00539 STR_APPEND(const csString&) 00540 STR_APPEND(const char*) 00541 STR_APPEND(char) 00542 STR_APPEND(unsigned char) 00543 STR_APPEND(short) 00544 STR_APPEND(unsigned short) 00545 STR_APPEND(int) 00546 STR_APPEND(unsigned int) 00547 STR_APPEND(long); 00548 STR_APPEND(unsigned long) 00549 STR_APPEND(float) 00550 STR_APPEND(double) 00551 #ifndef CS_USE_FAKE_BOOL_TYPE 00552 STR_APPEND(bool) 00553 #endif 00554 #undef STR_APPEND 00555 00557 const csString& operator + (const csString &iStr) const 00558 { return Clone ().Append (iStr); } 00559 00561 operator const char* () const 00562 { return Data; } 00563 00565 bool operator == (const csString& iStr) const 00566 { return Compare (iStr); } 00568 bool operator == (const char* iStr) const 00569 { return Compare (iStr); } 00571 bool operator != (const csString& iStr) const 00572 { return !Compare (iStr); } 00574 bool operator != (const char* iStr) const 00575 { return !Compare (iStr); } 00576 00578 csString& Downcase(); 00580 csString& Upcase(); 00581 00589 char* Detach () 00590 { char* d = Data; Data = 0; Size = 0; MaxSize = 0; return d; } 00591 }; 00592 00594 inline csString operator + (const char* iStr1, const csString &iStr2) 00595 { 00596 return csString (iStr1).Append (iStr2); 00597 } 00598 00600 inline csString operator + (const csString& iStr1, const char* iStr2) 00601 { 00602 return iStr1.Clone ().Append (iStr2); 00603 } 00604 00605 // Handy shift operators. For example: s << "Hi " << name << "; see " << foo; 00606 #define STR_SHIFT(TYPE) \ 00607 inline csString &operator << (csString &s, TYPE v) { return s.Append (v); } 00608 STR_SHIFT(const csString&) 00609 STR_SHIFT(const char*) 00610 STR_SHIFT(char) 00611 STR_SHIFT(unsigned char) 00612 STR_SHIFT(short) 00613 STR_SHIFT(unsigned short) 00614 STR_SHIFT(int) 00615 STR_SHIFT(unsigned int) 00616 STR_SHIFT(long); 00617 STR_SHIFT(unsigned long) 00618 STR_SHIFT(float) 00619 STR_SHIFT(double) 00620 #if !defined(CS_USE_FAKE_BOOL_TYPE) 00621 STR_SHIFT(bool) 00622 #endif 00623 #undef STR_SHIFT 00624 00625 #endif // __CS_CSSTRING_H__
Generated for Crystal Space by doxygen 1.2.18