aboutsummaryrefslogtreecommitdiff
path: root/src/fbasicstring.h
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2009-02-08 00:44:10 +0000
committerMike Buland <eichlan@xagasoft.com>2009-02-08 00:44:10 +0000
commit366a8063730aa7ae696bcb9cf56eafd13d43dfc0 (patch)
tree42e3597edfde0c183506ad0d452f045cb7726137 /src/fbasicstring.h
parent4f59dec6bad120b72f1bc075715d79bfbe881f7e (diff)
downloadlibbu++-366a8063730aa7ae696bcb9cf56eafd13d43dfc0.tar.gz
libbu++-366a8063730aa7ae696bcb9cf56eafd13d43dfc0.tar.bz2
libbu++-366a8063730aa7ae696bcb9cf56eafd13d43dfc0.tar.xz
libbu++-366a8063730aa7ae696bcb9cf56eafd13d43dfc0.zip
So many updates. I recommend using the new FString iterators instead of direct
indexing. It is now many times faster, and requires less overhead. Also, more stuff iterator related in every class. More on that later.
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