diff options
Diffstat (limited to '')
-rw-r--r-- | src/fbasicstring.h | 241 |
1 files changed, 132 insertions, 109 deletions
diff --git a/src/fbasicstring.h b/src/fbasicstring.h index 4c33479..064ff16 100644 --- a/src/fbasicstring.h +++ b/src/fbasicstring.h | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | namespace Bu | 26 | namespace Bu |
27 | { | 27 | { |
28 | /** @cond DEVEL */ | ||
28 | template< typename chr > | 29 | template< typename chr > |
29 | struct FStringChunk | 30 | struct FStringChunk |
30 | { | 31 | { |
@@ -34,10 +35,55 @@ namespace Bu | |||
34 | }; | 35 | }; |
35 | 36 | ||
36 | #define cpy( dest, src, size ) Bu::memcpy( dest, src, size*sizeof(chr) ) | 37 | #define cpy( dest, src, size ) Bu::memcpy( dest, src, size*sizeof(chr) ) |
38 | |||
39 | template< typename chr, int nMinSize, typename chralloc, | ||
40 | typename chunkalloc> class FBasicString; | ||
41 | |||
42 | template<typename chr> | ||
43 | size_t strlen( const chr *pData ) | ||
44 | { | ||
45 | for( size_t tLen = 0;; ++tLen ) | ||
46 | { | ||
47 | if( pData[tLen] == (chr)0 ) | ||
48 | return tLen; | ||
49 | } | ||
50 | return -1; | ||
51 | } | ||
52 | |||
53 | template<char> | ||
54 | size_t strlen( const char *pData ) | ||
55 | { | ||
56 | return ::strlen( pData ); | ||
57 | } | ||
58 | |||
59 | template<typename chr> | ||
60 | int strncmp( const chr *a, const chr *b, size_t iLen ) | ||
61 | { | ||
62 | for( size_t iPos = 0; iPos < iLen; iPos++ ) | ||
63 | { | ||
64 | if( a[iPos] != b[iPos] ) | ||
65 | { | ||
66 | return a[iPos]-b[iPos]; | ||
67 | } | ||
68 | } | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | template<char> | ||
73 | int strncmp( const char *a, const char *b, size_t iLen ) | ||
74 | { | ||
75 | return ::strncmp( a, b, iLen ); | ||
76 | } | ||
37 | 77 | ||
38 | template<typename chr, int nMinSize, typename chralloc, typename chunkalloc> | 78 | template<typename chr, int nMinSize, typename chralloc, typename chunkalloc> |
39 | struct FStringCore | 79 | struct FStringCore |
40 | { | 80 | { |
81 | friend class FBasicString<chr, nMinSize, chralloc, chunkalloc>; | ||
82 | friend class SharedCore< | ||
83 | FBasicString<chr, nMinSize, chralloc, chunkalloc>, | ||
84 | FStringCore<chr, nMinSize, chralloc, chunkalloc> | ||
85 | >; | ||
86 | private: | ||
41 | typedef struct FStringCore<chr, nMinSize, chralloc, chunkalloc> MyType; | 87 | typedef struct FStringCore<chr, nMinSize, chralloc, chunkalloc> MyType; |
42 | typedef struct FStringChunk<chr> Chunk; | 88 | typedef struct FStringChunk<chr> Chunk; |
43 | FStringCore() : | 89 | FStringCore() : |
@@ -157,6 +203,7 @@ namespace Bu | |||
157 | nLength += pNewChunk->nLength; | 203 | nLength += pNewChunk->nLength; |
158 | } | 204 | } |
159 | }; | 205 | }; |
206 | /** @endcond */ | ||
160 | 207 | ||
161 | /** | 208 | /** |
162 | * Flexible String class. This class was designed with string passing and | 209 | * Flexible String class. This class was designed with string passing and |
@@ -174,55 +221,24 @@ namespace Bu | |||
174 | *@param chralloc (typename) Memory Allocator for chr | 221 | *@param chralloc (typename) Memory Allocator for chr |
175 | *@param chunkalloc (typename) Memory Allocator for chr chunks | 222 | *@param chunkalloc (typename) Memory Allocator for chr chunks |
176 | */ | 223 | */ |
177 | template< typename chr, int nMinSize=256, typename chralloc=std::allocator<chr>, typename chunkalloc=std::allocator<struct FStringChunk<chr> > > | 224 | template< typename chr, int nMinSize=256, |
178 | class FBasicString : public SharedCore< FStringCore<chr, nMinSize, chralloc, chunkalloc> > | 225 | typename chralloc=std::allocator<chr>, |
226 | typename chunkalloc=std::allocator<struct FStringChunk<chr> > > | ||
227 | class FBasicString : public SharedCore< | ||
228 | FBasicString<chr, nMinSize, chralloc, chunkalloc>, | ||
229 | FStringCore<chr, nMinSize, chralloc, chunkalloc> > | ||
179 | { | 230 | { |
180 | protected: | 231 | protected: |
181 | typedef struct FStringChunk<chr> Chunk; | 232 | typedef struct FStringChunk<chr> Chunk; |
182 | typedef struct FBasicString<chr, nMinSize, chralloc, chunkalloc> MyType; | 233 | typedef struct FBasicString<chr, nMinSize, chralloc, chunkalloc> MyType; |
183 | typedef struct FStringCore<chr, nMinSize, chralloc, chunkalloc> Core; | 234 | typedef struct FStringCore<chr, nMinSize, chralloc, chunkalloc> Core; |
184 | 235 | ||
185 | using SharedCore< Core >::core; | 236 | using SharedCore<MyType, Core >::core; |
186 | using SharedCore< Core >::_hardCopy; | 237 | using SharedCore<MyType, Core >::_hardCopy; |
187 | |||
188 | public: | ||
189 | FBasicString() | ||
190 | { | ||
191 | } | ||
192 | |||
193 | FBasicString( const chr *pData ) | ||
194 | { | ||
195 | append( pData ); | ||
196 | } | ||
197 | |||
198 | FBasicString( const chr *pData, long nLength ) | ||
199 | { | ||
200 | append( pData, nLength ); | ||
201 | } | ||
202 | 238 | ||
203 | FBasicString( const MyType &rSrc ) : | 239 | public: // Iterators |
204 | SharedCore<Core>( rSrc ) | ||
205 | { | ||
206 | } | ||
207 | |||
208 | FBasicString( const MyType &rSrc, long nLength ) | ||
209 | { | ||
210 | append( rSrc, nLength ); | ||
211 | } | ||
212 | |||
213 | FBasicString( const MyType &rSrc, long nStart, long nLength ) | ||
214 | { | ||
215 | append( rSrc, nStart, nLength ); | ||
216 | } | ||
217 | |||
218 | FBasicString( long nSize ) | ||
219 | { | ||
220 | core->pFirst = core->pLast = core->newChunk( nSize ); | ||
221 | core->nLength = nSize; | ||
222 | } | ||
223 | |||
224 | struct iterator; | 240 | struct iterator; |
225 | struct const_iterator | 241 | typedef struct const_iterator |
226 | { | 242 | { |
227 | friend class FBasicString<chr, nMinSize, chralloc, chunkalloc>; | 243 | friend class FBasicString<chr, nMinSize, chralloc, chunkalloc>; |
228 | friend struct iterator; | 244 | friend struct iterator; |
@@ -243,7 +259,7 @@ namespace Bu | |||
243 | { | 259 | { |
244 | } | 260 | } |
245 | 261 | ||
246 | const_iterator( const iterator &i ) : | 262 | const_iterator( const struct iterator &i ) : |
247 | pChunk( i.pChunk ), | 263 | pChunk( i.pChunk ), |
248 | iPos( i.iPos ) | 264 | iPos( i.iPos ) |
249 | { | 265 | { |
@@ -454,7 +470,7 @@ namespace Bu | |||
454 | } | 470 | } |
455 | return const_iterator( NULL, 0 ); | 471 | return const_iterator( NULL, 0 ); |
456 | } | 472 | } |
457 | }; | 473 | } const_iterator; |
458 | 474 | ||
459 | typedef struct iterator | 475 | typedef struct iterator |
460 | { | 476 | { |
@@ -702,11 +718,41 @@ namespace Bu | |||
702 | } | 718 | } |
703 | } iterator; | 719 | } iterator; |
704 | 720 | ||
705 | typedef struct const_iterator const_iterator; | 721 | public: |
722 | FBasicString() | ||
723 | { | ||
724 | } | ||
725 | |||
726 | FBasicString( const chr *pData ) | ||
727 | { | ||
728 | append( pData ); | ||
729 | } | ||
730 | |||
731 | FBasicString( const chr *pData, long nLength ) | ||
732 | { | ||
733 | append( pData, nLength ); | ||
734 | } | ||
735 | |||
736 | FBasicString( const MyType &rSrc ) : | ||
737 | SharedCore<MyType, Core>( rSrc ) | ||
738 | { | ||
739 | } | ||
706 | 740 | ||
707 | //typedef chr *iterator; | 741 | FBasicString( const MyType &rSrc, long nLength ) |
708 | // typedef const chr *const_iterator; | 742 | { |
709 | // typedef iterator const_iterator; | 743 | append( rSrc, nLength ); |
744 | } | ||
745 | |||
746 | FBasicString( const MyType &rSrc, long nStart, long nLength ) | ||
747 | { | ||
748 | append( rSrc, nStart, nLength ); | ||
749 | } | ||
750 | |||
751 | FBasicString( long nSize ) | ||
752 | { | ||
753 | core->pFirst = core->pLast = core->newChunk( nSize ); | ||
754 | core->nLength = nSize; | ||
755 | } | ||
710 | 756 | ||
711 | FBasicString( const const_iterator &s ) | 757 | FBasicString( const const_iterator &s ) |
712 | { | 758 | { |
@@ -731,14 +777,8 @@ namespace Bu | |||
731 | if( !pData ) return; | 777 | if( !pData ) return; |
732 | long nLen; | 778 | long nLen; |
733 | for( nLen = 0; pData[nLen] != (chr)0; nLen++ ) { } | 779 | for( nLen = 0; pData[nLen] != (chr)0; nLen++ ) { } |
734 | if( nLen == 0 ) | ||
735 | return; | ||
736 | |||
737 | Chunk *pNew = core->newChunk( nLen ); | ||
738 | cpy( pNew->pData, pData, nLen ); | ||
739 | 780 | ||
740 | _hardCopy(); | 781 | append( pData, 0, nLen ); |
741 | core->appendChunk( pNew ); | ||
742 | } | 782 | } |
743 | 783 | ||
744 | /** | 784 | /** |
@@ -748,15 +788,7 @@ namespace Bu | |||
748 | */ | 788 | */ |
749 | void append( const chr *pData, long nLen ) | 789 | void append( const chr *pData, long nLen ) |
750 | { | 790 | { |
751 | if( nLen == 0 ) | 791 | append( pData, 0, nLen ); |
752 | return; | ||
753 | |||
754 | Chunk *pNew = core->newChunk( nLen ); | ||
755 | |||
756 | cpy( pNew->pData, pData, nLen ); | ||
757 | |||
758 | _hardCopy(); | ||
759 | core->appendChunk( pNew ); | ||
760 | } | 792 | } |
761 | 793 | ||
762 | /** | 794 | /** |
@@ -767,15 +799,37 @@ namespace Bu | |||
767 | */ | 799 | */ |
768 | void append( const chr *pData, long nStart, long nLen ) | 800 | void append( const chr *pData, long nStart, long nLen ) |
769 | { | 801 | { |
770 | if( nLen == 0 ) | 802 | if( !pData ) return; |
803 | if( nLen <= 0 ) | ||
771 | return; | 804 | return; |
772 | 805 | ||
773 | Chunk *pNew = core->newChunk( nLen ); | 806 | pData += nStart; |
774 | |||
775 | cpy( pNew->pData, pData+nStart, nLen ); | ||
776 | 807 | ||
777 | _hardCopy(); | 808 | _hardCopy(); |
778 | core->appendChunk( pNew ); | 809 | |
810 | if( core->pLast && core->pLast->nLength < nMinSize ) | ||
811 | { | ||
812 | int nAmnt = nMinSize - core->pLast->nLength; | ||
813 | if( nAmnt > nLen ) | ||
814 | nAmnt = nLen; | ||
815 | cpy( | ||
816 | core->pLast->pData+core->pLast->nLength, | ||
817 | pData, | ||
818 | nAmnt | ||
819 | ); | ||
820 | pData += nAmnt; | ||
821 | core->pLast->nLength += nAmnt; | ||
822 | nLen -= nAmnt; | ||
823 | core->nLength += nAmnt; | ||
824 | } | ||
825 | |||
826 | if( nLen > 0 ) | ||
827 | { | ||
828 | Chunk *pNew = core->newChunk( nLen ); | ||
829 | cpy( pNew->pData, pData, nLen ); | ||
830 | core->appendChunk( pNew ); | ||
831 | // core->nLength += nLen; | ||
832 | } | ||
779 | } | 833 | } |
780 | 834 | ||
781 | /** | 835 | /** |
@@ -804,7 +858,7 @@ namespace Bu | |||
804 | */ | 858 | */ |
805 | void append( const MyType & sData ) | 859 | void append( const MyType & sData ) |
806 | { | 860 | { |
807 | append( sData.getStr(), sData.getSize() ); | 861 | append( sData.getStr(), 0, sData.getSize() ); |
808 | } | 862 | } |
809 | 863 | ||
810 | /** | 864 | /** |
@@ -815,7 +869,7 @@ namespace Bu | |||
815 | */ | 869 | */ |
816 | void append( const MyType & sData, long nLen ) | 870 | void append( const MyType & sData, long nLen ) |
817 | { | 871 | { |
818 | append( sData.getStr(), nLen ); | 872 | append( sData.getStr(), 0, nLen ); |
819 | } | 873 | } |
820 | 874 | ||
821 | /** | 875 | /** |
@@ -1029,7 +1083,7 @@ namespace Bu | |||
1029 | */ | 1083 | */ |
1030 | void insert( long nPos, const chr *pData ) | 1084 | void insert( long nPos, const chr *pData ) |
1031 | { | 1085 | { |
1032 | insert( nPos, pData, strlen( pData ) ); | 1086 | insert( nPos, pData, Bu::strlen( pData ) ); |
1033 | } | 1087 | } |
1034 | 1088 | ||
1035 | void remove( long nPos, long nLen ) | 1089 | void remove( long nPos, long nLen ) |
@@ -1155,13 +1209,13 @@ namespace Bu | |||
1155 | if( iStart < 0 ) | 1209 | if( iStart < 0 ) |
1156 | iStart = 0; | 1210 | iStart = 0; |
1157 | if( iStart >= core->nLength ) | 1211 | if( iStart >= core->nLength ) |
1158 | return ""; | 1212 | return (const chr[]){(chr)0}; |
1159 | if( iSize < 0 ) | 1213 | if( iSize < 0 ) |
1160 | iSize = core->nLength; | 1214 | iSize = core->nLength; |
1161 | if( iStart+iSize > core->nLength ) | 1215 | if( iStart+iSize > core->nLength ) |
1162 | iSize = core->nLength-iStart; | 1216 | iSize = core->nLength-iStart; |
1163 | if( iSize == 0 ) | 1217 | if( iSize == 0 ) |
1164 | return ""; | 1218 | return (const chr[]){(chr)0}; |
1165 | 1219 | ||
1166 | flatten(); | 1220 | flatten(); |
1167 | MyType ret( core->pFirst->pData+iStart, iSize ); | 1221 | MyType ret( core->pFirst->pData+iStart, iSize ); |
@@ -1212,37 +1266,6 @@ namespace Bu | |||
1212 | } | 1266 | } |
1213 | } | 1267 | } |
1214 | 1268 | ||
1215 | /** | ||
1216 | * (std::string compatability) Get a pointer to the string array. | ||
1217 | *@returns (chr *) The string data. | ||
1218 | */ | ||
1219 | DEPRECATED | ||
1220 | chr *c_str() | ||
1221 | { | ||
1222 | if( core->pFirst == NULL || core->nLength == 0 ) | ||
1223 | return NULL; | ||
1224 | |||
1225 | flatten(); | ||
1226 | _hardCopy(); | ||
1227 | core->pFirst->pData[core->nLength] = (chr)0; | ||
1228 | return core->pFirst->pData; | ||
1229 | } | ||
1230 | |||
1231 | /** | ||
1232 | * (std::string compatability) Get a const pointer to the string array. | ||
1233 | *@returns (const chr *) The string data. | ||
1234 | */ | ||
1235 | DEPRECATED | ||
1236 | const chr *c_str() const | ||
1237 | { | ||
1238 | if( core->pFirst == NULL || core->nLength == 0 ) | ||
1239 | return NULL; | ||
1240 | |||
1241 | flatten(); | ||
1242 | core->pFirst->pData[core->nLength] = (chr)0; | ||
1243 | return core->pFirst->pData; | ||
1244 | } | ||
1245 | |||
1246 | Bu::List<MyType> split( const chr c ) const | 1269 | Bu::List<MyType> split( const chr c ) const |
1247 | { | 1270 | { |
1248 | Bu::List<MyType> ret; | 1271 | Bu::List<MyType> ret; |
@@ -1423,11 +1446,11 @@ namespace Bu | |||
1423 | wordexp_t result; | 1446 | wordexp_t result; |
1424 | 1447 | ||
1425 | /* Expand the string for the program to run. */ | 1448 | /* Expand the string for the program to run. */ |
1426 | switch (wordexp (core->pFirst->pData, &result, 0)) | 1449 | switch (wordexp ((char *)core->pFirst->pData, &result, 0)) |
1427 | { | 1450 | { |
1428 | case 0: /* Successful. */ | 1451 | case 0: /* Successful. */ |
1429 | { | 1452 | { |
1430 | set( result.we_wordv[0] ); | 1453 | set( (chr *)result.we_wordv[0] ); |
1431 | wordfree( &result ); | 1454 | wordfree( &result ); |
1432 | return; | 1455 | return; |
1433 | } | 1456 | } |
@@ -1941,7 +1964,7 @@ namespace Bu | |||
1941 | long iLen = vsnprintf( NULL, 0, sFrmt, ap ); | 1964 | long iLen = vsnprintf( NULL, 0, sFrmt, ap ); |
1942 | 1965 | ||
1943 | Chunk *pNew = core->newChunk( iLen ); | 1966 | Chunk *pNew = core->newChunk( iLen ); |
1944 | vsnprintf( pNew->pData, iLen+1, sFrmt, ap ); | 1967 | vsnprintf( (char *)pNew->pData, iLen+1, sFrmt, ap ); |
1945 | core->appendChunk( pNew ); | 1968 | core->appendChunk( pNew ); |
1946 | 1969 | ||
1947 | va_end( ap ); | 1970 | va_end( ap ); |
@@ -1958,7 +1981,7 @@ namespace Bu | |||
1958 | long iLen = vsnprintf( NULL, 0, sFrmt, ap ); | 1981 | long iLen = vsnprintf( NULL, 0, sFrmt, ap ); |
1959 | 1982 | ||
1960 | Chunk *pNew = core->newChunk( iLen ); | 1983 | Chunk *pNew = core->newChunk( iLen ); |
1961 | vsnprintf( pNew->pData, iLen+1, sFrmt, ap ); | 1984 | vsnprintf( (char *)pNew->pData, iLen+1, sFrmt, ap ); |
1962 | core->appendChunk( pNew ); | 1985 | core->appendChunk( pNew ); |
1963 | 1986 | ||
1964 | va_end( ap ); | 1987 | va_end( ap ); |
@@ -1975,7 +1998,7 @@ namespace Bu | |||
1975 | long iLen = vsnprintf( NULL, 0, sFrmt, ap ); | 1998 | long iLen = vsnprintf( NULL, 0, sFrmt, ap ); |
1976 | 1999 | ||
1977 | Chunk *pNew = core->newChunk( iLen ); | 2000 | Chunk *pNew = core->newChunk( iLen ); |
1978 | vsnprintf( pNew->pData, iLen+1, sFrmt, ap ); | 2001 | vsnprintf( (char *)pNew->pData, iLen+1, sFrmt, ap ); |
1979 | core->prependChunk( pNew ); | 2002 | core->prependChunk( pNew ); |
1980 | 2003 | ||
1981 | va_end( ap ); | 2004 | va_end( ap ); |