1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: String.h 23 // Author(s): Stefano Ceccherini (burton666@libero.it) 24 // Description: String class supporting common string operations. 25 //------------------------------------------------------------------------------ 26 27 28 29 #ifndef __BSTRING__ 30 #define __BSTRING__ 31 32 #include <BeBuild.h> 33 #include <SupportDefs.h> 34 #include <string.h> 35 36 class BString { 37 public: 38 BString(); 39 BString(const char *); 40 BString(const BString &); 41 BString(const char *, int32 maxLength); 42 43 ~BString(); 44 45 /*---- Access --------------------------------------------------------------*/ 46 const char *String() const; 47 /* returns null-terminated string */ 48 49 int32 Length() const; 50 /* length of corresponding string */ 51 52 int32 CountChars() const; 53 /* returns number of UTF8 characters in string */ 54 /*---- Assignment ----------------------------------------------------------*/ 55 BString &operator=(const BString &); 56 BString &operator=(const char *); 57 BString &operator=(char); 58 59 BString &SetTo(const char *); 60 BString &SetTo(const char *, int32 length); 61 62 BString &SetTo(const BString &from); 63 BString &Adopt(BString &from); 64 /* leaves <from> empty, avoiding a copy */ 65 66 BString &SetTo(const BString &, int32 length); 67 BString &Adopt(BString &from, int32 length); 68 /* leaves <from> empty, avoiding a copy */ 69 70 BString &SetTo(char, int32 count); 71 72 /*---- Substring copying ---------------------------------------------------*/ 73 BString &CopyInto(BString &into, int32 fromOffset, 74 int32 length) const; 75 /* returns <into> ref as it's result; doesn't do 76 * anything if <into> is <this> 77 */ 78 79 void CopyInto(char *into, int32 fromOffset, 80 int32 length) const; 81 /* caller guarantees that <into> is large enough */ 82 83 /*---- Appending -----------------------------------------------------------*/ 84 BString &operator+=(const BString &); 85 BString &operator+=(const char *); 86 BString &operator+=(char); 87 88 BString &Append(const BString &); 89 BString &Append(const char *); 90 91 BString &Append(const BString &, int32 length); 92 BString &Append(const char *, int32 length); 93 BString &Append(char, int32 count); 94 95 /*---- Prepending ----------------------------------------------------------*/ 96 BString &Prepend(const char *); 97 BString &Prepend(const BString &); 98 BString &Prepend(const char *, int32); 99 BString &Prepend(const BString &, int32); 100 BString &Prepend(char, int32 count); 101 102 /*---- Inserting ----------------------------------------------------------*/ 103 BString &Insert(const char *, int32 pos); 104 BString &Insert(const char *, int32 length, int32 pos); 105 BString &Insert(const char *, int32 fromOffset, 106 int32 length, int32 pos); 107 108 BString &Insert(const BString &, int32 pos); 109 BString &Insert(const BString &, int32 length, int32 pos); 110 BString &Insert(const BString &, int32 fromOffset, 111 int32 length, int32 pos); 112 BString &Insert(char, int32 count, int32 pos); 113 114 /*---- Removing -----------------------------------------------------------*/ 115 BString &Truncate(int32 newLength, bool lazy = true); 116 /* pass false in <lazy> to ensure freeing up the 117 * truncated memory 118 */ 119 120 BString &Remove(int32 from, int32 length); 121 122 BString &RemoveFirst(const BString &); 123 BString &RemoveLast(const BString &); 124 BString &RemoveAll(const BString &); 125 126 BString &RemoveFirst(const char *); 127 BString &RemoveLast(const char *); 128 BString &RemoveAll(const char *); 129 130 BString &RemoveSet(const char *setOfCharsToRemove); 131 132 BString &MoveInto(BString &into, int32 from, int32 length); 133 void MoveInto(char *into, int32 from, int32 length); 134 /* caller guarantees that <into> is large enough */ 135 136 137 /*---- Compare functions ---------------------------------------------------*/ 138 bool operator<(const BString &) const; 139 bool operator<=(const BString &) const; 140 bool operator==(const BString &) const; 141 bool operator>=(const BString &) const; 142 bool operator>(const BString &) const; 143 bool operator!=(const BString &) const; 144 145 bool operator<(const char *) const; 146 bool operator<=(const char *) const; 147 bool operator==(const char *) const; 148 bool operator>=(const char *) const; 149 bool operator>(const char *) const; 150 bool operator!=(const char *) const; 151 152 /*---- strcmp-style compare functions --------------------------------------*/ 153 int Compare(const BString &) const; 154 int Compare(const char *) const; 155 int Compare(const BString &, int32 n) const; 156 int Compare(const char *, int32 n) const; 157 int ICompare(const BString &) const; 158 int ICompare(const char *) const; 159 int ICompare(const BString &, int32 n) const; 160 int ICompare(const char *, int32 n) const; 161 162 /*---- Searching -----------------------------------------------------------*/ 163 int32 FindFirst(const BString &) const; 164 int32 FindFirst(const char *) const; 165 int32 FindFirst(const BString &, int32 fromOffset) const; 166 int32 FindFirst(const char *, int32 fromOffset) const; 167 int32 FindFirst(char) const; 168 int32 FindFirst(char, int32 fromOffset) const; 169 170 int32 FindLast(const BString &) const; 171 int32 FindLast(const char *) const; 172 int32 FindLast(const BString &, int32 beforeOffset) const; 173 int32 FindLast(const char *, int32 beforeOffset) const; 174 int32 FindLast(char) const; 175 int32 FindLast(char, int32 beforeOffset) const; 176 177 int32 IFindFirst(const BString &) const; 178 int32 IFindFirst(const char *) const; 179 int32 IFindFirst(const BString &, int32 fromOffset) const; 180 int32 IFindFirst(const char *, int32 fromOffset) const; 181 182 int32 IFindLast(const BString &) const; 183 int32 IFindLast(const char *) const; 184 int32 IFindLast(const BString &, int32 beforeOffset) const; 185 int32 IFindLast(const char *, int32 beforeOffset) const; 186 187 /*---- Replacing -----------------------------------------------------------*/ 188 189 BString &ReplaceFirst(char replaceThis, char withThis); 190 BString &ReplaceLast(char replaceThis, char withThis); 191 BString &ReplaceAll(char replaceThis, char withThis, 192 int32 fromOffset = 0); 193 BString &Replace(char replaceThis, char withThis, 194 int32 maxReplaceCount, int32 fromOffset = 0); 195 BString &ReplaceFirst(const char *replaceThis, 196 const char *withThis); 197 BString &ReplaceLast(const char *replaceThis, 198 const char *withThis); 199 BString &ReplaceAll(const char *replaceThis, 200 const char *withThis, int32 fromOffset = 0); 201 BString &Replace(const char *replaceThis, const char *withThis, 202 int32 maxReplaceCount, int32 fromOffset = 0); 203 204 BString &IReplaceFirst(char replaceThis, char withThis); 205 BString &IReplaceLast(char replaceThis, char withThis); 206 BString &IReplaceAll(char replaceThis, char withThis, 207 int32 fromOffset = 0); 208 BString &IReplace(char replaceThis, char withThis, 209 int32 maxReplaceCount, int32 fromOffset = 0); 210 BString &IReplaceFirst(const char *replaceThis, 211 const char *withThis); 212 BString &IReplaceLast(const char *replaceThis, 213 const char *withThis); 214 BString &IReplaceAll(const char *replaceThis, 215 const char *withThis, int32 fromOffset = 0); 216 BString &IReplace(const char *replaceThis, const char *withThis, 217 int32 maxReplaceCount, int32 fromOffset = 0); 218 219 BString &ReplaceSet(const char *setOfChars, char with); 220 BString &ReplaceSet(const char *setOfChars, const char *with); 221 /*---- Unchecked char access -----------------------------------------------*/ 222 char operator[](int32 index) const; 223 char &operator[](int32 index); 224 225 /*---- Checked char access -------------------------------------------------*/ 226 char ByteAt(int32 index) const; 227 228 /*---- Fast low-level manipulation -----------------------------------------*/ 229 char *LockBuffer(int32 maxLength); 230 231 /* Make room for characters to be added by C-string like manipulation. 232 * Returns the equivalent of String(), <maxLength> includes space for 233 * trailing zero while used as C-string, it is illegal to call other 234 * BString routines that rely on data/length consistency until 235 * UnlockBuffer sets things up again. 236 */ 237 238 BString &UnlockBuffer(int32 length = -1); 239 240 /* Finish using BString as C-string, adjusting length. If no length 241 * passed in, strlen of internal data is used to determine it. 242 * BString is in consistent state after this. 243 */ 244 245 /*---- Upercase<->Lowercase ------------------------------------------------*/ 246 BString &ToLower(); 247 BString &ToUpper(); 248 249 BString &Capitalize(); 250 /* Converts first character to upper-case, rest to 251 * lower-case 252 */ 253 254 BString &CapitalizeEachWord(); 255 /* Converts first character in each 256 * non-alphabethycal-character-separated 257 * word to upper-case, rest to lower-case 258 */ 259 /*----- Escaping and Deescaping --------------------------------------------*/ 260 BString &CharacterEscape(const char *original, 261 const char *setOfCharsToEscape, char escapeWith); 262 /* copies original into <this>, escaping characters 263 * specified in <setOfCharsToEscape> by prepending 264 * them with <escapeWith> 265 */ 266 BString &CharacterEscape(const char *setOfCharsToEscape, 267 char escapeWith); 268 /* escapes characters specified in <setOfCharsToEscape> 269 * by prepending them with <escapeWith> 270 */ 271 272 BString &CharacterDeescape(const char *original, char escapeChar); 273 /* copy <original> into the string removing the escaping 274 * characters <escapeChar> 275 */ 276 BString &CharacterDeescape(char escapeChar); 277 /* remove the escaping characters <escapeChar> from 278 * the string 279 */ 280 281 /*---- Simple sprintf replacement calls ------------------------------------*/ 282 /*---- Slower than sprintf but type and overflow safe ----------------------*/ 283 BString &operator<<(const char *); 284 BString &operator<<(const BString &); 285 BString &operator<<(char); 286 BString &operator<<(int); 287 BString &operator<<(unsigned int); 288 BString &operator<<(uint32); 289 BString &operator<<(int32); 290 BString &operator<<(uint64); 291 BString &operator<<(int64); 292 BString &operator<<(float); 293 /* float output hardcodes %.2f style formatting */ 294 295 /*----- Private or reserved ------------------------------------------------*/ 296 private: 297 void _Init(const char *, int32); 298 void _DoAssign(const char *, int32); 299 void _DoAppend(const char *, int32); 300 char *_GrowBy(int32); 301 char *_OpenAtBy(int32, int32); 302 char *_ShrinkAtBy(int32, int32); 303 void _DoPrepend(const char *, int32); 304 305 int32 _FindAfter(const char *, int32, int32) const; 306 int32 _IFindAfter(const char *, int32, int32) const; 307 int32 _ShortFindAfter(const char *, int32) const; 308 int32 _FindBefore(const char *, int32, int32) const; 309 int32 _IFindBefore(const char *, int32, int32) const; 310 BString &_DoReplace(const char *, const char *, int32, int32, 311 bool); 312 void _SetLength(int32); 313 314 #if DEBUG 315 void _SetUsingAsCString(bool); 316 void _AssertNotUsingAsCString() const; 317 #else 318 void _SetUsingAsCString(bool) {} 319 void _AssertNotUsingAsCString() const {} 320 #endif 321 322 protected: 323 char *_privateData; 324 }; 325 326 /*----- Comutative compare operators --------------------------------------*/ 327 bool operator<(const char *, const BString &); 328 bool operator<=(const char *, const BString &); 329 bool operator==(const char *, const BString &); 330 bool operator>(const char *, const BString &); 331 bool operator>=(const char *, const BString &); 332 bool operator!=(const char *, const BString &); 333 334 /*----- Non-member compare for sorting, etc. ------------------------------*/ 335 int Compare(const BString &, const BString &); 336 int ICompare(const BString &, const BString &); 337 int Compare(const BString *, const BString *); 338 int ICompare(const BString *, const BString *); 339 340 341 342 343 /*-------------------------------------------------------------------------*/ 344 /*---- No user serviceable parts after this -------------------------------*/ 345 346 inline int32 347 BString::Length() const 348 { 349 return _privateData ? (*((int32 *)_privateData - 1) & 0x7fffffff) : 0; 350 /* the most significant bit is reserved; accessing 351 * it in any way will cause the computer to explode 352 */ 353 } 354 355 inline const char * 356 BString::String() const 357 { 358 if (!_privateData) 359 return ""; 360 return _privateData; 361 } 362 363 inline BString & 364 BString::SetTo(const char *str) 365 { 366 return operator=(str); 367 } 368 369 inline char 370 BString::operator[](int32 index) const 371 { 372 return _privateData[index]; 373 } 374 375 inline char 376 BString::ByteAt(int32 index) const 377 { 378 if (!_privateData || index < 0 || index > Length()) 379 return 0; 380 return _privateData[index]; 381 } 382 383 inline BString & 384 BString::operator+=(const BString &string) 385 { 386 _DoAppend(string.String(), string.Length()); 387 return *this; 388 } 389 390 inline BString & 391 BString::Append(const BString &string) 392 { 393 _DoAppend(string.String(), string.Length()); 394 return *this; 395 } 396 397 inline BString & 398 BString::Append(const char *str) 399 { 400 return operator+=(str); 401 } 402 403 inline bool 404 BString::operator==(const BString &string) const 405 { 406 return strcmp(String(), string.String()) == 0; 407 } 408 409 inline bool 410 BString::operator<(const BString &string) const 411 { 412 return strcmp(String(), string.String()) < 0; 413 } 414 415 inline bool 416 BString::operator<=(const BString &string) const 417 { 418 return strcmp(String(), string.String()) <= 0; 419 } 420 421 inline bool 422 BString::operator>=(const BString &string) const 423 { 424 return strcmp(String(), string.String()) >= 0; 425 } 426 427 inline bool 428 BString::operator>(const BString &string) const 429 { 430 return strcmp(String(), string.String()) > 0; 431 } 432 433 inline bool 434 BString::operator!=(const BString &string) const 435 { 436 return strcmp(String(), string.String()) != 0; 437 } 438 439 inline bool 440 BString::operator!=(const char *str) const 441 { 442 return !operator==(str); 443 } 444 445 inline bool 446 operator<(const char *str, const BString &string) 447 { 448 return string > str; 449 } 450 451 inline bool 452 operator<=(const char *str, const BString &string) 453 { 454 return string >= str; 455 } 456 457 inline bool 458 operator==(const char *str, const BString &string) 459 { 460 return string == str; 461 } 462 463 inline bool 464 operator>(const char *str, const BString &string) 465 { 466 return string < str; 467 } 468 469 inline bool 470 operator>=(const char *str, const BString &string) 471 { 472 return string <= str; 473 } 474 475 inline bool 476 operator!=(const char *str, const BString &string) 477 { 478 return string != str; 479 } 480 481 #endif /* __BSTRING__ */ 482