1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2003, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: String.h 23 // Author(s): Stefano Ceccherini (burton666@libero.it) 24 // Description: String class supporting common string operations. 25 //------------------------------------------------------------------------------ 26 27 28 29 #ifndef __BSTRING__ 30 #define __BSTRING__ 31 32 #include <BeBuild.h> 33 #include <SupportDefs.h> 34 #include <string.h> 35 36 class BString { 37 public: 38 BString(); 39 BString(const char *); 40 BString(const BString &); 41 BString(const char *, int32 maxLength); 42 43 ~BString(); 44 45 /*---- Access --------------------------------------------------------------*/ 46 const char *String() const; 47 /* returns null-terminated string */ 48 49 int32 Length() const; 50 /* length of corresponding string */ 51 52 int32 CountChars() const; 53 /* returns number of UTF8 characters in string */ 54 /*---- Assignment ----------------------------------------------------------*/ 55 BString &operator=(const BString &); 56 BString &operator=(const char *); 57 BString &operator=(char); 58 59 BString &SetTo(const char *); 60 BString &SetTo(const char *, int32 length); 61 62 BString &SetTo(const BString &from); 63 BString &Adopt(BString &from); 64 /* leaves <from> empty, avoiding a copy */ 65 66 BString &SetTo(const BString &, int32 length); 67 BString &Adopt(BString &from, int32 length); 68 /* leaves <from> empty, avoiding a copy */ 69 70 BString &SetTo(char, int32 count); 71 72 /*---- Substring copying ---------------------------------------------------*/ 73 BString &CopyInto(BString &into, int32 fromOffset, 74 int32 length) const; 75 /* returns <into> ref as it's result; doesn't do 76 * anything if <into> is <this> 77 */ 78 79 void CopyInto(char *into, int32 fromOffset, 80 int32 length) const; 81 /* caller guarantees that <into> is large enough */ 82 83 /*---- Appending -----------------------------------------------------------*/ 84 BString &operator+=(const BString &); 85 BString &operator+=(const char *); 86 BString &operator+=(char); 87 88 BString &Append(const BString &); 89 BString &Append(const char *); 90 91 BString &Append(const BString &, int32 length); 92 BString &Append(const char *, int32 length); 93 BString &Append(char, int32 count); 94 95 /*---- Prepending ----------------------------------------------------------*/ 96 BString &Prepend(const char *); 97 BString &Prepend(const BString &); 98 BString &Prepend(const char *, int32); 99 BString &Prepend(const BString &, int32); 100 BString &Prepend(char, int32 count); 101 102 /*---- Inserting ----------------------------------------------------------*/ 103 BString &Insert(const char *, int32 pos); 104 BString &Insert(const char *, int32 length, int32 pos); 105 BString &Insert(const char *, int32 fromOffset, 106 int32 length, int32 pos); 107 108 BString &Insert(const BString &, int32 pos); 109 BString &Insert(const BString &, int32 length, int32 pos); 110 BString &Insert(const BString &, int32 fromOffset, 111 int32 length, int32 pos); 112 BString &Insert(char, int32 count, int32 pos); 113 114 /*---- Removing -----------------------------------------------------------*/ 115 BString &Truncate(int32 newLength, bool lazy = true); 116 /* pass false in <lazy> to ensure freeing up the 117 * truncated memory 118 */ 119 120 BString &Remove(int32 from, int32 length); 121 122 BString &RemoveFirst(const BString &); 123 BString &RemoveLast(const BString &); 124 BString &RemoveAll(const BString &); 125 126 BString &RemoveFirst(const char *); 127 BString &RemoveLast(const char *); 128 BString &RemoveAll(const char *); 129 130 BString &RemoveSet(const char *setOfCharsToRemove); 131 132 BString &MoveInto(BString &into, int32 from, int32 length); 133 void MoveInto(char *into, int32 from, int32 length); 134 /* caller guarantees that <into> is large enough */ 135 136 137 /*---- Compare functions ---------------------------------------------------*/ 138 bool operator<(const BString &) const; 139 bool operator<=(const BString &) const; 140 bool operator==(const BString &) const; 141 bool operator>=(const BString &) const; 142 bool operator>(const BString &) const; 143 bool operator!=(const BString &) const; 144 145 bool operator<(const char *) const; 146 bool operator<=(const char *) const; 147 bool operator==(const char *) const; 148 bool operator>=(const char *) const; 149 bool operator>(const char *) const; 150 bool operator!=(const char *) const; 151 152 /*---- strcmp-style compare functions --------------------------------------*/ 153 int Compare(const BString &) const; 154 int Compare(const char *) const; 155 int Compare(const BString &, int32 n) const; 156 int Compare(const char *, int32 n) const; 157 int ICompare(const BString &) const; 158 int ICompare(const char *) const; 159 int ICompare(const BString &, int32 n) const; 160 int ICompare(const char *, int32 n) const; 161 162 /*---- Searching -----------------------------------------------------------*/ 163 int32 FindFirst(const BString &) const; 164 int32 FindFirst(const char *) const; 165 int32 FindFirst(const BString &, int32 fromOffset) const; 166 int32 FindFirst(const char *, int32 fromOffset) const; 167 int32 FindFirst(char) const; 168 int32 FindFirst(char, int32 fromOffset) const; 169 170 int32 FindLast(const BString &) const; 171 int32 FindLast(const char *) const; 172 int32 FindLast(const BString &, int32 beforeOffset) const; 173 int32 FindLast(const char *, int32 beforeOffset) const; 174 int32 FindLast(char) const; 175 int32 FindLast(char, int32 beforeOffset) const; 176 177 int32 IFindFirst(const BString &) const; 178 int32 IFindFirst(const char *) const; 179 int32 IFindFirst(const BString &, int32 fromOffset) const; 180 int32 IFindFirst(const char *, int32 fromOffset) const; 181 182 int32 IFindLast(const BString &) const; 183 int32 IFindLast(const char *) const; 184 int32 IFindLast(const BString &, int32 beforeOffset) const; 185 int32 IFindLast(const char *, int32 beforeOffset) const; 186 187 /*---- Replacing -----------------------------------------------------------*/ 188 189 BString &ReplaceFirst(char replaceThis, char withThis); 190 BString &ReplaceLast(char replaceThis, char withThis); 191 BString &ReplaceAll(char replaceThis, char withThis, 192 int32 fromOffset = 0); 193 BString &Replace(char replaceThis, char withThis, 194 int32 maxReplaceCount, int32 fromOffset = 0); 195 BString &ReplaceFirst(const char *replaceThis, 196 const char *withThis); 197 BString &ReplaceLast(const char *replaceThis, 198 const char *withThis); 199 BString &ReplaceAll(const char *replaceThis, 200 const char *withThis, int32 fromOffset = 0); 201 BString &Replace(const char *replaceThis, const char *withThis, 202 int32 maxReplaceCount, int32 fromOffset = 0); 203 204 BString &IReplaceFirst(char replaceThis, char withThis); 205 BString &IReplaceLast(char replaceThis, char withThis); 206 BString &IReplaceAll(char replaceThis, char withThis, 207 int32 fromOffset = 0); 208 BString &IReplace(char replaceThis, char withThis, 209 int32 maxReplaceCount, int32 fromOffset = 0); 210 BString &IReplaceFirst(const char *replaceThis, 211 const char *withThis); 212 BString &IReplaceLast(const char *replaceThis, 213 const char *withThis); 214 BString &IReplaceAll(const char *replaceThis, 215 const char *withThis, int32 fromOffset = 0); 216 BString &IReplace(const char *replaceThis, const char *withThis, 217 int32 maxReplaceCount, int32 fromOffset = 0); 218 219 BString &ReplaceSet(const char *setOfChars, char with); 220 BString &ReplaceSet(const char *setOfChars, const char *with); 221 /*---- Unchecked char access -----------------------------------------------*/ 222 char operator[](int32 index) const; 223 char &operator[](int32 index); 224 225 /*---- Checked char access -------------------------------------------------*/ 226 char ByteAt(int32 index) const; 227 228 /*---- Fast low-level manipulation -----------------------------------------*/ 229 char *LockBuffer(int32 maxLength); 230 231 /* Make room for characters to be added by C-string like manipulation. 232 * Returns the equivalent of String(), <maxLength> includes space for 233 * trailing zero while used as C-string, it is illegal to call other 234 * BString routines that rely on data/length consistency until 235 * UnlockBuffer sets things up again. 236 */ 237 238 BString &UnlockBuffer(int32 length = -1); 239 240 /* Finish using BString as C-string, adjusting length. If no length 241 * passed in, strlen of internal data is used to determine it. 242 * BString is in consistent state after this. 243 */ 244 245 /*---- Upercase<->Lowercase ------------------------------------------------*/ 246 BString &ToLower(); 247 BString &ToUpper(); 248 249 BString &Capitalize(); 250 /* Converts first character to upper-case, rest to 251 * lower-case 252 */ 253 254 BString &CapitalizeEachWord(); 255 /* Converts first character in each 256 * non-alphabethycal-character-separated 257 * word to upper-case, rest to lower-case 258 */ 259 /*----- Escaping and Deescaping --------------------------------------------*/ 260 BString &CharacterEscape(const char *original, 261 const char *setOfCharsToEscape, char escapeWith); 262 /* copies original into <this>, escaping characters 263 * specified in <setOfCharsToEscape> by prepending 264 * them with <escapeWith> 265 */ 266 BString &CharacterEscape(const char *setOfCharsToEscape, 267 char escapeWith); 268 /* escapes characters specified in <setOfCharsToEscape> 269 * by prepending them with <escapeWith> 270 */ 271 272 BString &CharacterDeescape(const char *original, char escapeChar); 273 /* copy <original> into the string removing the escaping 274 * characters <escapeChar> 275 */ 276 BString &CharacterDeescape(char escapeChar); 277 /* remove the escaping characters <escapeChar> from 278 * the string 279 */ 280 281 /*---- Simple sprintf replacement calls ------------------------------------*/ 282 /*---- Slower than sprintf but type and overflow safe ----------------------*/ 283 BString &operator<<(const char *); 284 BString &operator<<(const BString &); 285 BString &operator<<(char); 286 BString &operator<<(int); 287 BString &operator<<(unsigned int); 288 BString &operator<<(unsigned long); 289 BString &operator<<(long); 290 BString &operator<<(unsigned long long); 291 BString &operator<<(long long); 292 BString &operator<<(float); 293 /* float output hardcodes %.2f style formatting */ 294 295 /*----- Private or reserved ------------------------------------------------*/ 296 private: 297 void _Init(const char *, int32); 298 void _DoAssign(const char *, int32); 299 void _DoAppend(const char *, int32); 300 char *_GrowBy(int32); 301 char *_OpenAtBy(int32, int32); 302 char *_ShrinkAtBy(int32, int32); 303 void _DoPrepend(const char *, int32); 304 305 int32 _FindAfter(const char *, int32, int32) const; 306 int32 _IFindAfter(const char *, int32, int32) const; 307 int32 _ShortFindAfter(const char *, int32) const; 308 int32 _FindBefore(const char *, int32, int32) const; 309 int32 _IFindBefore(const char *, int32, int32) const; 310 BString &_DoReplace(const char *, const char *, int32, int32, 311 bool); 312 void _SetLength(int32); 313 314 #if DEBUG 315 void _SetUsingAsCString(bool); 316 void _AssertNotUsingAsCString() const; 317 #else 318 void _SetUsingAsCString(bool) {} 319 void _AssertNotUsingAsCString() const {} 320 #endif 321 322 char *_Alloc( int32); 323 324 struct PosVect; 325 void _ReplaceAtPositions( const PosVect* positions, 326 int32 searchLen, 327 const char* with, 328 int32 withLen); 329 330 protected: 331 char *_privateData; 332 }; 333 334 /*----- Comutative compare operators --------------------------------------*/ 335 bool operator<(const char *, const BString &); 336 bool operator<=(const char *, const BString &); 337 bool operator==(const char *, const BString &); 338 bool operator>(const char *, const BString &); 339 bool operator>=(const char *, const BString &); 340 bool operator!=(const char *, const BString &); 341 342 /*----- Non-member compare for sorting, etc. ------------------------------*/ 343 int Compare(const BString &, const BString &); 344 int ICompare(const BString &, const BString &); 345 int Compare(const BString *, const BString *); 346 int ICompare(const BString *, const BString *); 347 348 349 350 351 /*-------------------------------------------------------------------------*/ 352 /*---- No user serviceable parts after this -------------------------------*/ 353 354 inline int32 355 BString::Length() const 356 { 357 return _privateData ? (*((int32 *)_privateData - 1) & 0x7fffffff) : 0; 358 /* the most significant bit is reserved; accessing 359 * it in any way will cause the computer to explode 360 */ 361 } 362 363 inline const char * 364 BString::String() const 365 { 366 if (!_privateData) 367 return ""; 368 return _privateData; 369 } 370 371 inline BString & 372 BString::SetTo(const char *str) 373 { 374 return operator=(str); 375 } 376 377 inline char 378 BString::operator[](int32 index) const 379 { 380 return _privateData[index]; 381 } 382 383 inline char 384 BString::ByteAt(int32 index) const 385 { 386 if (!_privateData || index < 0 || index > Length()) 387 return 0; 388 return _privateData[index]; 389 } 390 391 inline BString & 392 BString::operator+=(const BString &string) 393 { 394 _DoAppend(string.String(), string.Length()); 395 return *this; 396 } 397 398 inline BString & 399 BString::Append(const BString &string) 400 { 401 _DoAppend(string.String(), string.Length()); 402 return *this; 403 } 404 405 inline BString & 406 BString::Append(const char *str) 407 { 408 return operator+=(str); 409 } 410 411 inline bool 412 BString::operator==(const BString &string) const 413 { 414 return strcmp(String(), string.String()) == 0; 415 } 416 417 inline bool 418 BString::operator<(const BString &string) const 419 { 420 return strcmp(String(), string.String()) < 0; 421 } 422 423 inline bool 424 BString::operator<=(const BString &string) const 425 { 426 return strcmp(String(), string.String()) <= 0; 427 } 428 429 inline bool 430 BString::operator>=(const BString &string) const 431 { 432 return strcmp(String(), string.String()) >= 0; 433 } 434 435 inline bool 436 BString::operator>(const BString &string) const 437 { 438 return strcmp(String(), string.String()) > 0; 439 } 440 441 inline bool 442 BString::operator!=(const BString &string) const 443 { 444 return strcmp(String(), string.String()) != 0; 445 } 446 447 inline bool 448 BString::operator!=(const char *str) const 449 { 450 return !operator==(str); 451 } 452 453 inline bool 454 operator<(const char *str, const BString &string) 455 { 456 return string > str; 457 } 458 459 inline bool 460 operator<=(const char *str, const BString &string) 461 { 462 return string >= str; 463 } 464 465 inline bool 466 operator==(const char *str, const BString &string) 467 { 468 return string == str; 469 } 470 471 inline bool 472 operator>(const char *str, const BString &string) 473 { 474 return string < str; 475 } 476 477 inline bool 478 operator>=(const char *str, const BString &string) 479 { 480 return string <= str; 481 } 482 483 inline bool 484 operator!=(const char *str, const BString &string) 485 { 486 return string != str; 487 } 488 489 #endif /* __BSTRING__ */ 490