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