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