summaryrefslogtreecommitdiff
path: root/src/fstring.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/fstring.h')
-rw-r--r--src/fstring.h173
1 files changed, 13 insertions, 160 deletions
diff --git a/src/fstring.h b/src/fstring.h
index 65410af..be88ec0 100644
--- a/src/fstring.h
+++ b/src/fstring.h
@@ -49,7 +49,6 @@ namespace Bu
49 public: 49 public:
50 FBasicString() : 50 FBasicString() :
51 nLength( 0 ), 51 nLength( 0 ),
52 pnRefs( NULL ),
53 pFirst( NULL ), 52 pFirst( NULL ),
54 pLast( NULL ) 53 pLast( NULL )
55 { 54 {
@@ -57,7 +56,6 @@ namespace Bu
57 56
58 FBasicString( const chr *pData ) : 57 FBasicString( const chr *pData ) :
59 nLength( 0 ), 58 nLength( 0 ),
60 pnRefs( NULL ),
61 pFirst( NULL ), 59 pFirst( NULL ),
62 pLast( NULL ) 60 pLast( NULL )
63 { 61 {
@@ -66,7 +64,6 @@ namespace Bu
66 64
67 FBasicString( const chr *pData, long nLength ) : 65 FBasicString( const chr *pData, long nLength ) :
68 nLength( 0 ), 66 nLength( 0 ),
69 pnRefs( NULL ),
70 pFirst( NULL ), 67 pFirst( NULL ),
71 pLast( NULL ) 68 pLast( NULL )
72 { 69 {
@@ -75,21 +72,15 @@ namespace Bu
75 72
76 FBasicString( const MyType &rSrc ) : 73 FBasicString( const MyType &rSrc ) :
77 nLength( 0 ), 74 nLength( 0 ),
78 pnRefs( NULL ),
79 pFirst( NULL ), 75 pFirst( NULL ),
80 pLast( NULL ) 76 pLast( NULL )
81 { 77 {
82 // Here we have no choice but to copy, since the other guy is a const. 78 rSrc.flatten();
83 // In the case that the source were flat, we could get a reference, it 79 append( rSrc.pFirst->pData, rSrc.nLength );
84 // would make some things faster, but not matter in many other cases.
85
86 joinShare( rSrc );
87 //copyFrom( rSrc );
88 } 80 }
89 81
90 FBasicString( const MyType &rSrc, long nLength ) : 82 FBasicString( const MyType &rSrc, long nLength ) :
91 nLength( 0 ), 83 nLength( 0 ),
92 pnRefs( NULL ),
93 pFirst( NULL ), 84 pFirst( NULL ),
94 pLast( NULL ) 85 pLast( NULL )
95 { 86 {
@@ -98,7 +89,6 @@ namespace Bu
98 89
99 FBasicString( const MyType &rSrc, long nStart, long nLength ) : 90 FBasicString( const MyType &rSrc, long nStart, long nLength ) :
100 nLength( 0 ), 91 nLength( 0 ),
101 pnRefs( NULL ),
102 pFirst( NULL ), 92 pFirst( NULL ),
103 pLast( NULL ) 93 pLast( NULL )
104 { 94 {
@@ -107,7 +97,6 @@ namespace Bu
107 97
108 FBasicString( long nSize ) : 98 FBasicString( long nSize ) :
109 nLength( nSize ), 99 nLength( nSize ),
110 pnRefs( NULL ),
111 pFirst( NULL ), 100 pFirst( NULL ),
112 pLast( NULL ) 101 pLast( NULL )
113 { 102 {
@@ -383,15 +372,7 @@ namespace Bu
383 */ 372 */
384 MyType &operator =( const MyType &rSrc ) 373 MyType &operator =( const MyType &rSrc )
385 { 374 {
386 //if( rSrc.isFlat() ) 375 copyFrom( rSrc );
387 //{
388 joinShare( rSrc );
389 //}
390 //else
391 //{
392 // copyFrom( rSrc );
393 //}
394 //
395 376
396 return (*this); 377 return (*this);
397 } 378 }
@@ -538,7 +519,6 @@ namespace Bu
538 void toLower() 519 void toLower()
539 { 520 {
540 flatten(); 521 flatten();
541 unShare();
542 522
543 for( long j = 0; j < nLength; j++ ) 523 for( long j = 0; j < nLength; j++ )
544 { 524 {
@@ -553,7 +533,6 @@ namespace Bu
553 void toUpper() 533 void toUpper()
554 { 534 {
555 flatten(); 535 flatten();
556 unShare();
557 536
558 for( long j = 0; j < nLength; j++ ) 537 for( long j = 0; j < nLength; j++ )
559 { 538 {
@@ -648,8 +627,6 @@ namespace Bu
648 if( pFirst == NULL ) 627 if( pFirst == NULL )
649 return; 628 return;
650 629
651 unShare();
652
653 Chunk *pNew = newChunk( nLength ); 630 Chunk *pNew = newChunk( nLength );
654 chr *pos = pNew->pData; 631 chr *pos = pNew->pData;
655 Chunk *i = pFirst; 632 Chunk *i = pFirst;
@@ -672,25 +649,18 @@ namespace Bu
672 if( pFirst == NULL ) 649 if( pFirst == NULL )
673 return; 650 return;
674 651
675 if( isShared() ) 652 Chunk *i = pFirst;
676 { 653 for(;;)
677 decRefs();
678 }
679 else
680 { 654 {
681 Chunk *i = pFirst; 655 Chunk *n = i->pNext;
682 for(;;) 656 aChr.deallocate( i->pData, i->nLength+1 );
683 { 657 aChunk.deallocate( i, 1 );
684 Chunk *n = i->pNext; 658 if( n == NULL )
685 aChr.deallocate( i->pData, i->nLength+1 ); 659 break;
686 aChunk.deallocate( i, 1 ); 660 i = n;
687 if( n == NULL )
688 break;
689 i = n;
690 }
691 pFirst = pLast = NULL;
692 nLength = 0;
693 } 661 }
662 pFirst = pLast = NULL;
663 nLength = 0;
694 } 664 }
695 665
696 void copyFrom( const FBasicString<chr, nMinSize, chralloc, chunkalloc> &rSrc ) 666 void copyFrom( const FBasicString<chr, nMinSize, chralloc, chunkalloc> &rSrc )
@@ -698,8 +668,6 @@ namespace Bu
698 if( rSrc.pFirst == NULL ) 668 if( rSrc.pFirst == NULL )
699 return; 669 return;
700 670
701 decRefs();
702
703 Chunk *pNew = newChunk( rSrc.nLength ); 671 Chunk *pNew = newChunk( rSrc.nLength );
704 chr *pos = pNew->pData; 672 chr *pos = pNew->pData;
705 Chunk *i = rSrc.pFirst; 673 Chunk *i = rSrc.pFirst;
@@ -721,11 +689,6 @@ namespace Bu
721 return (pFirst == pLast); 689 return (pFirst == pLast);
722 } 690 }
723 691
724 bool isShared() const
725 {
726 return (pnRefs != NULL);
727 }
728
729 Chunk *newChunk() const 692 Chunk *newChunk() const
730 { 693 {
731 Chunk *pNew = aChunk.allocate( 1 ); 694 Chunk *pNew = aChunk.allocate( 1 );
@@ -745,8 +708,6 @@ namespace Bu
745 708
746 void appendChunk( Chunk *pNewChunk ) 709 void appendChunk( Chunk *pNewChunk )
747 { 710 {
748 unShare();
749
750 if( pFirst == NULL ) 711 if( pFirst == NULL )
751 pLast = pFirst = pNewChunk; 712 pLast = pFirst = pNewChunk;
752 else 713 else
@@ -760,8 +721,6 @@ namespace Bu
760 721
761 void prependChunk( Chunk *pNewChunk ) 722 void prependChunk( Chunk *pNewChunk )
762 { 723 {
763 unShare();
764
765 if( pFirst == NULL ) 724 if( pFirst == NULL )
766 pLast = pFirst = pNewChunk; 725 pLast = pFirst = pNewChunk;
767 else 726 else
@@ -773,102 +732,6 @@ namespace Bu
773 nLength += pNewChunk->nLength; 732 nLength += pNewChunk->nLength;
774 } 733 }
775 734
776 void joinShare( MyType &rSrc )
777 {
778 clear();
779
780 if( !rSrc.isFlat() )
781 rSrc.flatten();
782
783 rSrc.initCount();
784 pnRefs = rSrc.pnRefs;
785 (*pnRefs)++;
786 nLength = rSrc.nLength;
787 pFirst = rSrc.pFirst;
788 pLast = rSrc.pLast;
789 }
790
791 void joinShare( const MyType &rSrc )
792 {
793 clear();
794
795 rSrc.flatten();
796
797 if( !rSrc.isShared() )
798 {
799 rSrc.pnRefs = new uint32_t;
800 (*rSrc.pnRefs) = 1;
801 }
802 pnRefs = rSrc.pnRefs;
803 (*pnRefs)++;
804 nLength = rSrc.nLength;
805 pFirst = rSrc.pFirst;
806 pLast = rSrc.pLast;
807 }
808
809 /**
810 * This takes an object that was shared and makes a copy of the base data
811 * that was being shared so that this copy can be changed. This should be
812 * added before any call that will change this object;
813 */
814 void unShare() const
815 {
816 if( isShared() == false )
817 return;
818 if( pFirst == NULL )
819 return;
820
821 Chunk *pNew = newChunk( nLength );
822 chr *pos = pNew->pData;
823 Chunk *i = pFirst;
824 for(;;)
825 {
826 cpy( pos, i->pData, i->nLength );
827 pos += i->nLength;
828 i = i->pNext;
829 if( i == NULL )
830 break;
831 }
832 decRefs();
833 pLast = pFirst = pNew;
834 nLength = pNew->nLength;
835 }
836
837 /**
838 * This decrements our ref count and pulls us out of the share. If the ref
839 * count hits zero because of this, it destroys the share. This is not
840 * safe to call on it's own, it's much better to call unShare.
841 */
842 void decRefs() const
843 {
844 if( isShared() )
845 {
846 (*pnRefs)--;
847 if( (*pnRefs) == 0 )
848 destroyShare();
849 else
850 {
851 pnRefs = NULL;
852 pFirst = NULL;
853 pLast = NULL;
854 nLength = 0;
855 }
856 }
857 }
858
859 /**
860 * While the unShare function removes an instance from a share, this
861 * function destroys the data that was in the share, removing the share
862 * itself. This should only be called when the refcount for the share has
863 * or is about to reach zero.
864 */
865 void destroyShare() const
866 {
867 delete pnRefs;
868 pnRefs = NULL;
869 realClear();
870 }
871
872#ifdef VALTEST 735#ifdef VALTEST
873 void cpy( chr *dest, const chr *src, long count ) const 736 void cpy( chr *dest, const chr *src, long count ) const
874 { 737 {
@@ -881,18 +744,8 @@ namespace Bu
881 } 744 }
882#endif 745#endif
883 746
884 void initCount() const
885 {
886 if( !isShared() )
887 {
888 pnRefs = new uint32_t;
889 (*pnRefs) = 1;
890 }
891 }
892
893 private: 747 private:
894 mutable long nLength; 748 mutable long nLength;
895 mutable uint32_t *pnRefs;
896 mutable Chunk *pFirst; 749 mutable Chunk *pFirst;
897 mutable Chunk *pLast; 750 mutable Chunk *pLast;
898 751