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 // Replacing 225 BString& ReplaceFirst(char replaceThis, char withThis); 226 BString& ReplaceLast(char replaceThis, char withThis); 227 BString& ReplaceAll(char replaceThis, char withThis, 228 int32 fromOffset = 0); 229 BString& Replace(char replaceThis, char withThis, 230 int32 maxReplaceCount, int32 fromOffset = 0); 231 BString& ReplaceFirst(const char* replaceThis, 232 const char* withThis); 233 BString& ReplaceLast(const char* replaceThis, 234 const char* withThis); 235 BString& ReplaceAll(const char* replaceThis, 236 const char* withThis, int32 fromOffset = 0); 237 BString& Replace(const char* replaceThis, 238 const char* withThis, int32 maxReplaceCount, 239 int32 fromOffset = 0); 240 241 BString& ReplaceAllChars(const char* replaceThis, 242 const char* withThis, int32 fromCharOffset); 243 BString& ReplaceChars(const char* replaceThis, 244 const char* withThis, int32 maxReplaceCount, 245 int32 fromCharOffset); 246 247 BString& IReplaceFirst(char replaceThis, char withThis); 248 BString& IReplaceLast(char replaceThis, char withThis); 249 BString& IReplaceAll(char replaceThis, char withThis, 250 int32 fromOffset = 0); 251 BString& IReplace(char replaceThis, char withThis, 252 int32 maxReplaceCount, int32 fromOffset = 0); 253 BString& IReplaceFirst(const char* replaceThis, 254 const char* withThis); 255 BString& IReplaceLast(const char* replaceThis, 256 const char* withThis); 257 BString& IReplaceAll(const char* replaceThis, 258 const char* withThis, int32 fromOffset = 0); 259 BString& IReplace(const char* replaceThis, 260 const char* withThis, int32 maxReplaceCount, 261 int32 fromOffset = 0); 262 263 BString& ReplaceSet(const char* setOfBytes, char with); 264 BString& ReplaceSet(const char* setOfBytes, 265 const char* with); 266 267 BString& ReplaceCharsSet(const char* setOfChars, 268 const char* with); 269 270 // Unchecked char access 271 char operator[](int32 index) const; 272 273 #if __GNUC__ > 3 274 BStringRef operator[](int32 index); 275 #else 276 char& operator[](int32 index); 277 #endif 278 279 // Checked char access 280 char ByteAt(int32 index) const; 281 const char* CharAt(int32 charIndex, int32* bytes = NULL) const; 282 bool CharAt(int32 charIndex, char* buffer, 283 int32* bytes) const; 284 285 // Fast low-level manipulation 286 char* LockBuffer(int32 maxLength); 287 BString& UnlockBuffer(int32 length = -1); 288 289 // Upercase <-> Lowercase 290 BString& ToLower(); 291 BString& ToUpper(); 292 293 BString& Capitalize(); 294 BString& CapitalizeEachWord(); 295 296 // Escaping and De-escaping 297 BString& CharacterEscape(const char* original, 298 const char* setOfCharsToEscape, 299 char escapeWith); 300 BString& CharacterEscape(const char* setOfCharsToEscape, 301 char escapeWith); 302 BString& CharacterDeescape(const char* original, 303 char escapeChar); 304 BString& CharacterDeescape(char escapeChar); 305 306 // Trimming 307 BString& Trim(); 308 309 // Insert 310 BString& operator<<(const char* string); 311 BString& operator<<(const BString& string); 312 BString& operator<<(char c); 313 BString& operator<<(bool value); 314 BString& operator<<(int value); 315 BString& operator<<(unsigned int value); 316 BString& operator<<(unsigned long value); 317 BString& operator<<(long value); 318 BString& operator<<(unsigned long long value); 319 BString& operator<<(long long value); 320 // float/double output hardcodes %.2f style formatting 321 BString& operator<<(float value); 322 BString& operator<<(double value); 323 324 public: 325 class Private; 326 friend class Private; 327 328 private: 329 class PosVect; 330 friend class BStringRef; 331 332 enum PrivateDataTag { 333 PRIVATE_DATA 334 }; 335 336 private: 337 BString(char* privateData, PrivateDataTag tag); 338 339 // Management 340 status_t _MakeWritable(); 341 status_t _MakeWritable(int32 length, bool copy); 342 static char* _Allocate(int32 length); 343 char* _Resize(int32 length); 344 void _Init(const char* src, int32 length); 345 char* _Clone(const char* data, int32 length); 346 char* _OpenAtBy(int32 offset, int32 length); 347 char* _ShrinkAtBy(int32 offset, int32 length); 348 349 // Data 350 void _SetLength(int32 length); 351 bool _DoAppend(const char* string, int32 length); 352 bool _DoPrepend(const char* string, int32 length); 353 bool _DoInsert(const char* string, int32 offset, 354 int32 length); 355 356 // Search 357 int32 _ShortFindAfter(const char* string, 358 int32 length) const; 359 int32 _FindAfter(const char* string, int32 offset, 360 int32 length) const; 361 int32 _IFindAfter(const char* string, int32 offset, 362 int32 length) const; 363 int32 _FindBefore(const char* string, int32 offset, 364 int32 length) const; 365 int32 _IFindBefore(const char* string, int32 offset, 366 int32 length) const; 367 368 // Escape 369 BString& _DoCharacterEscape(const char* string, 370 const char *setOfCharsToEscape, char escapeChar); 371 BString& _DoCharacterDeescape(const char* string, 372 char escapeChar); 373 374 // Replace 375 BString& _DoReplace(const char* findThis, 376 const char* replaceWith, int32 maxReplaceCount, 377 int32 fromOffset, bool ignoreCase); 378 void _ReplaceAtPositions(const PosVect* positions, 379 int32 searchLength, const char* with, 380 int32 withLength); 381 382 private: 383 vint32& _ReferenceCount(); 384 const vint32& _ReferenceCount() const; 385 bool _IsShareable() const; 386 void _FreePrivateData(); 387 388 char* fPrivateData; 389 }; 390 391 392 // Commutative compare operators 393 bool operator<(const char* a, const BString& b); 394 bool operator<=(const char* a, const BString& b); 395 bool operator==(const char* a, const BString& b); 396 bool operator>(const char* a, const BString& b); 397 bool operator>=(const char* a, const BString& b); 398 bool operator!=(const char* a, const BString& b); 399 400 401 // Non-member compare for sorting, etc. 402 int Compare(const BString& a, const BString& b); 403 int ICompare(const BString& a, const BString& b); 404 int Compare(const BString* a, const BString* b); 405 int ICompare(const BString* a, const BString* b); 406 407 408 inline int32 409 BString::Length() const 410 { 411 // the most significant bit is reserved; accessing 412 // it in any way will cause the computer to explode 413 return fPrivateData ? (*(((int32 *)fPrivateData) - 1) & 0x7fffffff) : 0; 414 } 415 416 417 inline bool 418 BString::IsEmpty() const 419 { 420 return !Length(); 421 } 422 423 424 inline const char* 425 BString::String() const 426 { 427 if (!fPrivateData) 428 return ""; 429 return fPrivateData; 430 } 431 432 433 inline uint32 434 BString::HashValue() const 435 { 436 return HashValue(String()); 437 } 438 439 440 inline BString & 441 BString::SetTo(const char* string) 442 { 443 return operator=(string); 444 } 445 446 447 inline char 448 BString::operator[](int32 index) const 449 { 450 return fPrivateData[index]; 451 } 452 453 454 inline char 455 BString::ByteAt(int32 index) const 456 { 457 if (!fPrivateData || index < 0 || index >= Length()) 458 return 0; 459 return fPrivateData[index]; 460 } 461 462 463 inline BString & 464 BString::operator+=(const BString &string) 465 { 466 _DoAppend(string.String(), string.Length()); 467 return *this; 468 } 469 470 471 inline BString & 472 BString::Append(const BString &string) 473 { 474 _DoAppend(string.String(), string.Length()); 475 return *this; 476 } 477 478 479 inline BString & 480 BString::Append(const char* string) 481 { 482 return operator+=(string); 483 } 484 485 486 inline bool 487 BString::operator==(const BString &string) const 488 { 489 return strcmp(String(), string.String()) == 0; 490 } 491 492 493 inline bool 494 BString::operator<(const BString &string) const 495 { 496 return strcmp(String(), string.String()) < 0; 497 } 498 499 500 inline bool 501 BString::operator<=(const BString &string) const 502 { 503 return strcmp(String(), string.String()) <= 0; 504 } 505 506 507 inline bool 508 BString::operator>=(const BString &string) const 509 { 510 return strcmp(String(), string.String()) >= 0; 511 } 512 513 514 inline bool 515 BString::operator>(const BString &string) const 516 { 517 return strcmp(String(), string.String()) > 0; 518 } 519 520 521 inline bool 522 BString::operator!=(const BString &string) const 523 { 524 return strcmp(String(), string.String()) != 0; 525 } 526 527 528 inline bool 529 BString::operator!=(const char* string) const 530 { 531 return !operator==(string); 532 } 533 534 535 inline 536 BString::operator const char*() const 537 { 538 return String(); 539 } 540 541 542 inline bool 543 operator<(const char *str, const BString &string) 544 { 545 return string > str; 546 } 547 548 549 inline bool 550 operator<=(const char *str, const BString &string) 551 { 552 return string >= str; 553 } 554 555 556 inline bool 557 operator==(const char *str, const BString &string) 558 { 559 return string == str; 560 } 561 562 563 inline bool 564 operator>(const char *str, const BString &string) 565 { 566 return string < str; 567 } 568 569 570 inline bool 571 operator>=(const char *str, const BString &string) 572 { 573 return string <= str; 574 } 575 576 577 inline bool 578 operator!=(const char *str, const BString &string) 579 { 580 return string != str; 581 } 582 583 584 // #pragma mark - BStringRef 585 586 587 class BStringRef { 588 public: 589 BStringRef(BString& string, int32 position); 590 ~BStringRef() {} 591 592 operator char() const; 593 594 char* operator&(); 595 const char* operator&() const; 596 597 BStringRef& operator=(char c); 598 BStringRef& operator=(const BStringRef& rc); 599 600 private: 601 BString& fString; 602 int32 fPosition; 603 }; 604 605 #endif // __BSTRING__ 606