summaryrefslogtreecommitdiff
path: root/src/fbasicstring.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/fbasicstring.h')
-rw-r--r--src/fbasicstring.h720
1 files changed, 673 insertions, 47 deletions
diff --git a/src/fbasicstring.h b/src/fbasicstring.h
index 669784b..8303b5a 100644
--- a/src/fbasicstring.h
+++ b/src/fbasicstring.h
@@ -122,6 +122,481 @@ namespace Bu
122 { 122 {
123 pFirst = pLast = newChunk( nSize ); 123 pFirst = pLast = newChunk( nSize );
124 } 124 }
125
126 struct iterator;
127 typedef struct const_iterator
128 {
129 friend class FBasicString<chr, nMinSize, chralloc, chunkalloc>;
130 private:
131 const_iterator( Chunk *pChunk, int iPos ) :
132 pChunk( pChunk ),
133 iPos( iPos )
134 {
135 }
136
137 Chunk *pChunk;
138 int iPos;
139
140 public:
141 const_iterator( const const_iterator &i ) :
142 pChunk( i.pChunk ),
143 iPos( i.iPos )
144 {
145 }
146
147 const_iterator( const iterator &i ) :
148 pChunk( i.pChunk ),
149 iPos( i.iPos )
150 {
151 }
152
153 bool operator==( const const_iterator &i ) const
154 {
155 return pChunk == i.pChunk && iPos == i.iPos;
156 }
157
158 bool operator!=( const const_iterator &i ) const
159 {
160 return !(*this == i);
161 }
162
163 const_iterator &operator=( const const_iterator &i )
164 {
165 pChunk = i.pChunk;
166 iPos = i.iPos;
167 return *this;
168 }
169
170 const_iterator &operator++()
171 {
172 if( !pChunk ) return *this;
173 iPos++;
174 if( iPos >= pChunk->nLength )
175 {
176 iPos = 0;
177 pChunk = pChunk->pNext;
178 }
179 return *this;
180 }
181
182 const_iterator &operator++( int )
183 {
184 if( !pChunk ) return *this;
185 iPos++;
186 if( iPos >= pChunk->nLength )
187 {
188 iPos = 0;
189 pChunk = pChunk->pNext;
190 }
191 return *this;
192 }
193
194 const_iterator &operator+=( int iAmnt )
195 {
196 if( !pChunk ) return *this;
197 iPos += iAmnt;
198 while( iPos >= pChunk->nLength )
199 {
200 iPos -= pChunk->nLength;
201 pChunk = pChunk->pNext;
202 if( pChunk == NULL )
203 break;
204 }
205 return *this;
206 }
207
208 const_iterator operator+( int iAmnt ) const
209 {
210 if( !pChunk ) return *this;
211 const_iterator ret( *this );
212 ret += iAmnt;
213 return ret;
214 }
215
216 const chr &operator *() const
217 {
218 if( !pChunk ) throw Bu::ExceptionBase("Not a valid const_iterator.");
219 return pChunk->pData[iPos];
220 }
221
222 bool operator==( const chr &c ) const
223 {
224 if( !pChunk ) return false;
225 return pChunk->pData[iPos] == c;
226 }
227
228 operator bool() const
229 {
230 return pChunk != NULL;
231 }
232
233 bool isValid() const
234 {
235 return pChunk != NULL;
236 }
237
238 bool compare( const const_iterator &c ) const
239 {
240 const_iterator a = *this;
241 const_iterator b = c;
242 if( a == b )
243 return true;
244 for(; a && b; a++, b++ )
245 {
246 if( *a != *b )
247 return false;
248 }
249 return true;
250 }
251
252 bool compare( const const_iterator &c, int nLen ) const
253 {
254 const_iterator a = *this;
255 const_iterator b = c;
256 if( a == b )
257 return true;
258 for(int j = 0; a && b && j < nLen; a++, b++, j++ )
259 {
260 if( *a != *b )
261 return false;
262 }
263 return true;
264 }
265
266 bool compare( const chr *c ) const
267 {
268 if( !pChunk ) return false;
269 const_iterator a = *this;
270 for(; a && *c; a++, c++ )
271 {
272 if( *a != *c )
273 return false;
274 }
275 if( a.isValid() != (*c!=(chr)0) )
276 return false;
277 return true;
278 }
279
280 bool compare( const chr *c, int nLen ) const
281 {
282 if( !pChunk ) return false;
283 const_iterator a = *this;
284 int j = 0;
285 for(; a && j < nLen; a++, c++, j++ )
286 {
287 if( *a != *c )
288 return false;
289 }
290 if( j < nLen )
291 return false;
292 return true;
293 }
294
295 bool compare( const MyType &s ) const
296 {
297 if( !pChunk ) return false;
298 return compare( s.begin() );
299 }
300
301 bool compare( const MyType &s, int nLen ) const
302 {
303 if( !pChunk ) return false;
304 return compare( s.begin(), nLen );
305 }
306
307 const_iterator find( const chr c ) const
308 {
309 for( const_iterator i = *this; i; i++ )
310 {
311 if( *i == c )
312 return i;
313 }
314 return const_iterator( NULL, 0 );
315 }
316
317 const_iterator find( const chr *pStr, int nLen ) const
318 {
319 for( const_iterator i = *this; i; i++ )
320 {
321 if( i.compare( pStr, nLen ) )
322 return i;
323 }
324 return const_iterator( NULL, 0 );
325 }
326
327 const_iterator find( const MyType &s ) const
328 {
329 for( const_iterator i = *this; i; i++ )
330 {
331 if( i.compare( s ) )
332 return i;
333 }
334 return const_iterator( NULL, 0 );
335 }
336
337 const_iterator find( const MyType &s, int nLen ) const
338 {
339 for( const_iterator i = *this; i; i++ )
340 {
341 if( i.compare( s, nLen ) )
342 return i;
343 }
344 return const_iterator( NULL, 0 );
345 }
346 } const_iterator;
347
348 typedef struct iterator
349 {
350 friend class FBasicString<chr, nMinSize, chralloc, chunkalloc>;
351 private:
352 iterator( Chunk *pChunk, int iPos ) :
353 pChunk( pChunk ),
354 iPos( iPos )
355 {
356 }
357
358 Chunk *pChunk;
359 int iPos;
360
361 public:
362 iterator( const iterator &i ) :
363 pChunk( i.pChunk ),
364 iPos( i.iPos )
365 {
366 }
367
368 operator const_iterator() const
369 {
370 return const_iterator( pChunk, iPos );
371 }
372
373 bool operator==( const iterator &i ) const
374 {
375 return pChunk == i.pChunk && iPos == i.iPos;
376 }
377
378 bool operator!=( const iterator &i ) const
379 {
380 return !(*this == i);
381 }
382
383 iterator &operator=( const iterator &i )
384 {
385 pChunk = i.pChunk;
386 iPos = i.iPos;
387 return *this;
388 }
389
390 iterator &operator++()
391 {
392 if( !pChunk ) return *this;
393 iPos++;
394 if( iPos >= pChunk->nLength )
395 {
396 iPos = 0;
397 pChunk = pChunk->pNext;
398 }
399 return *this;
400 }
401
402 iterator &operator++( int )
403 {
404 if( !pChunk ) return *this;
405 iPos++;
406 if( iPos >= pChunk->nLength )
407 {
408 iPos = 0;
409 pChunk = pChunk->pNext;
410 }
411 return *this;
412 }
413
414 iterator &operator+=( int iAmnt )
415 {
416 if( !pChunk ) return *this;
417 iPos += iAmnt;
418 while( iPos >= pChunk->nLength )
419 {
420 iPos -= pChunk->nLength;
421 pChunk = pChunk->pNext;
422 if( pChunk == NULL )
423 break;
424 }
425 return *this;
426 }
427
428 iterator operator+( int iAmnt ) const
429 {
430 if( !pChunk ) return *this;
431 iterator ret( *this );
432 ret += iAmnt;
433 return ret;
434 }
435
436 chr &operator*()
437 {
438 if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator.");
439 return pChunk->pData[iPos];
440 }
441
442 const chr &operator*() const
443 {
444 if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator.");
445 return pChunk->pData[iPos];
446 }
447
448 bool operator==( const chr &c ) const
449 {
450 if( !pChunk ) return false;
451 return pChunk->pData[iPos] == c;
452 }
453
454 iterator &operator=( const chr &c )
455 {
456 if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator.");
457 pChunk->pData[iPos] = c;
458 return *this;
459 }
460
461 operator bool() const
462 {
463 return pChunk != NULL;
464 }
465
466 bool isValid() const
467 {
468 return pChunk != NULL;
469 }
470
471 bool compare( const iterator &c ) const
472 {
473 iterator a = *this;
474 iterator b = c;
475 if( a == b )
476 return true;
477 for(; a && b; a++, b++ )
478 {
479 if( *a != *b )
480 return false;
481 }
482 return true;
483 }
484
485 bool compare( const iterator &c, int nLen ) const
486 {
487 iterator a = *this;
488 iterator b = c;
489 if( a == b )
490 return true;
491 for(int j = 0; a && b && j < nLen; a++, b++, j++ )
492 {
493 if( *a != *b )
494 return false;
495 }
496 return true;
497 }
498
499 bool compare( const chr *c ) const
500 {
501 if( !pChunk ) return false;
502 iterator a = *this;
503 for(; a && *c; a++, c++ )
504 {
505 if( *a != *c )
506 return false;
507 }
508 if( a.isValid() != (*c!=(chr)0) )
509 return false;
510 return true;
511 }
512
513 bool compare( const chr *c, int nLen ) const
514 {
515 if( !pChunk ) return false;
516 iterator a = *this;
517 int j = 0;
518 for(; a && j < nLen; a++, c++, j++ )
519 {
520 if( *a != *c )
521 return false;
522 }
523 if( j < nLen )
524 return false;
525 return true;
526 }
527
528 bool compare( const MyType &s ) const
529 {
530 if( !pChunk ) return false;
531 return compare( s.begin() );
532 }
533
534 bool compare( const MyType &s, int nLen ) const
535 {
536 if( !pChunk ) return false;
537 return compare( s.begin(), nLen );
538 }
539
540 iterator find( const chr c ) const
541 {
542 for( iterator i = *this; i; i++ )
543 {
544 if( *i == c )
545 return i;
546 }
547 return iterator( NULL, 0 );
548 }
549
550 iterator find( const chr *pStr, int nLen ) const
551 {
552 for( iterator i = *this; i; i++ )
553 {
554 if( i.compare( pStr, nLen ) )
555 return i;
556 }
557 return iterator( NULL, 0 );
558 }
559
560 iterator find( const MyType &s ) const
561 {
562 for( iterator i = *this; i; i++ )
563 {
564 if( i.compare( s ) )
565 return i;
566 }
567 return iterator( NULL, 0 );
568 }
569
570 iterator find( const MyType &s, int nLen ) const
571 {
572 for( iterator i = *this; i; i++ )
573 {
574 if( i.compare( s, nLen ) )
575 return i;
576 }
577 return iterator( NULL, 0 );
578 }
579 } iterator;
580
581 //typedef chr *iterator;
582// typedef const chr *const_iterator;
583 // typedef iterator const_iterator;
584
585 FBasicString( const const_iterator &s ) :
586 nLength( 0 ),
587 pFirst( NULL ),
588 pLast( NULL )
589 {
590 append( s );
591 }
592
593 FBasicString( const const_iterator &s, const const_iterator &e ) :
594 nLength( 0 ),
595 pFirst( NULL ),
596 pLast( NULL )
597 {
598 append( s, e );
599 }
125 600
126 virtual ~FBasicString() 601 virtual ~FBasicString()
127 { 602 {
@@ -129,10 +604,6 @@ namespace Bu
129 } 604 }
130 605
131 /** 606 /**
132 *@todo void append( const MyType & sData )
133 */
134
135 /**
136 * Append data to your string. 607 * Append data to your string.
137 *@param pData (const chr *) The data to append. 608 *@param pData (const chr *) The data to append.
138 */ 609 */
@@ -205,6 +676,74 @@ namespace Bu
205 } 676 }
206 677
207 /** 678 /**
679 * Append another FString to this one.
680 *@param sData (MyType &) The FString to append.
681 *@param nLen How much data to append.
682 */
683 void append( const MyType & sData, long nStart, long nLen )
684 {
685 if( nLen < 0 )
686 nLen = sData.getSize() - nStart;
687 append( sData.getStr(), nStart, nLen );
688 }
689
690 void append( const const_iterator &s )
691 {
692 if( !s.isValid() )
693 return;
694 Chunk *pSrc = s.pChunk;
695
696 Chunk *pNew = newChunk( pSrc->nLength-s.iPos );
697 cpy( pNew->pData, pSrc->pData+s.iPos, pSrc->nLength-s.iPos );
698 appendChunk( pNew );
699
700 while( (pSrc = pSrc->pNext) )
701 {
702 appendChunk( copyChunk( pSrc ) );
703 }
704 }
705
706 void append( const iterator &s ) // I get complainst without this one
707 {
708 append( const_iterator( s ) );
709 }
710
711 void append( const const_iterator &s, const const_iterator &e )
712 {
713 if( !s.isValid() )
714 return;
715 if( !e.isValid() )
716 {
717 append( s );
718 return;
719 }
720 if( s.pChunk == e.pChunk )
721 {
722 // Simple case, they're the same chunk
723 Chunk *pNew = newChunk( e.iPos-s.iPos );
724 cpy( pNew->pData, s.pChunk->pData+s.iPos, e.iPos-s.iPos );
725 appendChunk( pNew );
726 }
727 else
728 {
729 // A little trickier, scan the blocks...
730 Chunk *pSrc = s.pChunk;
731 Chunk *pNew = newChunk( pSrc->nLength-s.iPos );
732 cpy( pNew->pData, pSrc->pData+s.iPos, pSrc->nLength-s.iPos );
733 appendChunk( pNew );
734
735 while( (pSrc = pSrc->pNext) != e.pChunk )
736 {
737 appendChunk( copyChunk( pSrc ) );
738 }
739
740 pNew = newChunk( e.iPos );
741 cpy( pNew->pData, pSrc->pData, e.iPos );
742 appendChunk( pNew );
743 }
744 }
745
746 /**
208 * Prepend another FString to this one. 747 * Prepend another FString to this one.
209 *@param sData (MyType &) The FString to prepend. 748 *@param sData (MyType &) The FString to prepend.
210 */ 749 */
@@ -549,6 +1088,42 @@ namespace Bu
549 append( pData, nSize ); 1088 append( pData, nSize );
550 } 1089 }
551 1090
1091 void set( const chr *pData, long nStart, long nSize )
1092 {
1093 clear();
1094 append( pData, nStart, nSize );
1095 }
1096
1097 void set( const MyType &rData )
1098 {
1099 clear();
1100 append( rData );
1101 }
1102
1103 void set( const MyType &rData, long nSize )
1104 {
1105 clear();
1106 append( rData, nSize );
1107 }
1108
1109 void set( const MyType &rData, long nStart, long nSize )
1110 {
1111 clear();
1112 append( rData, nStart, nSize );
1113 }
1114
1115 void set( const_iterator s )
1116 {
1117 clear();
1118 append( s );
1119 }
1120
1121 void set( const_iterator s, const_iterator e )
1122 {
1123 clear();
1124 append( s, e );
1125 }
1126
552 void expand() 1127 void expand()
553 { 1128 {
554 flatten(); 1129 flatten();
@@ -704,6 +1279,55 @@ namespace Bu
704 return (pFirst != NULL); 1279 return (pFirst != NULL);
705 } 1280 }
706 1281
1282 bool compareSub( const chr *pData, long nIndex, long nLen )
1283 {
1284 if( pFirst == NULL ) {
1285 if( pData == NULL )
1286 return true;
1287 if( pData[0] == (chr)0 )
1288 return true;
1289 return false;
1290 }
1291 if( nIndex+nLen > nLength )
1292 return false;
1293
1294 flatten();
1295 pFirst->pData[nLength] = (chr)0;
1296 const chr *a = pData;
1297 chr *b = pFirst->pData+nIndex;
1298 for( long j = 0; j < nLen; j++, a++, b++ )
1299 {
1300 if( *a != *b )
1301 return false;
1302 if( *a == (chr)0 && j < nLength )
1303 return false;
1304 }
1305
1306 return true;
1307 }
1308
1309 bool compareSub( const MyType &rData, long nIndex, long nLen )
1310 {
1311 if( pFirst == NULL || rData.pFirst == NULL )
1312 return false;
1313 if( nLen < 0 )
1314 nLen = rData.nLength;
1315 if( nIndex+nLen > nLength )
1316 return false;
1317
1318 flatten();
1319 rData.flatten();
1320 const chr *a = rData.pFirst->pData;
1321 chr *b = pFirst->pData + nIndex;
1322 for( long j = 0; j < nLen; j++, a++, b++ )
1323 {
1324 if( *a != *b )
1325 return false;
1326 }
1327
1328 return true;
1329 }
1330
707 /** 1331 /**
708 * Is the character at index (nIndex) white space? 1332 * Is the character at index (nIndex) white space?
709 *@param nIndex (long) The index of the character you want to check. 1333 *@param nIndex (long) The index of the character you want to check.
@@ -758,45 +1382,56 @@ namespace Bu
758 } 1382 }
759 } 1383 }
760 1384
761 /** 1385 const_iterator find( const chr cChar,
762 * Find the index of the first occurrance of (sText) 1386 const_iterator iStart=begin() ) const
763 *@param sText (const chr *) The string to search for.
764 *@returns (long) The index of the first occurrance. -1 for not found.
765 */
766 long find( const chr cChar ) const
767 { 1387 {
768 flatten(); 1388 for( ; iStart; iStart++ )
769 for( long j = 0; j < pFirst->nLength; j++ )
770 { 1389 {
771 if( pFirst->pData[j] == cChar ) 1390 if( cChar == *iStart )
772 return j; 1391 return iStart;
773 } 1392 }
774 return -1; 1393 return end();
775 } 1394 }
776 1395
777 /** 1396 const_iterator find( const chr *sText, int nLen,
778 * Find the index of the first occurrance of cChar 1397 const_iterator iStart=begin() ) const
779 *@param cChar (const chr) The character to search for.
780 *@returns (long) The index of the first occurrance. -1 for not found.
781 */
782 long find( const chr *sText ) const
783 { 1398 {
784 long nTLen = strlen( sText ); 1399 for( ; iStart; iStart++ )
785 flatten();
786 for( long j = 0; j < pFirst->nLength-nTLen; j++ )
787 { 1400 {
788 if( !strncmp( sText, pFirst->pData+j, nTLen ) ) 1401 if( iStart.compare( sText, nLen ) )
789 return j; 1402 return iStart;
790 } 1403 }
791 return -1; 1404 return end();
792 } 1405 }
793 1406
1407 const_iterator find( const MyType &rStr,
1408 const_iterator iStart=begin() ) const
1409 {
1410 for( ; iStart; iStart++ )
1411 {
1412 if( iStart.compare( rStr ) )
1413 return iStart;
1414 }
1415 return end();
1416 }
1417
1418 const_iterator find( const MyType &rStr, int nLen,
1419 const_iterator iStart=begin() ) const
1420 {
1421 for( ; iStart; iStart++ )
1422 {
1423 if( iStart.compare( rStr, nLen ) )
1424 return iStart;
1425 }
1426 return end();
1427 }
1428
794 /** 1429 /**
795 * Find the index of the first occurrance of cChar 1430 * Find the index of the first occurrance of cChar
796 *@param sText (const chr *) The string to search for. 1431 *@param sText (const chr *) The string to search for.
797 *@returns (long) The index of the first occurrance. -1 for not found. 1432 *@returns (long) The index of the first occurrance. -1 for not found.
798 */ 1433 */
799 long find( long iStart, const chr cChar ) const 1434 long findIdx( const chr cChar, long iStart=0 ) const
800 { 1435 {
801 flatten(); 1436 flatten();
802 for( long j = iStart; j < pFirst->nLength; j++ ) 1437 for( long j = iStart; j < pFirst->nLength; j++ )
@@ -812,7 +1447,7 @@ namespace Bu
812 *@param cChar (const chr) The character to search for. 1447 *@param cChar (const chr) The character to search for.
813 *@returns (long) The index of the first occurrance. -1 for not found. 1448 *@returns (long) The index of the first occurrance. -1 for not found.
814 */ 1449 */
815 long find( long iStart, const chr *sText ) const 1450 long findIdx( const chr *sText, long iStart=0 ) const
816 { 1451 {
817 long nTLen = strlen( sText ); 1452 long nTLen = strlen( sText );
818 flatten(); 1453 flatten();
@@ -829,7 +1464,7 @@ namespace Bu
829 *@param sText (const chr *) The string to search for. 1464 *@param sText (const chr *) The string to search for.
830 *@returns (long) The index of the last occurrance. -1 for not found. 1465 *@returns (long) The index of the last occurrance. -1 for not found.
831 */ 1466 */
832 long rfind( const chr *sText ) const 1467 long rfindIdx( const chr *sText ) const
833 { 1468 {
834 long nTLen = strlen( sText ); 1469 long nTLen = strlen( sText );
835 flatten(); 1470 flatten();
@@ -928,37 +1563,28 @@ namespace Bu
928 } 1563 }
929 } 1564 }
930 1565
931 typedef chr *iterator;
932 typedef const chr *const_iterator;
933
934 iterator begin() 1566 iterator begin()
935 { 1567 {
936 if( nLength == 0 ) 1568 if( nLength == 0 )
937 return NULL; 1569 return iterator( NULL, 0 );
938 flatten(); 1570 return iterator( pFirst, 0 );
939 return pFirst->pData;
940 } 1571 }
941 1572
942 const_iterator begin() const 1573 const_iterator begin() const
943 { 1574 {
944 if( nLength == 0 ) 1575 if( nLength == 0 )
945 return NULL; 1576 return const_iterator( NULL, 0 );
946 flatten(); 1577 return iterator( pFirst, 0 );
947 return pFirst->pData;
948 } 1578 }
949 1579
950 iterator end() 1580 iterator end()
951 { 1581 {
952 if( nLength == 0 ) 1582 return iterator( NULL, 0 );
953 return NULL;
954 return pFirst->pData+pFirst->nLength;
955 } 1583 }
956 1584
957 const_iterator end() const 1585 const_iterator end() const
958 { 1586 {
959 if( nLength == 0 ) 1587 return const_iterator( NULL, 0 );
960 return NULL;
961 return pFirst->pData+pFirst->nLength;
962 } 1588 }
963 1589
964 bool isEmpty() const 1590 bool isEmpty() const