aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2007-03-15 04:03:52 +0000
committerMike Buland <eichlan@xagasoft.com>2007-03-15 04:03:52 +0000
commit46725741fc82866e41652dee7adeddf376fde618 (patch)
treec3577a311ce4a5242f7eaf0d8359649013fb4cf8
parent571f489db6a49809e29c6b1f9c3f2fd08089f012 (diff)
downloadlibbu++-46725741fc82866e41652dee7adeddf376fde618.tar.gz
libbu++-46725741fc82866e41652dee7adeddf376fde618.tar.bz2
libbu++-46725741fc82866e41652dee7adeddf376fde618.tar.xz
libbu++-46725741fc82866e41652dee7adeddf376fde618.zip
FString is totally usable, a few more helpers must be written before it surpases
the other classes in functionality. It's already rather fast.
-rw-r--r--build.conf1
-rw-r--r--src/fstring.h239
-rw-r--r--src/tests/fstring.cpp28
3 files changed, 260 insertions, 8 deletions
diff --git a/build.conf b/build.conf
index a9c6d49..5c4dbb6 100644
--- a/build.conf
+++ b/build.conf
@@ -4,6 +4,7 @@ default action: check "libbu++.a"
4"clean" action: clean targets() 4"clean" action: clean targets()
5"tests" action: check targets() filter regexp("^tests/.*$") 5"tests" action: check targets() filter regexp("^tests/.*$")
6"all" action: check targets() 6"all" action: check targets()
7"fstring" action: check "tests/fstring"
7 8
8set "CXXFLAGS" += "-ggdb -Wall" 9set "CXXFLAGS" += "-ggdb -Wall"
9 10
diff --git a/src/fstring.h b/src/fstring.h
index 2eaa4ba..287641f 100644
--- a/src/fstring.h
+++ b/src/fstring.h
@@ -4,28 +4,251 @@
4#include <stdint.h> 4#include <stdint.h>
5#include <memory> 5#include <memory>
6 6
7template< typename chr=char >
8struct FStringChunk
9{
10 long nLength;
11 chr *pData;
12 FStringChunk *pNext;
13};
14
7/** 15/**
8 * 16 *
9 */ 17 */
10template< typename chr, typename chralloc = std::allocator<chr> > 18template< typename chr=char, typename chralloc=std::allocator<chr>, typename chunkalloc=std::allocator<struct FStringChunk<chr> > >
11class FString 19class FBasicString
12{ 20{
21private:
22 typedef struct FStringChunk<chr> Chunk;
23
13public: 24public:
14 FString() : 25 FBasicString() :
15 pData( NULL ), 26 nLength( 0 ),
16 pnRefs( NULL ) 27 pnRefs( NULL ),
28 pFirst( NULL ),
29 pLast( NULL )
30 {
31 }
32
33 FBasicString( const chr *pData ) :
34 nLength( 0 ),
35 pnRefs( NULL ),
36 pFirst( NULL ),
37 pLast( NULL )
38 {
39 append( pData );
40 }
41
42 FBasicString( const chr *pData, long nLength ) :
43 nLength( 0 ),
44 pnRefs( NULL ),
45 pFirst( NULL ),
46 pLast( NULL )
47 {
48 append( pData, nLength );
49 }
50
51 virtual ~FBasicString()
52 {
53 }
54
55 void append( const chr *pData )
56 {
57 long nLen;
58 for( nLen = 0; pData[nLen] != (chr)0; nLen++ );
59
60 Chunk *pNew = newChunk( nLen );
61 memcpy( pNew->pData, pData, nLen * sizeof(chr) );
62
63 appendChunk( pNew );
64 }
65
66 void append( const chr *pData, long nLen )
67 {
68 Chunk *pNew = newChunk( nLen );
69
70 memcpy( pNew->pData, pData, nLen * sizeof(chr) );
71
72 appendChunk( pNew );
73 }
74
75 void prepend( const chr *pData )
76 {
77 long nLen;
78 for( nLen = 0; pData[nLen] != (chr)0; nLen++ );
79
80 Chunk *pNew = newChunk( nLen );
81 memcpy( pNew->pData, pData, nLen * sizeof(chr) );
82
83 prependChunk( pNew );
84 }
85
86 void prepend( const chr *pData, long nLen )
87 {
88 Chunk *pNew = newChunk( nLen );
89
90 memcpy( pNew->pData, pData, nLen * sizeof(chr) );
91
92 prependChunk( pNew );
93 }
94
95 void clear()
96 {
97 if( pFirst == NULL )
98 return;
99
100 Chunk *i = pFirst;
101 for(;;)
102 {
103 Chunk *n = i->pNext;
104 aChr.deallocate( i->pData, i->nLength+1 );
105 aChunk.deallocate( i, 1 );
106 if( n == NULL )
107 break;
108 i = n;
109 }
110 pFirst = pLast = NULL;
111 nLength = 0;
112 }
113
114 chr *c_str()
115 {
116 if( pFirst == NULL )
117 return NULL;
118
119 flatten();
120 return pFirst->pData;
121 }
122
123 FBasicString<chr, chralloc, chunkalloc> &operator +=( const chr *pData )
17 { 124 {
125 append( pData );
126
127 return (*this);
18 } 128 }
19 129
20 virtual ~FString() 130 FBasicString<chr, chralloc, chunkalloc> &operator =( const chr *pData )
21 { 131 {
132 clear();
133 append( pData );
134
135 return (*this);
136 }
137
138 bool operator ==( const chr *pData )
139 {
140 if( pFirst == NULL ) {
141 if( pData == NULL )
142 return true;
143 return false;
144 }
145
146 flatten();
147 const chr *a = pData;
148 chr *b = pFirst->pData;
149 for( ; *a!=(chr)0; a++, b++ )
150 {
151 if( *a != *b )
152 return false;
153 }
154
155 return true;
156 }
157
158 bool operator !=(const chr *pData )
159 {
160 return !(*this == pData);
161 }
162
163
164
165private:
166 void flatten()
167 {
168 if( isFlat() )
169 return;
170
171 if( pFirst == NULL )
172 return;
173
174 Chunk *pNew = newChunk( nLength );
175 chr *pos = pNew->pData;
176 Chunk *i = pFirst;
177 for(;;)
178 {
179 memcpy( pos, i->pData, i->nLength*sizeof(chr) );
180 pos += i->nLength;
181 i = i->pNext;
182 if( i == NULL )
183 break;
184 }
185 clear();
186
187 appendChunk( pNew );
188 }
189
190 bool isFlat()
191 {
192 return (pFirst == pLast);
193 }
194
195 bool isShared()
196 {
197 return (pnRefs != NULL);
198 }
199
200 Chunk *newChunk()
201 {
202 Chunk *pNew = aChunk.allocate( 1 );
203 pNew->pNext = NULL;
204 return pNew;
205 }
206
207 Chunk *newChunk( long nLen )
208 {
209 Chunk *pNew = aChunk.allocate( 1 );
210 pNew->pNext = NULL;
211 pNew->nLength = nLen;
212 pNew->pData = aChr.allocate( nLen+1 );
213 return pNew;
214 }
215
216 void appendChunk( Chunk *pNewChunk )
217 {
218 if( pFirst == NULL )
219 pLast = pFirst = pNewChunk;
220 else
221 {
222 pLast->pNext = pNewChunk;
223 pLast = pNewChunk;
224 }
225
226 nLength += pNewChunk->nLength;
227 }
228
229 void prependChunk( Chunk *pNewChunk )
230 {
231 if( pFirst == NULL )
232 pLast = pFirst = pNewChunk;
233 else
234 {
235 pNewChunk->pNext = pFirst;
236 pFirst = pNewChunk;
237 }
238
239 nLength += pNewChunk->nLength;
22 } 240 }
23 241
24private: 242private:
25 long nLength; 243 long nLength;
26 chr *pData;
27 uint32_t *pnRefs; 244 uint32_t *pnRefs;
28 chralloc aChars; 245 Chunk *pFirst;
246 Chunk *pLast;
247
248 chralloc aChr;
249 chunkalloc aChunk;
29}; 250};
30 251
252typedef FBasicString<char> FString;
253
31#endif 254#endif
diff --git a/src/tests/fstring.cpp b/src/tests/fstring.cpp
new file mode 100644
index 0000000..26905ac
--- /dev/null
+++ b/src/tests/fstring.cpp
@@ -0,0 +1,28 @@
1#include "fstring.h"
2
3int main( int argc, char *argv )
4{
5 FString str("[] this won't be in there", 3);
6
7 str.append("Hello");
8 str.append(" th");
9 str.append("ere.");
10
11 if( str == "[] Hello there." )
12 printf("1) check\n");
13
14 if( str != "[] Hello there. " )
15 printf("2) check\n");
16
17 if( str != "[] Hello there." )
18 printf("3) failed\n");
19 else
20 printf("3) check\n");
21
22 str += " How are you?";
23
24 str.prepend("Bob says: ");
25
26 printf("%s\n", str.c_str() );
27}
28