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