diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2011-01-10 21:04:17 +0000 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2011-01-10 21:04:17 +0000 |
| commit | 2ba3f84ab559da02a11aa000b3cecb3b3668af61 (patch) | |
| tree | 266f450b512f607ec54d54af4fa8c13fdbe7ef91 /src/fbasicstring.h | |
| parent | ea18007633b31901f2ae275cc0576c3f7ce99fc9 (diff) | |
| parent | 3611f253f6fdfa4954d374ab85ddaa7f799c130c (diff) | |
| download | libbu++-2ba3f84ab559da02a11aa000b3cecb3b3668af61.tar.gz libbu++-2ba3f84ab559da02a11aa000b3cecb3b3668af61.tar.bz2 libbu++-2ba3f84ab559da02a11aa000b3cecb3b3668af61.tar.xz libbu++-2ba3f84ab559da02a11aa000b3cecb3b3668af61.zip | |
Merged in the core branch. This is a major update that fixes many things, and
changes many others, including source files that were deleted and renamed.
Before doing this update, I reccomend a full clean, or even a fresh checkout.
Things to note, most outstanding about this update:
- Bu::Socket was changed to Bu::TcpSocket and the default mode is blocking.
- All templatized container classes are SharedCore now, which is good, but
SharedCore is inherently non-reentrant safe. However, all SharedCore classes
have a "clone" function that return a non-shared copy of the object, safe for
passing into a reentrant safe function accessing shared memory.
Diffstat (limited to 'src/fbasicstring.h')
| -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 ); |
