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 | ||