diff options
-rw-r--r-- | src/unstable/blob.cpp | 11 | ||||
-rw-r--r-- | src/unstable/blob.h | 1 | ||||
-rw-r--r-- | src/unstable/blobbuilder.cpp | 129 | ||||
-rw-r--r-- | src/unstable/blobbuilder.h | 23 |
4 files changed, 160 insertions, 4 deletions
diff --git a/src/unstable/blob.cpp b/src/unstable/blob.cpp index 3f7d9d9..9abfede 100644 --- a/src/unstable/blob.cpp +++ b/src/unstable/blob.cpp | |||
@@ -6,6 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "bu/blob.h" | 8 | #include "bu/blob.h" |
9 | #include "bu/blobbuilder.h" | ||
9 | #include "bu/exceptioninvaliditerator.h" | 10 | #include "bu/exceptioninvaliditerator.h" |
10 | #include "bu/exceptionindexoutofbounds.h" | 11 | #include "bu/exceptionindexoutofbounds.h" |
11 | 12 | ||
@@ -25,6 +26,16 @@ Bu::Blob::Blob( const Bu::Blob &rSrc ) : | |||
25 | memcpy( pData, rSrc.pData, iSize+1 ); | 26 | memcpy( pData, rSrc.pData, iSize+1 ); |
26 | } | 27 | } |
27 | 28 | ||
29 | Bu::Blob::Blob( const class BlobBuilder &rSrc ) : | ||
30 | pData( 0 ), | ||
31 | iSize( 0 ) | ||
32 | { | ||
33 | iSize = rSrc.getSize(); | ||
34 | pData = new char[iSize]; | ||
35 | |||
36 | rSrc.copyTo( pData, iSize ); | ||
37 | } | ||
38 | |||
28 | Bu::Blob::Blob( const char *pSrc ) : | 39 | Bu::Blob::Blob( const char *pSrc ) : |
29 | pData( 0 ), | 40 | pData( 0 ), |
30 | iSize( 0 ) | 41 | iSize( 0 ) |
diff --git a/src/unstable/blob.h b/src/unstable/blob.h index b48f488..d6c40e3 100644 --- a/src/unstable/blob.h +++ b/src/unstable/blob.h | |||
@@ -37,6 +37,7 @@ namespace Bu | |||
37 | public: | 37 | public: |
38 | Blob(); | 38 | Blob(); |
39 | Blob( const Blob &rSrc ); | 39 | Blob( const Blob &rSrc ); |
40 | Blob( const class BlobBuilder &rSrc ); | ||
40 | Blob( const char *pSrc ); | 41 | Blob( const char *pSrc ); |
41 | Blob( const void *pSrc, int32_t iSize ); | 42 | Blob( const void *pSrc, int32_t iSize ); |
42 | Blob( const const_iterator &iStart ); | 43 | Blob( const const_iterator &iStart ); |
diff --git a/src/unstable/blobbuilder.cpp b/src/unstable/blobbuilder.cpp index 7ea159d..d4b458b 100644 --- a/src/unstable/blobbuilder.cpp +++ b/src/unstable/blobbuilder.cpp | |||
@@ -60,6 +60,22 @@ void Bu::BlobBuilderCore::Chunk::append( const char *&pSrc, int32_t &iLength ) | |||
60 | iLength -= iCopy; | 60 | iLength -= iCopy; |
61 | } | 61 | } |
62 | 62 | ||
63 | Bu::BlobBuilderCore::Chunk *Bu::BlobBuilderCore::Chunk::split( int32_t iIndex ) | ||
64 | { | ||
65 | if( iIndex == 0 ) | ||
66 | return NULL; | ||
67 | |||
68 | if( iIndex >= iLength ) | ||
69 | return NULL; | ||
70 | |||
71 | Chunk *pNew = new Chunk( pData+iIndex, iLength-iIndex ); | ||
72 | iLength -= iIndex; | ||
73 | pNew->pNext = pNext; | ||
74 | pNext = pNew; | ||
75 | |||
76 | return pNew; | ||
77 | } | ||
78 | |||
63 | ///// | 79 | ///// |
64 | // BlobBuilderCore | 80 | // BlobBuilderCore |
65 | // | 81 | // |
@@ -119,12 +135,83 @@ void Bu::BlobBuilderCore::append( const char *pSrc, int32_t iLength ) | |||
119 | } | 135 | } |
120 | } | 136 | } |
121 | 137 | ||
138 | void Bu::BlobBuilderCore::prepend( const char *pSrc, int32_t iLength ) | ||
139 | { | ||
140 | if( pFirst == 0 ) | ||
141 | { | ||
142 | pFirst = pLast = new Chunk( pSrc, iLength ); | ||
143 | } | ||
144 | else | ||
145 | { | ||
146 | Chunk *pNew = new Chunk( pSrc, iLength ); | ||
147 | pNew->pNext = pFirst; | ||
148 | pFirst = pNew; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | void Bu::BlobBuilderCore::insert( int32_t iBefore, const char *pSrc, | ||
153 | int32_t iLength ) | ||
154 | { | ||
155 | if( iBefore <= 0 ) | ||
156 | { | ||
157 | prepend( pSrc, iLength ); | ||
158 | return; | ||
159 | } | ||
160 | if( iBefore >= this->iLength ) | ||
161 | { | ||
162 | append( pSrc, iLength ); | ||
163 | return; | ||
164 | } | ||
165 | |||
166 | Chunk *pCur = pFirst; | ||
167 | while( pCur ) | ||
168 | { | ||
169 | if( iBefore == 0 ) | ||
170 | { | ||
171 | // Insert between chunks, no splitting required. | ||
172 | Chunk *pNew = new Chunk( pSrc, iLength ); | ||
173 | pNew->pNext = pCur->pNext; | ||
174 | pCur->pNext = pNew; | ||
175 | if( pLast == pCur ) | ||
176 | pLast = pNew; | ||
177 | } | ||
178 | if( iBefore < pCur->iLength ) | ||
179 | { | ||
180 | // This is the chunk we need to split. | ||
181 | Chunk *pNew = pCur->split( iBefore ); | ||
182 | if( pLast == pCur ) | ||
183 | pLast = pNew; | ||
184 | continue; | ||
185 | } | ||
186 | pCur = pCur->pNext; | ||
187 | } | ||
188 | } | ||
189 | |||
122 | void Bu::BlobBuilderCore::set( const char *pSrc, int32_t iLength ) | 190 | void Bu::BlobBuilderCore::set( const char *pSrc, int32_t iLength ) |
123 | { | 191 | { |
124 | clear(); | 192 | clear(); |
125 | append( pSrc, iLength ); | 193 | append( pSrc, iLength ); |
126 | } | 194 | } |
127 | 195 | ||
196 | void Bu::BlobBuilderCore::copyTo( void *pDestRaw, int32_t iLength ) const | ||
197 | { | ||
198 | char *pDest = reinterpret_cast<char *>(pDestRaw); | ||
199 | |||
200 | Chunk *pCur = pFirst; | ||
201 | while( pCur && iLength ) | ||
202 | { | ||
203 | int32_t iChunkLen = pCur->iLength; | ||
204 | if( iChunkLen > iLength ) | ||
205 | iChunkLen = iLength; | ||
206 | |||
207 | memcpy( pDest, pCur->pData, iChunkLen ); | ||
208 | pDest += iChunkLen; | ||
209 | iLength -= iChunkLen; | ||
210 | |||
211 | pCur = pCur->pNext; | ||
212 | } | ||
213 | } | ||
214 | |||
128 | ////// | 215 | ////// |
129 | // BlobBuilder | 216 | // BlobBuilder |
130 | // | 217 | // |
@@ -154,6 +241,11 @@ void Bu::BlobBuilder::set( const char *pSrc, int32_t iLength ) | |||
154 | core->set( pSrc, iLength ); | 241 | core->set( pSrc, iLength ); |
155 | } | 242 | } |
156 | 243 | ||
244 | void Bu::BlobBuilder::set( const char *pSrc ) | ||
245 | { | ||
246 | set( pSrc, strlen( pSrc ) ); | ||
247 | } | ||
248 | |||
157 | void Bu::BlobBuilder::append( const Blob &rSrc ) | 249 | void Bu::BlobBuilder::append( const Blob &rSrc ) |
158 | { | 250 | { |
159 | _hardCopy(); | 251 | _hardCopy(); |
@@ -166,24 +258,44 @@ void Bu::BlobBuilder::append( const char *pSrc, int32_t iLength ) | |||
166 | core->append( pSrc, iLength ); | 258 | core->append( pSrc, iLength ); |
167 | } | 259 | } |
168 | 260 | ||
261 | void Bu::BlobBuilder::append( const char *pSrc ) | ||
262 | { | ||
263 | append( pSrc, strlen( pSrc ) ); | ||
264 | } | ||
265 | |||
169 | void Bu::BlobBuilder::prepend( const Blob &rSrc ) | 266 | void Bu::BlobBuilder::prepend( const Blob &rSrc ) |
170 | { | 267 | { |
171 | _hardCopy(); | 268 | _hardCopy(); |
269 | core->prepend( rSrc.getData(), rSrc.getSize() ); | ||
172 | } | 270 | } |
173 | 271 | ||
174 | void Bu::BlobBuilder::prepend( const char *pSrc, int32_t iLength ) | 272 | void Bu::BlobBuilder::prepend( const char *pSrc, int32_t iLength ) |
175 | { | 273 | { |
176 | _hardCopy(); | 274 | _hardCopy(); |
275 | core->prepend( pSrc, iLength ); | ||
276 | } | ||
277 | |||
278 | void Bu::BlobBuilder::prepend( const char *pSrc ) | ||
279 | { | ||
280 | prepend( pSrc, strlen( pSrc ) ); | ||
177 | } | 281 | } |
178 | 282 | ||
179 | void Bu::BlobBuilder::insert( int32_t iBefore, const Blob &rSrc ) | 283 | void Bu::BlobBuilder::insert( int32_t iBefore, const Blob &rSrc ) |
180 | { | 284 | { |
181 | _hardCopy(); | 285 | _hardCopy(); |
286 | core->insert( iBefore, rSrc.getData(), rSrc.getSize() ); | ||
182 | } | 287 | } |
183 | 288 | ||
184 | void Bu::BlobBuilder::insert( int32_t iBefore, const char *pSrc, const Bu::Blob &rSrc ) | 289 | void Bu::BlobBuilder::insert( int32_t iBefore, const char *pSrc, |
290 | int32_t iLength ) | ||
185 | { | 291 | { |
186 | _hardCopy(); | 292 | _hardCopy(); |
293 | core->insert( iBefore, pSrc, iLength ); | ||
294 | } | ||
295 | |||
296 | void Bu::BlobBuilder::insert( int32_t iBefore, const char *pSrc ) | ||
297 | { | ||
298 | insert( iBefore, pSrc, strlen( pSrc ) ); | ||
187 | } | 299 | } |
188 | 300 | ||
189 | void Bu::BlobBuilder::clear() | 301 | void Bu::BlobBuilder::clear() |
@@ -199,23 +311,36 @@ int32_t Bu::BlobBuilder::getSize() const | |||
199 | 311 | ||
200 | Bu::Blob Bu::BlobBuilder::getBlob() const | 312 | Bu::Blob Bu::BlobBuilder::getBlob() const |
201 | { | 313 | { |
202 | Blob bRet(); | 314 | return Blob( *this ); |
315 | } | ||
316 | |||
317 | void Bu::BlobBuilder::copyTo( void *pDestRaw, int32_t iDestSize ) const | ||
318 | { | ||
319 | core->copyTo( pDestRaw, iDestSize ); | ||
203 | } | 320 | } |
204 | 321 | ||
205 | Bu::BlobBuilder &Bu::BlobBuilder::operator=( const Blob &rSrc ) | 322 | Bu::BlobBuilder &Bu::BlobBuilder::operator=( const Blob &rSrc ) |
206 | { | 323 | { |
324 | set( rSrc ); | ||
325 | return *this; | ||
207 | } | 326 | } |
208 | 327 | ||
209 | Bu::BlobBuilder &Bu::BlobBuilder::operator=( const char *pSrc ) | 328 | Bu::BlobBuilder &Bu::BlobBuilder::operator=( const char *pSrc ) |
210 | { | 329 | { |
330 | set( pSrc ); | ||
331 | return *this; | ||
211 | } | 332 | } |
212 | 333 | ||
213 | Bu::BlobBuilder &Bu::BlobBuilder::operator+=( const Blob &rSrc ) | 334 | Bu::BlobBuilder &Bu::BlobBuilder::operator+=( const Blob &rSrc ) |
214 | { | 335 | { |
336 | append( rSrc ); | ||
337 | return *this; | ||
215 | } | 338 | } |
216 | 339 | ||
217 | Bu::BlobBuilder &Bu::BlobBuilder::operator+=( const char *pSrc ) | 340 | Bu::BlobBuilder &Bu::BlobBuilder::operator+=( const char *pSrc ) |
218 | { | 341 | { |
342 | append( pSrc ); | ||
343 | return *this; | ||
219 | } | 344 | } |
220 | 345 | ||
221 | 346 | ||
diff --git a/src/unstable/blobbuilder.h b/src/unstable/blobbuilder.h index 9b5e390..483de43 100644 --- a/src/unstable/blobbuilder.h +++ b/src/unstable/blobbuilder.h | |||
@@ -16,6 +16,7 @@ namespace Bu | |||
16 | class Blob; | 16 | class Blob; |
17 | class BlobBuilder; | 17 | class BlobBuilder; |
18 | 18 | ||
19 | /** @cond DEVEL */ | ||
19 | class BlobBuilderCore | 20 | class BlobBuilderCore |
20 | { | 21 | { |
21 | friend class BlobBuilder; | 22 | friend class BlobBuilder; |
@@ -29,6 +30,15 @@ namespace Bu | |||
29 | 30 | ||
30 | void append( const char *&pSrc, int32_t &iLength ); | 31 | void append( const char *&pSrc, int32_t &iLength ); |
31 | 32 | ||
33 | /** | ||
34 | * Splits this chunk into two chunks, and fixes the links. | ||
35 | *@param iIndex The first byte to be in the new chunk, if this is | ||
36 | * zero or less then it has no effect. | ||
37 | *@returns A pointer to the new chunk, or null if no work was | ||
38 | * done. | ||
39 | */ | ||
40 | Chunk *split( int32_t iIndex ); | ||
41 | |||
32 | int32_t iLength; | 42 | int32_t iLength; |
33 | char *pData; | 43 | char *pData; |
34 | Chunk *pNext; | 44 | Chunk *pNext; |
@@ -40,12 +50,16 @@ namespace Bu | |||
40 | 50 | ||
41 | void clear(); | 51 | void clear(); |
42 | void append( const char *pSrc, int32_t iLength ); | 52 | void append( const char *pSrc, int32_t iLength ); |
53 | void prepend( const char *pSrc, int32_t iLength ); | ||
54 | void insert( int32_t iBefore, const char *pSrc, int32_t iLength ); | ||
43 | void set( const char *pSrc, int32_t iLength ); | 55 | void set( const char *pSrc, int32_t iLength ); |
56 | void copyTo( void *pDestRaw, int32_t iLength ) const; | ||
44 | 57 | ||
45 | Chunk *pFirst; | 58 | Chunk *pFirst; |
46 | Chunk *pLast; | 59 | Chunk *pLast; |
47 | int32_t iLength; | 60 | int32_t iLength; |
48 | }; | 61 | }; |
62 | /** @endcond */ | ||
49 | 63 | ||
50 | class BlobBuilder : public Bu::SharedCore<BlobBuilder, BlobBuilderCore> | 64 | class BlobBuilder : public Bu::SharedCore<BlobBuilder, BlobBuilderCore> |
51 | { | 65 | { |
@@ -61,16 +75,21 @@ namespace Bu | |||
61 | 75 | ||
62 | void set( const Blob &rSrc ); | 76 | void set( const Blob &rSrc ); |
63 | void set( const char *pSrc, int32_t iLength ); | 77 | void set( const char *pSrc, int32_t iLength ); |
78 | void set( const char *pSrc ); | ||
64 | void append( const Blob &rSrc ); | 79 | void append( const Blob &rSrc ); |
65 | void append( const char *pSrc, int32_t iLength ); | 80 | void append( const char *pSrc, int32_t iLength ); |
81 | void append( const char *pSrc ); | ||
66 | void prepend( const Blob &rSrc ); | 82 | void prepend( const Blob &rSrc ); |
67 | void prepend( const char *pSrc, int32_t iLength ); | 83 | void prepend( const char *pSrc, int32_t iLength ); |
84 | void prepend( const char *pSrc ); | ||
68 | void insert( int32_t iBefore, const Blob &rSrc ); | 85 | void insert( int32_t iBefore, const Blob &rSrc ); |
69 | void insert( int32_t iBefore, const char *pSrc, const Blob &rSrc ); | 86 | void insert( int32_t iBefore, const char *pSrc, int32_t iLength ); |
87 | void insert( int32_t iBefore, const char *pSrc ); | ||
70 | void clear(); | 88 | void clear(); |
71 | int32_t getSize() const; | ||
72 | 89 | ||
90 | int32_t getSize() const; | ||
73 | Blob getBlob() const; | 91 | Blob getBlob() const; |
92 | void copyTo( void *pDestRaw, int32_t iDestSize ) const; | ||
74 | 93 | ||
75 | BlobBuilder &operator=( const Blob &rSrc ); | 94 | BlobBuilder &operator=( const Blob &rSrc ); |
76 | BlobBuilder &operator=( const char *pSrc ); | 95 | BlobBuilder &operator=( const char *pSrc ); |