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