1 /* 2 * Copyright 2001-2010 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _B_STRING_H 6 #define _B_STRING_H 7 8 9 #include <stdarg.h> 10 #include <string.h> 11 12 #include <SupportDefs.h> 13 14 15 class BStringList; 16 class BStringRef; 17 18 19 class BString { 20 public: 21 BString(); 22 BString(const char* string); 23 BString(const BString& string); 24 BString(const char* string, int32 maxLength); 25 ~BString(); 26 27 // Access 28 const char* String() const; 29 int32 Length() const; 30 int32 CountChars() const; 31 int32 CountBytes(int32 fromCharOffset, 32 int32 charCount) const; 33 bool IsEmpty() const; 34 35 uint32 HashValue() const; 36 static uint32 HashValue(const char* string); 37 38 // Assignment 39 BString& operator=(const BString& string); 40 BString& operator=(const char* string); 41 BString& operator=(char c); 42 43 BString& SetTo(const char* string); 44 BString& SetTo(const char* string, int32 maxLength); 45 46 BString& SetTo(const BString& string); 47 BString& Adopt(BString& from); 48 49 BString& SetTo(const BString& string, int32 maxLength); 50 BString& Adopt(BString& from, int32 maxLength); 51 52 BString& SetTo(char c, int32 count); 53 54 BString& SetToChars(const char* string, int32 charCount); 55 BString& SetToChars(const BString& string, int32 charCount); 56 BString& AdoptChars(BString& from, int32 charCount); 57 58 BString& SetToFormat(const char* format, ...) 59 __attribute__((__format__(__printf__, 2, 3))); 60 BString& SetToFormatVarArgs(const char* format, 61 va_list args) 62 __attribute__((__format__(__printf__, 2, 0))); 63 64 int ScanWithFormat(const char* format, ...) 65 __attribute__((__format__(__scanf__, 2, 3))); 66 int ScanWithFormatVarArgs(const char* format, 67 va_list args) 68 __attribute__((__format__(__scanf__, 2, 0))); 69 70 // Substring copying 71 BString& CopyInto(BString& into, int32 fromOffset, 72 int32 length) const; 73 void CopyInto(char* into, int32 fromOffset, 74 int32 length) const; 75 76 BString& CopyCharsInto(BString& into, int32 fromCharOffset, 77 int32 charCount) const; 78 bool CopyCharsInto(char* into, int32* intoLength, 79 int32 fromCharOffset, int32 charCount) const; 80 81 bool Split(const char* separator, bool noEmptyStrings, 82 BStringList& _list) const; 83 84 // Appending 85 BString& operator+=(const BString& string); 86 BString& operator+=(const char* string); 87 BString& operator+=(char c); 88 89 BString& Append(const BString& string); 90 BString& Append(const char* string); 91 92 BString& Append(const BString& string, int32 length); 93 BString& Append(const char* string, int32 length); 94 BString& Append(char c, int32 count); 95 96 BString& AppendChars(const BString& string, int32 charCount); 97 BString& AppendChars(const char* string, int32 charCount); 98 99 // Prepending 100 BString& Prepend(const char* string); 101 BString& Prepend(const BString& string); 102 BString& Prepend(const char* string, int32 length); 103 BString& Prepend(const BString& string, int32 length); 104 BString& Prepend(char c, int32 count); 105 106 BString& PrependChars(const char* string, int32 charCount); 107 BString& PrependChars(const BString& string, 108 int32 charCount); 109 110 // Inserting 111 BString& Insert(const char* string, int32 position); 112 BString& Insert(const char* string, int32 length, 113 int32 position); 114 BString& Insert(const char* string, int32 fromOffset, 115 int32 length, int32 position); 116 BString& Insert(const BString& string, int32 position); 117 BString& Insert(const BString& string, int32 length, 118 int32 position); 119 BString& Insert(const BString& string, int32 fromOffset, 120 int32 length, int32 position); 121 BString& Insert(char c, int32 count, int32 position); 122 123 BString& InsertChars(const char* string, int32 charPosition); 124 BString& InsertChars(const char* string, int32 charCount, 125 int32 charPosition); 126 BString& InsertChars(const char* string, 127 int32 fromCharOffset, int32 charCount, 128 int32 charPosition); 129 BString& InsertChars(const BString& string, 130 int32 charPosition); 131 BString& InsertChars(const BString& string, int32 charCount, 132 int32 charPosition); 133 BString& InsertChars(const BString& string, 134 int32 fromCharOffset, int32 charCount, 135 int32 charPosition); 136 137 // Removing 138 BString& Truncate(int32 newLength, bool lazy = true); 139 BString& TruncateChars(int32 newCharCount, bool lazy = true); 140 141 BString& Remove(int32 from, int32 length); 142 BString& RemoveChars(int32 fromCharOffset, int32 charCount); 143 144 BString& RemoveFirst(const BString& string); 145 BString& RemoveLast(const BString& string); 146 BString& RemoveAll(const BString& string); 147 148 BString& RemoveFirst(const char* string); 149 BString& RemoveLast(const char* string); 150 BString& RemoveAll(const char* string); 151 152 BString& RemoveSet(const char* setOfBytesToRemove); 153 BString& RemoveCharsSet(const char* setOfCharsToRemove); 154 155 BString& MoveInto(BString& into, int32 from, int32 length); 156 void MoveInto(char* into, int32 from, int32 length); 157 158 BString& MoveCharsInto(BString& into, int32 fromCharOffset, 159 int32 charCount); 160 bool MoveCharsInto(char* into, int32* intoLength, 161 int32 fromCharOffset, int32 charCount); 162 163 // Compare functions 164 bool operator<(const BString& string) const; 165 bool operator<=(const BString& string) const; 166 bool operator==(const BString& string) const; 167 bool operator>=(const BString& string) const; 168 bool operator>(const BString& string) const; 169 bool operator!=(const BString& string) const; 170 171 bool operator<(const char* string) const; 172 bool operator<=(const char* string) const; 173 bool operator==(const char* string) const; 174 bool operator>=(const char* string) const; 175 bool operator>(const char* string) const; 176 bool operator!=(const char* string) const; 177 178 operator const char*() const; 179 180 // strcmp()-style compare functions 181 int Compare(const BString& string) const; 182 int Compare(const char* string) const; 183 int Compare(const BString& string, int32 length) const; 184 int Compare(const char* string, int32 length) const; 185 186 int CompareChars(const BString& string, 187 int32 charCount) const; 188 int CompareChars(const char* string, 189 int32 charCount) const; 190 191 int ICompare(const BString& string) const; 192 int ICompare(const char* string) const; 193 int ICompare(const BString& string, int32 length) const; 194 int ICompare(const char* string, int32 length) const; 195 196 // Searching 197 int32 FindFirst(const BString& string) const; 198 int32 FindFirst(const char* string) const; 199 int32 FindFirst(const BString& string, 200 int32 fromOffset) const; 201 int32 FindFirst(const char* string, 202 int32 fromOffset) const; 203 int32 FindFirst(char c) const; 204 int32 FindFirst(char c, int32 fromOffset) const; 205 206 int32 FindFirstChars(const BString& string, 207 int32 fromCharOffset) const; 208 int32 FindFirstChars(const char* string, 209 int32 fromCharOffset) const; 210 211 int32 FindLast(const BString& string) const; 212 int32 FindLast(const char* string) const; 213 int32 FindLast(const BString& string, 214 int32 beforeOffset) const; 215 int32 FindLast(const char* string, 216 int32 beforeOffset) const; 217 int32 FindLast(char c) const; 218 int32 FindLast(char c, int32 beforeOffset) const; 219 220 int32 FindLastChars(const BString& string, 221 int32 beforeCharOffset) const; 222 int32 FindLastChars(const char* string, 223 int32 beforeCharOffset) const; 224 225 int32 IFindFirst(const BString& string) const; 226 int32 IFindFirst(const char* string) const; 227 int32 IFindFirst(const BString& string, 228 int32 fromOffset) const; 229 int32 IFindFirst(const char* string, 230 int32 fromOffset) const; 231 232 int32 IFindLast(const BString& string) const; 233 int32 IFindLast(const char* string) const; 234 int32 IFindLast(const BString& string, 235 int32 beforeOffset) const; 236 int32 IFindLast(const char* string, 237 int32 beforeOffset) const; 238 239 bool StartsWith(const BString& string) const; 240 bool StartsWith(const char* string) const; 241 bool StartsWith(const char* string, int32 length) const; 242 243 bool EndsWith(const BString& string) const; 244 bool EndsWith(const char* string) const; 245 bool EndsWith(const char* string, int32 length) const; 246 247 // Replacing 248 BString& ReplaceFirst(char replaceThis, char withThis); 249 BString& ReplaceLast(char replaceThis, char withThis); 250 BString& ReplaceAll(char replaceThis, char withThis, 251 int32 fromOffset = 0); 252 BString& Replace(char replaceThis, char withThis, 253 int32 maxReplaceCount, int32 fromOffset = 0); 254 BString& ReplaceFirst(const char* replaceThis, 255 const char* withThis); 256 BString& ReplaceLast(const char* replaceThis, 257 const char* withThis); 258 BString& ReplaceAll(const char* replaceThis, 259 const char* withThis, int32 fromOffset = 0); 260 BString& Replace(const char* replaceThis, 261 const char* withThis, int32 maxReplaceCount, 262 int32 fromOffset = 0); 263 264 BString& ReplaceAllChars(const char* replaceThis, 265 const char* withThis, int32 fromCharOffset); 266 BString& ReplaceChars(const char* replaceThis, 267 const char* withThis, int32 maxReplaceCount, 268 int32 fromCharOffset); 269 270 BString& IReplaceFirst(char replaceThis, char withThis); 271 BString& IReplaceLast(char replaceThis, char withThis); 272 BString& IReplaceAll(char replaceThis, char withThis, 273 int32 fromOffset = 0); 274 BString& IReplace(char replaceThis, char withThis, 275 int32 maxReplaceCount, int32 fromOffset = 0); 276 BString& IReplaceFirst(const char* replaceThis, 277 const char* withThis); 278 BString& IReplaceLast(const char* replaceThis, 279 const char* withThis); 280 BString& IReplaceAll(const char* replaceThis, 281 const char* withThis, int32 fromOffset = 0); 282 BString& IReplace(const char* replaceThis, 283 const char* withThis, int32 maxReplaceCount, 284 int32 fromOffset = 0); 285 286 BString& ReplaceSet(const char* setOfBytes, char with); 287 BString& ReplaceSet(const char* setOfBytes, 288 const char* with); 289 290 BString& ReplaceCharsSet(const char* setOfChars, 291 const char* with); 292 293 // Unchecked char access 294 char operator[](int32 index) const; 295 296 #if __GNUC__ > 3 297 BStringRef operator[](int32 index); 298 #else 299 char& operator[](int32 index); 300 #endif 301 302 // Checked char access 303 char ByteAt(int32 index) const; 304 const char* CharAt(int32 charIndex, int32* bytes = NULL) const; 305 bool CharAt(int32 charIndex, char* buffer, 306 int32* bytes) const; 307 308 // Fast low-level manipulation 309 char* LockBuffer(int32 maxLength); 310 BString& UnlockBuffer(int32 length = -1); 311 312 // Upercase <-> Lowercase 313 BString& ToLower(); 314 BString& ToUpper(); 315 316 BString& Capitalize(); 317 BString& CapitalizeEachWord(); 318 319 // Escaping and De-escaping 320 BString& CharacterEscape(const char* original, 321 const char* setOfCharsToEscape, 322 char escapeWith); 323 BString& CharacterEscape(const char* setOfCharsToEscape, 324 char escapeWith); 325 BString& CharacterDeescape(const char* original, 326 char escapeChar); 327 BString& CharacterDeescape(char escapeChar); 328 329 // Trimming 330 BString& Trim(); 331 332 // Insert 333 BString& operator<<(const char* string); 334 BString& operator<<(const BString& string); 335 BString& operator<<(char c); 336 BString& operator<<(bool value); 337 BString& operator<<(int value); 338 BString& operator<<(unsigned int value); 339 BString& operator<<(unsigned long value); 340 BString& operator<<(long value); 341 BString& operator<<(unsigned long long value); 342 BString& operator<<(long long value); 343 // float/double output hardcodes %.2f style formatting 344 BString& operator<<(float value); 345 BString& operator<<(double value); 346 347 public: 348 class Private; 349 friend class Private; 350 351 private: 352 class PosVect; 353 friend class BStringRef; 354 355 enum PrivateDataTag { 356 PRIVATE_DATA 357 }; 358 359 private: 360 BString(char* privateData, PrivateDataTag tag); 361 362 // Management 363 status_t _MakeWritable(); 364 status_t _MakeWritable(int32 length, bool copy); 365 static char* _Allocate(int32 length); 366 char* _Resize(int32 length); 367 void _Init(const char* src, int32 length); 368 char* _Clone(const char* data, int32 length); 369 char* _OpenAtBy(int32 offset, int32 length); 370 char* _ShrinkAtBy(int32 offset, int32 length); 371 372 // Data 373 void _SetLength(int32 length); 374 bool _DoAppend(const char* string, int32 length); 375 bool _DoPrepend(const char* string, int32 length); 376 bool _DoInsert(const char* string, int32 offset, 377 int32 length); 378 379 // Search 380 int32 _ShortFindAfter(const char* string, 381 int32 length) const; 382 int32 _FindAfter(const char* string, int32 offset, 383 int32 length) const; 384 int32 _IFindAfter(const char* string, int32 offset, 385 int32 length) const; 386 int32 _FindBefore(const char* string, int32 offset, 387 int32 length) const; 388 int32 _IFindBefore(const char* string, int32 offset, 389 int32 length) const; 390 391 // Escape 392 BString& _DoCharacterEscape(const char* string, 393 const char* setOfCharsToEscape, char escapeChar); 394 BString& _DoCharacterDeescape(const char* string, 395 char escapeChar); 396 397 // Replace 398 BString& _DoReplace(const char* findThis, 399 const char* replaceWith, int32 maxReplaceCount, 400 int32 fromOffset, bool ignoreCase); 401 void _ReplaceAtPositions(const PosVect* positions, 402 int32 searchLength, const char* with, 403 int32 withLength); 404 405 private: 406 int32& _ReferenceCount(); 407 const int32& _ReferenceCount() const; 408 bool _IsShareable() const; 409 void _FreePrivateData(); 410 411 char* fPrivateData; 412 }; 413 414 415 // Commutative compare operators 416 bool operator<(const char* a, const BString& b); 417 bool operator<=(const char* a, const BString& b); 418 bool operator==(const char* a, const BString& b); 419 bool operator>(const char* a, const BString& b); 420 bool operator>=(const char* a, const BString& b); 421 bool operator!=(const char* a, const BString& b); 422 423 424 // Non-member compare for sorting, etc. 425 int Compare(const BString& a, const BString& b); 426 int ICompare(const BString& a, const BString& b); 427 int Compare(const BString* a, const BString* b); 428 int ICompare(const BString* a, const BString* b); 429 430 431 inline int32 432 BString::Length() const 433 { 434 // the most significant bit is reserved; accessing 435 // it in any way will cause the computer to explode 436 return fPrivateData ? (*(((int32*)fPrivateData) - 1) & 0x7fffffff) : 0; 437 } 438 439 440 inline bool 441 BString::IsEmpty() const 442 { 443 return !Length(); 444 } 445 446 447 inline const char* 448 BString::String() const 449 { 450 if (!fPrivateData) 451 return ""; 452 return fPrivateData; 453 } 454 455 456 inline uint32 457 BString::HashValue() const 458 { 459 return HashValue(String()); 460 } 461 462 463 inline BString& 464 BString::SetTo(const char* string) 465 { 466 return operator=(string); 467 } 468 469 470 inline char 471 BString::operator[](int32 index) const 472 { 473 return fPrivateData[index]; 474 } 475 476 477 inline char 478 BString::ByteAt(int32 index) const 479 { 480 if (!fPrivateData || index < 0 || index >= Length()) 481 return 0; 482 return fPrivateData[index]; 483 } 484 485 486 inline BString& 487 BString::operator+=(const BString& string) 488 { 489 _DoAppend(string.String(), string.Length()); 490 return *this; 491 } 492 493 494 inline BString& 495 BString::Append(const BString& string) 496 { 497 _DoAppend(string.String(), string.Length()); 498 return *this; 499 } 500 501 502 inline BString& 503 BString::Append(const char* string) 504 { 505 return operator+=(string); 506 } 507 508 509 inline bool 510 BString::operator==(const BString& string) const 511 { 512 return strcmp(String(), string.String()) == 0; 513 } 514 515 516 inline bool 517 BString::operator<(const BString& string) const 518 { 519 return strcmp(String(), string.String()) < 0; 520 } 521 522 523 inline bool 524 BString::operator<=(const BString& string) const 525 { 526 return strcmp(String(), string.String()) <= 0; 527 } 528 529 530 inline bool 531 BString::operator>=(const BString& string) const 532 { 533 return strcmp(String(), string.String()) >= 0; 534 } 535 536 537 inline bool 538 BString::operator>(const BString& string) const 539 { 540 return strcmp(String(), string.String()) > 0; 541 } 542 543 544 inline bool 545 BString::operator!=(const BString& string) const 546 { 547 return strcmp(String(), string.String()) != 0; 548 } 549 550 551 inline bool 552 BString::operator!=(const char* string) const 553 { 554 return !operator==(string); 555 } 556 557 558 inline 559 BString::operator const char*() const 560 { 561 return String(); 562 } 563 564 565 inline bool 566 operator<(const char* str, const BString& string) 567 { 568 return string > str; 569 } 570 571 572 inline bool 573 operator<=(const char* str, const BString& string) 574 { 575 return string >= str; 576 } 577 578 579 inline bool 580 operator==(const char* str, const BString& string) 581 { 582 return string == str; 583 } 584 585 586 inline bool 587 operator>(const char* str, const BString& string) 588 { 589 return string < str; 590 } 591 592 593 inline bool 594 operator>=(const char* str, const BString& string) 595 { 596 return string <= str; 597 } 598 599 600 inline bool 601 operator!=(const char* str, const BString& string) 602 { 603 return string != str; 604 } 605 606 607 // #pragma mark - BStringRef 608 609 610 class BStringRef { 611 public: 612 BStringRef(BString& string, int32 position); 613 ~BStringRef() {} 614 615 operator char() const; 616 617 char* operator&(); 618 const char* operator&() const; 619 620 BStringRef& operator=(char c); 621 BStringRef& operator=(const BStringRef& rc); 622 623 private: 624 BString& fString; 625 int32 fPosition; 626 }; 627 628 629 #endif // _B_STRING_H 630