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