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