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