diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2012-03-25 20:00:08 +0000 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2012-03-25 20:00:08 +0000 |
| commit | 469bbcf0701e1eb8a6670c23145b0da87357e178 (patch) | |
| tree | b5b062a16e46a6c5d3410b4e574cd0cc09057211 /src/stable/string.h | |
| parent | ee1b79396076edc4e30aefb285fada03bb45e80d (diff) | |
| download | libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.gz libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.bz2 libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.xz libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.zip | |
Code is all reorganized. We're about ready to release. I should write up a
little explenation of the arrangement.
Diffstat (limited to 'src/stable/string.h')
| -rw-r--r-- | src/stable/string.h | 1053 |
1 files changed, 1053 insertions, 0 deletions
diff --git a/src/stable/string.h b/src/stable/string.h new file mode 100644 index 0000000..a9006d1 --- /dev/null +++ b/src/stable/string.h | |||
| @@ -0,0 +1,1053 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007-2011 Xagasoft, All rights reserved. | ||
| 3 | * | ||
| 4 | * This file is part of the libbu++ library and is released under the | ||
| 5 | * terms of the license contained in the file LICENSE. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef BU_STRING_H | ||
| 9 | #define BU_STRING_H | ||
| 10 | |||
| 11 | #include <stdint.h> | ||
| 12 | #include <memory> | ||
| 13 | |||
| 14 | #include "bu/util.h" | ||
| 15 | #include "bu/sharedcore.h" | ||
| 16 | #include "bu/exceptionbase.h" | ||
| 17 | #include "bu/archivebase.h" | ||
| 18 | #include "bu/list.h" | ||
| 19 | #include "bu/fmt.h" | ||
| 20 | #include "bu/variant.h" | ||
| 21 | #include <string.h> | ||
| 22 | |||
| 23 | namespace Bu | ||
| 24 | { | ||
| 25 | class String; | ||
| 26 | class MemBuf; | ||
| 27 | |||
| 28 | /** @cond DEVEL */ | ||
| 29 | class StringCore | ||
| 30 | { | ||
| 31 | friend class String; | ||
| 32 | friend class SharedCore<String, StringCore>; | ||
| 33 | private: | ||
| 34 | struct Chunk | ||
| 35 | { | ||
| 36 | long nLength; | ||
| 37 | char *pData; | ||
| 38 | Chunk *pNext; | ||
| 39 | }; | ||
| 40 | |||
| 41 | StringCore(); | ||
| 42 | StringCore( const StringCore &rSrc ); | ||
| 43 | virtual ~StringCore(); | ||
| 44 | |||
| 45 | mutable long nLength; | ||
| 46 | mutable Chunk *pFirst; | ||
| 47 | mutable Chunk *pLast; | ||
| 48 | |||
| 49 | void clear() const; | ||
| 50 | Chunk *newChunk() const; | ||
| 51 | Chunk *newChunk( long nLen ) const; | ||
| 52 | Chunk *copyChunk( Chunk *pSrc ) const; | ||
| 53 | void appendChunk( Chunk *pNewChunk ); | ||
| 54 | void prependChunk( Chunk *pNewChunk ); | ||
| 55 | }; | ||
| 56 | /** @endcond */ | ||
| 57 | |||
| 58 | /** | ||
| 59 | */ | ||
| 60 | class String : public SharedCore<String, StringCore> | ||
| 61 | { | ||
| 62 | protected: | ||
| 63 | using SharedCore<String, StringCore >::core; | ||
| 64 | using SharedCore<String, StringCore >::_hardCopy; | ||
| 65 | |||
| 66 | private: | ||
| 67 | typedef StringCore::Chunk Chunk; | ||
| 68 | |||
| 69 | public: // Iterators | ||
| 70 | struct iterator; | ||
| 71 | typedef struct const_iterator | ||
| 72 | { | ||
| 73 | friend class String; | ||
| 74 | friend struct iterator; | ||
| 75 | private: | ||
| 76 | const_iterator( Chunk *pChunk, int iPos ) : | ||
| 77 | pChunk( pChunk ), | ||
| 78 | iPos( iPos ) | ||
| 79 | { | ||
| 80 | } | ||
| 81 | |||
| 82 | Chunk *pChunk; | ||
| 83 | int iPos; | ||
| 84 | |||
| 85 | public: | ||
| 86 | const_iterator( const const_iterator &i ) : | ||
| 87 | pChunk( i.pChunk ), | ||
| 88 | iPos( i.iPos ) | ||
| 89 | { | ||
| 90 | } | ||
| 91 | |||
| 92 | const_iterator( const struct iterator &i ) : | ||
| 93 | pChunk( i.pChunk ), | ||
| 94 | iPos( i.iPos ) | ||
| 95 | { | ||
| 96 | } | ||
| 97 | |||
| 98 | const_iterator() : | ||
| 99 | pChunk( NULL ), | ||
| 100 | iPos( 0 ) | ||
| 101 | { | ||
| 102 | } | ||
| 103 | |||
| 104 | bool operator==( const const_iterator &i ) const | ||
| 105 | { | ||
| 106 | return pChunk == i.pChunk && iPos == i.iPos; | ||
| 107 | } | ||
| 108 | |||
| 109 | bool operator!=( const const_iterator &i ) const | ||
| 110 | { | ||
| 111 | return !(*this == i); | ||
| 112 | } | ||
| 113 | |||
| 114 | const_iterator &operator=( const const_iterator &i ) | ||
| 115 | { | ||
| 116 | pChunk = i.pChunk; | ||
| 117 | iPos = i.iPos; | ||
| 118 | return *this; | ||
| 119 | } | ||
| 120 | |||
| 121 | const_iterator &operator=( const iterator &i ) | ||
| 122 | { | ||
| 123 | pChunk = i.pChunk; | ||
| 124 | iPos = i.iPos; | ||
| 125 | return *this; | ||
| 126 | } | ||
| 127 | |||
| 128 | const_iterator &operator++() | ||
| 129 | { | ||
| 130 | if( !pChunk ) return *this; | ||
| 131 | iPos++; | ||
| 132 | if( iPos >= pChunk->nLength ) | ||
| 133 | { | ||
| 134 | iPos = 0; | ||
| 135 | pChunk = pChunk->pNext; | ||
| 136 | } | ||
| 137 | return *this; | ||
| 138 | } | ||
| 139 | |||
| 140 | const_iterator &operator++( int ) | ||
| 141 | { | ||
| 142 | if( !pChunk ) return *this; | ||
| 143 | iPos++; | ||
| 144 | if( iPos >= pChunk->nLength ) | ||
| 145 | { | ||
| 146 | iPos = 0; | ||
| 147 | pChunk = pChunk->pNext; | ||
| 148 | } | ||
| 149 | return *this; | ||
| 150 | } | ||
| 151 | |||
| 152 | const_iterator &operator+=( int iAmnt ) | ||
| 153 | { | ||
| 154 | if( !pChunk ) return *this; | ||
| 155 | iPos += iAmnt; | ||
| 156 | while( iPos >= pChunk->nLength ) | ||
| 157 | { | ||
| 158 | iPos -= pChunk->nLength; | ||
| 159 | pChunk = pChunk->pNext; | ||
| 160 | if( pChunk == NULL ) | ||
| 161 | break; | ||
| 162 | } | ||
| 163 | return *this; | ||
| 164 | } | ||
| 165 | |||
| 166 | const_iterator operator+( int iAmnt ) const | ||
| 167 | { | ||
| 168 | if( !pChunk ) return *this; | ||
| 169 | const_iterator ret( *this ); | ||
| 170 | ret += iAmnt; | ||
| 171 | return ret; | ||
| 172 | } | ||
| 173 | |||
| 174 | const char &operator *() const | ||
| 175 | { | ||
| 176 | if( !pChunk ) throw Bu::ExceptionBase("Not a valid const_iterator."); | ||
| 177 | return pChunk->pData[iPos]; | ||
| 178 | } | ||
| 179 | |||
| 180 | bool operator==( const char &c ) const | ||
| 181 | { | ||
| 182 | if( !pChunk ) return false; | ||
| 183 | return pChunk->pData[iPos] == c; | ||
| 184 | } | ||
| 185 | |||
| 186 | bool operator!=( const char &c ) const | ||
| 187 | { | ||
| 188 | if( !pChunk ) return false; | ||
| 189 | return pChunk->pData[iPos] != c; | ||
| 190 | } | ||
| 191 | |||
| 192 | operator bool() const | ||
| 193 | { | ||
| 194 | return pChunk != NULL; | ||
| 195 | } | ||
| 196 | |||
| 197 | bool isValid() const | ||
| 198 | { | ||
| 199 | return pChunk != NULL; | ||
| 200 | } | ||
| 201 | |||
| 202 | bool compare( const const_iterator &c ) const | ||
| 203 | { | ||
| 204 | const_iterator a = *this; | ||
| 205 | const_iterator b = c; | ||
| 206 | if( a == b ) | ||
| 207 | return true; | ||
| 208 | for(; a && b; a++, b++ ) | ||
| 209 | { | ||
| 210 | if( *a != *b ) | ||
| 211 | return false; | ||
| 212 | } | ||
| 213 | if( (bool)a != (bool)b ) | ||
| 214 | return false; | ||
| 215 | return true; | ||
| 216 | } | ||
| 217 | |||
| 218 | bool compare( const const_iterator &c, int nLen ) const | ||
| 219 | { | ||
| 220 | const_iterator a = *this; | ||
| 221 | const_iterator b = c; | ||
| 222 | if( a == b ) | ||
| 223 | return true; | ||
| 224 | for(int j = 0; j < nLen; a++, b++, j++ ) | ||
| 225 | { | ||
| 226 | if( !a || !b || *a != *b ) | ||
| 227 | return false; | ||
| 228 | } | ||
| 229 | return true; | ||
| 230 | } | ||
| 231 | |||
| 232 | bool compare( const char *c ) const | ||
| 233 | { | ||
| 234 | if( !pChunk ) return false; | ||
| 235 | const_iterator a = *this; | ||
| 236 | for(; a && *c; a++, c++ ) | ||
| 237 | { | ||
| 238 | if( *a != *c ) | ||
| 239 | return false; | ||
| 240 | } | ||
| 241 | if( a.isValid() != (*c!=(char)0) ) | ||
| 242 | return false; | ||
| 243 | return true; | ||
| 244 | } | ||
| 245 | |||
| 246 | bool compare( const char *c, int nLen ) const | ||
| 247 | { | ||
| 248 | if( !pChunk ) return false; | ||
| 249 | const_iterator a = *this; | ||
| 250 | int j = 0; | ||
| 251 | for(; a && j < nLen; a++, c++, j++ ) | ||
| 252 | { | ||
| 253 | if( *a != *c ) | ||
| 254 | return false; | ||
| 255 | } | ||
| 256 | if( j < nLen ) | ||
| 257 | return false; | ||
| 258 | return true; | ||
| 259 | } | ||
| 260 | |||
| 261 | bool compare( const String &s ) const | ||
| 262 | { | ||
| 263 | if( !pChunk ) return false; | ||
| 264 | return compare( s.begin() ); | ||
| 265 | } | ||
| 266 | |||
| 267 | bool compare( const String &s, int nLen ) const | ||
| 268 | { | ||
| 269 | if( !pChunk ) return false; | ||
| 270 | return compare( s.begin(), nLen ); | ||
| 271 | } | ||
| 272 | |||
| 273 | const_iterator find( const char c ) const | ||
| 274 | { | ||
| 275 | for( const_iterator i = *this; i; i++ ) | ||
| 276 | { | ||
| 277 | if( *i == c ) | ||
| 278 | return i; | ||
| 279 | } | ||
| 280 | return const_iterator( NULL, 0 ); | ||
| 281 | } | ||
| 282 | |||
| 283 | const_iterator find( const char *pStr, int nLen ) const | ||
| 284 | { | ||
| 285 | for( const_iterator i = *this; i; i++ ) | ||
| 286 | { | ||
| 287 | if( i.compare( pStr, nLen ) ) | ||
| 288 | return i; | ||
| 289 | } | ||
| 290 | return const_iterator( NULL, 0 ); | ||
| 291 | } | ||
| 292 | |||
| 293 | const_iterator find( const String &s ) const | ||
| 294 | { | ||
| 295 | for( const_iterator i = *this; i; i++ ) | ||
| 296 | { | ||
| 297 | if( i.compare( s ) ) | ||
| 298 | return i; | ||
| 299 | } | ||
| 300 | return const_iterator( NULL, 0 ); | ||
| 301 | } | ||
| 302 | |||
| 303 | const_iterator find( const String &s, int nLen ) const | ||
| 304 | { | ||
| 305 | for( const_iterator i = *this; i; i++ ) | ||
| 306 | { | ||
| 307 | if( i.compare( s, nLen ) ) | ||
| 308 | return i; | ||
| 309 | } | ||
| 310 | return const_iterator( NULL, 0 ); | ||
| 311 | } | ||
| 312 | } const_iterator; | ||
| 313 | |||
| 314 | typedef struct iterator | ||
| 315 | { | ||
| 316 | friend class String; | ||
| 317 | friend struct const_iterator; | ||
| 318 | private: | ||
| 319 | iterator( Chunk *pChunk, int iPos ) : | ||
| 320 | pChunk( pChunk ), | ||
| 321 | iPos( iPos ) | ||
| 322 | { | ||
| 323 | } | ||
| 324 | |||
| 325 | Chunk *pChunk; | ||
| 326 | int iPos; | ||
| 327 | |||
| 328 | public: | ||
| 329 | iterator( const iterator &i ) : | ||
| 330 | pChunk( i.pChunk ), | ||
| 331 | iPos( i.iPos ) | ||
| 332 | { | ||
| 333 | } | ||
| 334 | |||
| 335 | iterator() : | ||
| 336 | pChunk( NULL ), | ||
| 337 | iPos( 0 ) | ||
| 338 | { | ||
| 339 | } | ||
| 340 | |||
| 341 | operator const_iterator() const | ||
| 342 | { | ||
| 343 | return const_iterator( pChunk, iPos ); | ||
| 344 | } | ||
| 345 | |||
| 346 | bool operator==( const iterator &i ) const | ||
| 347 | { | ||
| 348 | return pChunk == i.pChunk && iPos == i.iPos; | ||
| 349 | } | ||
| 350 | |||
| 351 | bool operator!=( const iterator &i ) const | ||
| 352 | { | ||
| 353 | return !(*this == i); | ||
| 354 | } | ||
| 355 | |||
| 356 | iterator &operator=( const iterator &i ) | ||
| 357 | { | ||
| 358 | pChunk = i.pChunk; | ||
| 359 | iPos = i.iPos; | ||
| 360 | return *this; | ||
| 361 | } | ||
| 362 | |||
| 363 | iterator &operator++() | ||
| 364 | { | ||
| 365 | if( !pChunk ) return *this; | ||
| 366 | iPos++; | ||
| 367 | if( iPos >= pChunk->nLength ) | ||
| 368 | { | ||
| 369 | iPos = 0; | ||
| 370 | pChunk = pChunk->pNext; | ||
| 371 | } | ||
| 372 | return *this; | ||
| 373 | } | ||
| 374 | |||
| 375 | iterator &operator++( int ) | ||
| 376 | { | ||
| 377 | if( !pChunk ) return *this; | ||
| 378 | iPos++; | ||
| 379 | if( iPos >= pChunk->nLength ) | ||
| 380 | { | ||
| 381 | iPos = 0; | ||
| 382 | pChunk = pChunk->pNext; | ||
| 383 | } | ||
| 384 | return *this; | ||
| 385 | } | ||
| 386 | |||
| 387 | iterator &operator+=( int iAmnt ) | ||
| 388 | { | ||
| 389 | if( !pChunk ) return *this; | ||
| 390 | iPos += iAmnt; | ||
| 391 | while( iPos >= pChunk->nLength ) | ||
| 392 | { | ||
| 393 | iPos -= pChunk->nLength; | ||
| 394 | pChunk = pChunk->pNext; | ||
| 395 | if( pChunk == NULL ) | ||
| 396 | break; | ||
| 397 | } | ||
| 398 | return *this; | ||
| 399 | } | ||
| 400 | |||
| 401 | iterator operator+( int iAmnt ) const | ||
| 402 | { | ||
| 403 | if( !pChunk ) return *this; | ||
| 404 | iterator ret( *this ); | ||
| 405 | ret += iAmnt; | ||
| 406 | return ret; | ||
| 407 | } | ||
| 408 | |||
| 409 | char &operator*() | ||
| 410 | { | ||
| 411 | if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator."); | ||
| 412 | return pChunk->pData[iPos]; | ||
| 413 | } | ||
| 414 | |||
| 415 | const char &operator*() const | ||
| 416 | { | ||
| 417 | if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator."); | ||
| 418 | return pChunk->pData[iPos]; | ||
| 419 | } | ||
| 420 | |||
| 421 | bool operator==( const char &c ) const | ||
| 422 | { | ||
| 423 | if( !pChunk ) return false; | ||
| 424 | return pChunk->pData[iPos] == c; | ||
| 425 | } | ||
| 426 | |||
| 427 | bool operator!=( const char &c ) const | ||
| 428 | { | ||
| 429 | if( !pChunk ) return false; | ||
| 430 | return pChunk->pData[iPos] != c; | ||
| 431 | } | ||
| 432 | |||
| 433 | iterator &operator=( const char &c ) | ||
| 434 | { | ||
| 435 | if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator."); | ||
| 436 | pChunk->pData[iPos] = c; | ||
| 437 | return *this; | ||
| 438 | } | ||
| 439 | |||
| 440 | operator bool() const | ||
| 441 | { | ||
| 442 | return pChunk != NULL; | ||
| 443 | } | ||
| 444 | |||
| 445 | bool isValid() const | ||
| 446 | { | ||
| 447 | return pChunk != NULL; | ||
| 448 | } | ||
| 449 | |||
| 450 | bool compare( const const_iterator &c ) const | ||
| 451 | { | ||
| 452 | const_iterator a( *this ); | ||
| 453 | const_iterator b = c; | ||
| 454 | if( a == b ) | ||
| 455 | return true; | ||
| 456 | for(; a && b; a++, b++ ) | ||
| 457 | { | ||
| 458 | if( *a != *b ) | ||
| 459 | return false; | ||
| 460 | } | ||
| 461 | if( (bool)a != (bool)b ) | ||
| 462 | return false; | ||
| 463 | return true; | ||
| 464 | } | ||
| 465 | |||
| 466 | bool compare( const const_iterator &c, int nLen ) const | ||
| 467 | { | ||
| 468 | const_iterator a( *this ); | ||
| 469 | const_iterator b = c; | ||
| 470 | if( a == b ) | ||
| 471 | return true; | ||
| 472 | for(int j = 0; j < nLen; a++, b++, j++ ) | ||
| 473 | { | ||
| 474 | if( !a || !b || *a != *b ) | ||
| 475 | return false; | ||
| 476 | } | ||
| 477 | return true; | ||
| 478 | } | ||
| 479 | |||
| 480 | bool compare( const char *c ) const | ||
| 481 | { | ||
| 482 | if( !pChunk ) return false; | ||
| 483 | iterator a = *this; | ||
| 484 | for(; a && *c; a++, c++ ) | ||
| 485 | { | ||
| 486 | if( *a != *c ) | ||
| 487 | return false; | ||
| 488 | } | ||
| 489 | if( a.isValid() != (*c!=(char)0) ) | ||
| 490 | return false; | ||
| 491 | return true; | ||
| 492 | } | ||
| 493 | |||
| 494 | bool compare( const char *c, int nLen ) const | ||
| 495 | { | ||
| 496 | if( !pChunk ) return false; | ||
| 497 | iterator a = *this; | ||
| 498 | int j = 0; | ||
| 499 | for(; a && j < nLen; a++, c++, j++ ) | ||
| 500 | { | ||
| 501 | if( *a != *c ) | ||
| 502 | return false; | ||
| 503 | } | ||
| 504 | if( j < nLen ) | ||
| 505 | return false; | ||
| 506 | return true; | ||
| 507 | } | ||
| 508 | |||
| 509 | bool compare( const String &s ) const | ||
| 510 | { | ||
| 511 | if( !pChunk ) return false; | ||
| 512 | return compare( s.begin() ); | ||
| 513 | } | ||
| 514 | |||
| 515 | bool compare( const String &s, int nLen ) const | ||
| 516 | { | ||
| 517 | if( !pChunk ) return false; | ||
| 518 | return compare( s.begin(), nLen ); | ||
| 519 | } | ||
| 520 | |||
| 521 | iterator find( const char c ) const | ||
| 522 | { | ||
| 523 | for( iterator i = *this; i; i++ ) | ||
| 524 | { | ||
| 525 | if( *i == c ) | ||
| 526 | return i; | ||
| 527 | } | ||
| 528 | return iterator( NULL, 0 ); | ||
| 529 | } | ||
| 530 | |||
| 531 | iterator find( const char *pStr, int nLen ) const | ||
| 532 | { | ||
| 533 | for( iterator i = *this; i; i++ ) | ||
| 534 | { | ||
| 535 | if( i.compare( pStr, nLen ) ) | ||
| 536 | return i; | ||
| 537 | } | ||
| 538 | return iterator( NULL, 0 ); | ||
| 539 | } | ||
| 540 | |||
| 541 | iterator find( const String &s ) const | ||
| 542 | { | ||
| 543 | for( iterator i = *this; i; i++ ) | ||
| 544 | { | ||
| 545 | if( i.compare( s ) ) | ||
| 546 | return i; | ||
| 547 | } | ||
| 548 | return iterator( NULL, 0 ); | ||
| 549 | } | ||
| 550 | |||
| 551 | iterator find( const String &s, int nLen ) const | ||
| 552 | { | ||
| 553 | for( iterator i = *this; i; i++ ) | ||
| 554 | { | ||
| 555 | if( i.compare( s, nLen ) ) | ||
| 556 | return i; | ||
| 557 | } | ||
| 558 | return iterator( NULL, 0 ); | ||
| 559 | } | ||
| 560 | } iterator; | ||
| 561 | |||
| 562 | public: | ||
| 563 | String(); | ||
| 564 | String( const char *pData ); | ||
| 565 | String( const char *pData, long nLength ); | ||
| 566 | String( const String &rSrc ); | ||
| 567 | String( const String &rSrc, long nLength ); | ||
| 568 | String( const String &rSrc, long nStart, long nLength ); | ||
| 569 | String( long nSize ); | ||
| 570 | String( const const_iterator &s ); | ||
| 571 | String( const const_iterator &s, const const_iterator &e ); | ||
| 572 | virtual ~String(); | ||
| 573 | |||
| 574 | /** | ||
| 575 | * Append data to your string. | ||
| 576 | *@param pData (const char *) The data to append. | ||
| 577 | */ | ||
| 578 | void append( const char *pData ); | ||
| 579 | |||
| 580 | /** | ||
| 581 | * Append data to your string. | ||
| 582 | *@param pData (const char *) The data to append. | ||
| 583 | *@param nLen (long) The length of the data to append. | ||
| 584 | */ | ||
| 585 | void append( const char *pData, long nLen ); | ||
| 586 | |||
| 587 | /** | ||
| 588 | * Append data to your string. | ||
| 589 | *@param pData (const char *) The data to append. | ||
| 590 | *@param nStart (long) The start position to copy from. | ||
| 591 | *@param nLen (long) The length of the data to append. | ||
| 592 | */ | ||
| 593 | void append( const char *pData, long nStart, long nLen ); | ||
| 594 | |||
| 595 | /** | ||
| 596 | * Append a single char to your string. | ||
| 597 | *@param cData (const char &) The character to append. | ||
| 598 | */ | ||
| 599 | void append( const char &cData ); | ||
| 600 | |||
| 601 | /** | ||
| 602 | * Append another String to this one. | ||
| 603 | *@param sData (String &) The String to append. | ||
| 604 | *@todo This function can be made much faster by not using getStr() | ||
| 605 | */ | ||
| 606 | void append( const String & sData ); | ||
| 607 | |||
| 608 | /** | ||
| 609 | * Append another String to this one. | ||
| 610 | *@param sData (String &) The String to append. | ||
| 611 | *@param nLen How much data to append. | ||
| 612 | *@todo This function can be made much faster by not using getStr() | ||
| 613 | */ | ||
| 614 | void append( const String & sData, long nLen ); | ||
| 615 | |||
| 616 | /** | ||
| 617 | * Append another String to this one. | ||
| 618 | *@param sData (String &) The String to append. | ||
| 619 | *@param nStart Start position in sData to start copying from. | ||
| 620 | *@param nLen How much data to append. | ||
| 621 | *@todo This function can be made much faster by not using getStr() | ||
| 622 | */ | ||
| 623 | void append( const String & sData, long nStart, long nLen ); | ||
| 624 | |||
| 625 | /** | ||
| 626 | * Append data to this String using the passed in iterator as a base. | ||
| 627 | * The iterator is const, it is not changed. | ||
| 628 | *@param s Iterator from any compatible String to copy data from. | ||
| 629 | */ | ||
| 630 | void append( const const_iterator &s ); | ||
| 631 | |||
| 632 | /** | ||
| 633 | * Append data to this String using the passed in iterator as a base. | ||
| 634 | * The iterator is const, it is not changed. | ||
| 635 | *@param s Iterator from any compatible String to copy data from. | ||
| 636 | */ | ||
| 637 | void append( const iterator &s ); | ||
| 638 | |||
| 639 | /** | ||
| 640 | * Append data to this String using the passed in iterator as a base, | ||
| 641 | * and copy data until the ending iterator is reached. The character | ||
| 642 | * at the ending iterator is not copied. | ||
| 643 | * The iterators are const, they are not changed. | ||
| 644 | *@param s Iterator from any compatible String to copy data from. | ||
| 645 | *@param e Iterator to stop copying at. | ||
| 646 | */ | ||
| 647 | void append( const const_iterator &s, const const_iterator &e ); | ||
| 648 | |||
| 649 | /** | ||
| 650 | * Prepend another String to this one. | ||
| 651 | *@param sData (String &) The String to prepend. | ||
| 652 | *@todo This function can be made much faster by not using getStr() | ||
| 653 | */ | ||
| 654 | void prepend( const String & sData ); | ||
| 655 | |||
| 656 | /** | ||
| 657 | * Prepend data to your string. | ||
| 658 | *@param pData (const char *) The data to prepend. | ||
| 659 | */ | ||
| 660 | void prepend( const char *pData ); | ||
| 661 | |||
| 662 | /** | ||
| 663 | * Prepend data to your string. | ||
| 664 | *@param pData (const char *) The data to prepend. | ||
| 665 | *@param nLen (long) The length of the data to prepend. | ||
| 666 | */ | ||
| 667 | void prepend( const char *pData, long nLen ); | ||
| 668 | |||
| 669 | void prepend( const char c ); | ||
| 670 | |||
| 671 | /** | ||
| 672 | * Insert pData before byte nPos, that is, the first byte of pData will | ||
| 673 | * start at nPos. This could probably be made faster by avoiding | ||
| 674 | * flattening. | ||
| 675 | */ | ||
| 676 | void insert( long nPos, const char *pData, long nLen ); | ||
| 677 | |||
| 678 | void insert( long nPos, const String &str ); | ||
| 679 | |||
| 680 | /** | ||
| 681 | *@todo This function shouldn't use strlen, we should add our own to | ||
| 682 | * this class, one that can be overridden in a specific implementation. | ||
| 683 | */ | ||
| 684 | void insert( long nPos, const char *pData ); | ||
| 685 | |||
| 686 | void remove( long nPos, long nLen ); | ||
| 687 | |||
| 688 | /** | ||
| 689 | * Clear all data from the string. | ||
| 690 | */ | ||
| 691 | void clear(); | ||
| 692 | |||
| 693 | String replace( const String &fnd, const String &rep ) const; | ||
| 694 | |||
| 695 | /** | ||
| 696 | * Force the string to resize | ||
| 697 | *@param nNewSize (long) The new size of the string. | ||
| 698 | */ | ||
| 699 | void resize( long nNewSize ); | ||
| 700 | |||
| 701 | /** | ||
| 702 | * Get the current size of the string. | ||
| 703 | *@returns (long) The current size of the string. | ||
| 704 | */ | ||
| 705 | long getSize() const; | ||
| 706 | |||
| 707 | /** | ||
| 708 | * Get a pointer to the string array. | ||
| 709 | *@returns (char *) The string data. | ||
| 710 | */ | ||
| 711 | char *getStr(); | ||
| 712 | |||
| 713 | /** | ||
| 714 | * Get a const pointer to the string array. | ||
| 715 | *@returns (const char *) The string data. | ||
| 716 | */ | ||
| 717 | const char *getStr() const; | ||
| 718 | |||
| 719 | /** | ||
| 720 | * A convinience function, this one won't cause as much work as the | ||
| 721 | * non-const getStr, so if you're not changing the data, consider it. | ||
| 722 | */ | ||
| 723 | const char *getConstStr() const; | ||
| 724 | |||
| 725 | String getSubStrIdx( long iStart, long iSize=-1 ) const; | ||
| 726 | |||
| 727 | String getSubStr( const_iterator iBegin, | ||
| 728 | const_iterator iEnd=String::const_iterator() ) const; | ||
| 729 | |||
| 730 | Bu::List<String> split( const char c ) const; | ||
| 731 | |||
| 732 | /** | ||
| 733 | * Plus equals operator for String. | ||
| 734 | *@param pData (const char *) The data to append to your String. | ||
| 735 | */ | ||
| 736 | String &operator+=( const char *pData ); | ||
| 737 | |||
| 738 | /** | ||
| 739 | * Plus equals operator for String. | ||
| 740 | *@param rSrc (const String &) The String to append to your String. | ||
| 741 | */ | ||
| 742 | String &operator+=( const String &rSrc ); | ||
| 743 | |||
| 744 | String &operator+=( const String::const_iterator &i ); | ||
| 745 | |||
| 746 | /** | ||
| 747 | * Plus equals operator for String. | ||
| 748 | *@param cData (const char) The character to append to your String. | ||
| 749 | */ | ||
| 750 | String &operator+=( const char cData ); | ||
| 751 | |||
| 752 | /** | ||
| 753 | * Assignment operator. | ||
| 754 | *@param pData (const char *) The character array to append to your | ||
| 755 | * String. | ||
| 756 | */ | ||
| 757 | String &operator=( const char *pData ); | ||
| 758 | |||
| 759 | String operator+( const String &rRight ) const; | ||
| 760 | |||
| 761 | String operator+( const char *pRight ) const; | ||
| 762 | |||
| 763 | String operator+( char *pRight ) const; | ||
| 764 | |||
| 765 | /** | ||
| 766 | * Reset your String to this character array. | ||
| 767 | *@param pData (const char *) The character array to set your String to. | ||
| 768 | */ | ||
| 769 | void set( const char *pData ); | ||
| 770 | |||
| 771 | /** | ||
| 772 | * Reset your String to this character array. | ||
| 773 | *@param pData (const char *) The character array to set your String to. | ||
| 774 | *@param nSize (long) The length of the inputted character array. | ||
| 775 | */ | ||
| 776 | void set( const char *pData, long nSize ); | ||
| 777 | |||
| 778 | void set( const char *pData, long nStart, long nSize ); | ||
| 779 | |||
| 780 | void set( const String &rData ); | ||
| 781 | |||
| 782 | void set( const String &rData, long nSize ); | ||
| 783 | |||
| 784 | void set( const String &rData, long nStart, long nSize ); | ||
| 785 | |||
| 786 | void set( const_iterator s ); | ||
| 787 | |||
| 788 | void set( const_iterator s, const_iterator e ); | ||
| 789 | |||
| 790 | /** | ||
| 791 | * Resize the string, possibly to make room for a copy. At the moment | ||
| 792 | * this operation *is* destructive. What was in the string will in no | ||
| 793 | * way be preserved. This is, however, very fast. If you want to | ||
| 794 | * keep your data check out resize. | ||
| 795 | *@param iSize the new size in bytes. The string is guranteed to have | ||
| 796 | * at least this much contiguous space available when done. | ||
| 797 | */ | ||
| 798 | void setSize( long iSize ); | ||
| 799 | |||
| 800 | /** | ||
| 801 | * Equals comparison operator. | ||
| 802 | *@param pData (const char *) The character array to compare your String | ||
| 803 | * to. | ||
| 804 | */ | ||
| 805 | bool operator==( const char *pData ) const; | ||
| 806 | |||
| 807 | /** | ||
| 808 | * Equals comparison operator. | ||
| 809 | *@param pData (const String &) The String to compare your String to. | ||
| 810 | */ | ||
| 811 | bool operator==( const String &pData ) const; | ||
| 812 | |||
| 813 | /** | ||
| 814 | * Not equals comparison operator. | ||
| 815 | *@param pData (const char *) The character array to compare your String | ||
| 816 | * to. | ||
| 817 | */ | ||
| 818 | bool operator!=(const char *pData ) const; | ||
| 819 | |||
| 820 | /** | ||
| 821 | * Not equals comparison operator. | ||
| 822 | *@param pData (const String &) The String to compare your String to. | ||
| 823 | */ | ||
| 824 | bool operator!=(const String &pData ) const; | ||
| 825 | |||
| 826 | bool operator<(const String &pData ) const; | ||
| 827 | |||
| 828 | bool operator<=(const String &pData ) const; | ||
| 829 | |||
| 830 | bool operator>(const String &pData ) const; | ||
| 831 | |||
| 832 | bool operator>=(const String &pData ) const; | ||
| 833 | |||
| 834 | /** | ||
| 835 | * Indexing operator | ||
| 836 | *@param nIndex (long) The index of the character you want. | ||
| 837 | *@returns (char &) The character at position (nIndex). | ||
| 838 | */ | ||
| 839 | char &operator[]( long nIndex ); | ||
| 840 | |||
| 841 | /** | ||
| 842 | * Const indexing operator | ||
| 843 | *@param nIndex (long) The index of the character you want. | ||
| 844 | *@returns (const char &) The character at position (nIndex). | ||
| 845 | */ | ||
| 846 | const char &operator[]( long nIndex ) const; | ||
| 847 | |||
| 848 | bool isSet() const; | ||
| 849 | |||
| 850 | bool compareSub( const char *pData, long nIndex, long nLen ) const; | ||
| 851 | |||
| 852 | bool compareSub( const String &rData, long nIndex, long nLen ) const; | ||
| 853 | |||
| 854 | /** | ||
| 855 | * Is the character at index (nIndex) white space? | ||
| 856 | *@param nIndex (long) The index of the character you want to check. | ||
| 857 | *@returns (bool) Is it white space? | ||
| 858 | */ | ||
| 859 | bool isWS( long nIndex ) const; | ||
| 860 | |||
| 861 | /** | ||
| 862 | * Is the character at index (nIndex) a letter? | ||
| 863 | *@param nIndex (long) The index of the character you want to check. | ||
| 864 | *@returns (bool) Is it a letter? | ||
| 865 | */ | ||
| 866 | bool isAlpha( long nIndex ) const; | ||
| 867 | |||
| 868 | /** | ||
| 869 | * Convert your alpha characters to lower case. | ||
| 870 | */ | ||
| 871 | String toLower() const; | ||
| 872 | |||
| 873 | /** | ||
| 874 | * Convert your alpha characters to upper case. | ||
| 875 | */ | ||
| 876 | String toUpper() const; | ||
| 877 | |||
| 878 | const_iterator find( const char cChar, | ||
| 879 | const_iterator iStart=const_iterator() ) const; | ||
| 880 | |||
| 881 | const_iterator find( const char *sText, int nLen, | ||
| 882 | const_iterator iStart=const_iterator() ) const; | ||
| 883 | |||
| 884 | const_iterator find( const String &rStr, | ||
| 885 | const_iterator iStart=const_iterator() ) const; | ||
| 886 | |||
| 887 | const_iterator find( const String &rStr, int nLen, | ||
| 888 | const_iterator iStart=const_iterator() ) const; | ||
| 889 | |||
| 890 | iterator find( const char cChar, | ||
| 891 | const_iterator iStart=const_iterator() ); | ||
| 892 | |||
| 893 | iterator find( const char *sText, int nLen, | ||
| 894 | const_iterator iStart=const_iterator() ); | ||
| 895 | |||
| 896 | iterator find( const String &rStr, | ||
| 897 | const_iterator iStart=const_iterator() ); | ||
| 898 | |||
| 899 | iterator find( const String &rStr, int nLen, | ||
| 900 | const_iterator iStart=const_iterator() ); | ||
| 901 | |||
| 902 | /** | ||
| 903 | * Find the index of the first occurrance of cChar | ||
| 904 | *@param cChar The character to search for. | ||
| 905 | *@param iStart The position in the string to start searching from. | ||
| 906 | *@returns (long) The index of the first occurrance. -1 for not found. | ||
| 907 | */ | ||
| 908 | long findIdx( const char cChar, long iStart=0 ) const; | ||
| 909 | |||
| 910 | /** | ||
| 911 | * Find the index of the first occurrance of sText | ||
| 912 | *@param sText The null-terminated string to search for. | ||
| 913 | *@param iStart The position in the string to start searching from. | ||
| 914 | *@returns The index of the first occurrance. -1 for not found. | ||
| 915 | */ | ||
| 916 | long findIdx( const char *sText, long iStart=0 ) const; | ||
| 917 | |||
| 918 | /** | ||
| 919 | * Do a reverse search for (sText) | ||
| 920 | *@param sText (const char *) The string to search for. | ||
| 921 | *@returns (long) The index of the last occurrance. -1 for not found. | ||
| 922 | */ | ||
| 923 | long rfindIdx( const char *sText ) const; | ||
| 924 | |||
| 925 | /** | ||
| 926 | * Remove nAmnt bytes from the front of the string. This function | ||
| 927 | * operates in O(n) time and should be used sparingly. | ||
| 928 | */ | ||
| 929 | void trimFront( long nAmnt ); | ||
| 930 | |||
| 931 | void trimBack( long iAmnt ); | ||
| 932 | |||
| 933 | Bu::String trimWhitespace() const; | ||
| 934 | |||
| 935 | iterator begin(); | ||
| 936 | |||
| 937 | const_iterator begin() const; | ||
| 938 | |||
| 939 | iterator end(); | ||
| 940 | |||
| 941 | const_iterator end() const; | ||
| 942 | |||
| 943 | bool isEmpty() const; | ||
| 944 | |||
| 945 | private: | ||
| 946 | void flatten() const; | ||
| 947 | bool isFlat() const; | ||
| 948 | |||
| 949 | class FormatProxy | ||
| 950 | { | ||
| 951 | public: | ||
| 952 | FormatProxy( const String &rFmt ); | ||
| 953 | virtual ~FormatProxy(); | ||
| 954 | |||
| 955 | template<typename T> | ||
| 956 | FormatProxy &arg( const T &x ) | ||
| 957 | { | ||
| 958 | lArgs.append( Arg( x ) ); | ||
| 959 | |||
| 960 | return *this; | ||
| 961 | } | ||
| 962 | |||
| 963 | template<typename T> | ||
| 964 | FormatProxy &arg( const T &x, const Bu::Fmt &f ) | ||
| 965 | { | ||
| 966 | lArgs.append( Arg( x, f ) ); | ||
| 967 | |||
| 968 | return *this; | ||
| 969 | } | ||
| 970 | |||
| 971 | operator String() const; | ||
| 972 | |||
| 973 | private: | ||
| 974 | const String &rFmt; | ||
| 975 | class Arg | ||
| 976 | { | ||
| 977 | public: | ||
| 978 | template<typename T> | ||
| 979 | Arg( const T &v ) : | ||
| 980 | value( v ) | ||
| 981 | { | ||
| 982 | } | ||
| 983 | |||
| 984 | template<typename T> | ||
| 985 | Arg( const T &v, const Bu::Fmt &f ) : | ||
| 986 | value( v ), | ||
| 987 | format( f ) | ||
| 988 | { | ||
| 989 | } | ||
| 990 | |||
| 991 | Bu::Variant value; | ||
| 992 | Bu::Fmt format; | ||
| 993 | }; | ||
| 994 | typedef Bu::List<Arg> ArgList; | ||
| 995 | ArgList lArgs; | ||
| 996 | }; | ||
| 997 | |||
| 998 | public: | ||
| 999 | template<typename ArgType> | ||
| 1000 | FormatProxy arg( const ArgType &x ) | ||
| 1001 | { | ||
| 1002 | return FormatProxy( *this ).arg( x ); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | template<typename ArgType> | ||
| 1006 | FormatProxy arg( const ArgType &x, const Bu::Fmt &f ) | ||
| 1007 | { | ||
| 1008 | return FormatProxy( *this ).arg( x, f ); | ||
| 1009 | } | ||
| 1010 | }; | ||
| 1011 | |||
| 1012 | template<class T> String operator+( const T *pLeft, const String &rRight ) | ||
| 1013 | { | ||
| 1014 | Bu::String ret( pLeft ); | ||
| 1015 | ret.append( rRight ); | ||
| 1016 | return ret; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | ArchiveBase &operator<<( ArchiveBase &ar, const String &s ); | ||
| 1020 | ArchiveBase &operator>>( ArchiveBase &ar, String &s ); | ||
| 1021 | |||
| 1022 | template<typename T> | ||
| 1023 | uint32_t __calcHashCode( const T &k ); | ||
| 1024 | |||
| 1025 | template<typename T> | ||
| 1026 | bool __cmpHashKeys( const T &a, const T &b ); | ||
| 1027 | |||
| 1028 | template<> uint32_t __calcHashCode<String>( const String &k ); | ||
| 1029 | template<> bool __cmpHashKeys<String>( | ||
| 1030 | const String &a, const String &b ); | ||
| 1031 | |||
| 1032 | template<typename t> void __tracer_format( const t &v ); | ||
| 1033 | template<> void __tracer_format<String>( const String &v ); | ||
| 1034 | |||
| 1035 | bool &operator<<( bool &dst, const String &sIn ); | ||
| 1036 | uint8_t &operator<<( uint8_t &dst, const String &sIn ); | ||
| 1037 | int8_t &operator<<( int8_t &dst, const String &sIn ); | ||
| 1038 | char &operator<<( char &dst, const String &sIn ); | ||
| 1039 | uint16_t &operator<<( uint16_t &dst, const String &sIn ); | ||
| 1040 | int16_t &operator<<( int16_t &dst, const String &sIn ); | ||
| 1041 | uint32_t &operator<<( uint32_t &dst, const String &sIn ); | ||
| 1042 | int32_t &operator<<( int32_t &dst, const String &sIn ); | ||
| 1043 | uint64_t &operator<<( uint64_t &dst, const String &sIn ); | ||
| 1044 | int64_t &operator<<( int64_t &dst, const String &sIn ); | ||
| 1045 | float &operator<<( float &dst, const String &sIn ); | ||
| 1046 | double &operator<<( double &dst, const String &sIn ); | ||
| 1047 | long double &operator<<( long double &dst, const String &sIn ); | ||
| 1048 | Bu::String &operator<<( Bu::String &dst, const String &sIn ); | ||
| 1049 | |||
| 1050 | typedef Bu::List<String> StringList; | ||
| 1051 | }; | ||
| 1052 | |||
| 1053 | #endif | ||
