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