aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/unstable/blob.cpp11
-rw-r--r--src/unstable/blob.h1
-rw-r--r--src/unstable/blobbuilder.cpp129
-rw-r--r--src/unstable/blobbuilder.h23
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
29Bu::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
28Bu::Blob::Blob( const char *pSrc ) : 39Bu::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
63Bu::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
138void 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
152void 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
122void Bu::BlobBuilderCore::set( const char *pSrc, int32_t iLength ) 190void 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
196void 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
244void Bu::BlobBuilder::set( const char *pSrc )
245{
246 set( pSrc, strlen( pSrc ) );
247}
248
157void Bu::BlobBuilder::append( const Blob &rSrc ) 249void 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
261void Bu::BlobBuilder::append( const char *pSrc )
262{
263 append( pSrc, strlen( pSrc ) );
264}
265
169void Bu::BlobBuilder::prepend( const Blob &rSrc ) 266void Bu::BlobBuilder::prepend( const Blob &rSrc )
170{ 267{
171 _hardCopy(); 268 _hardCopy();
269 core->prepend( rSrc.getData(), rSrc.getSize() );
172} 270}
173 271
174void Bu::BlobBuilder::prepend( const char *pSrc, int32_t iLength ) 272void Bu::BlobBuilder::prepend( const char *pSrc, int32_t iLength )
175{ 273{
176 _hardCopy(); 274 _hardCopy();
275 core->prepend( pSrc, iLength );
276}
277
278void Bu::BlobBuilder::prepend( const char *pSrc )
279{
280 prepend( pSrc, strlen( pSrc ) );
177} 281}
178 282
179void Bu::BlobBuilder::insert( int32_t iBefore, const Blob &rSrc ) 283void 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
184void Bu::BlobBuilder::insert( int32_t iBefore, const char *pSrc, const Bu::Blob &rSrc ) 289void 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
296void Bu::BlobBuilder::insert( int32_t iBefore, const char *pSrc )
297{
298 insert( iBefore, pSrc, strlen( pSrc ) );
187} 299}
188 300
189void Bu::BlobBuilder::clear() 301void Bu::BlobBuilder::clear()
@@ -199,23 +311,36 @@ int32_t Bu::BlobBuilder::getSize() const
199 311
200Bu::Blob Bu::BlobBuilder::getBlob() const 312Bu::Blob Bu::BlobBuilder::getBlob() const
201{ 313{
202 Blob bRet(); 314 return Blob( *this );
315}
316
317void Bu::BlobBuilder::copyTo( void *pDestRaw, int32_t iDestSize ) const
318{
319 core->copyTo( pDestRaw, iDestSize );
203} 320}
204 321
205Bu::BlobBuilder &Bu::BlobBuilder::operator=( const Blob &rSrc ) 322Bu::BlobBuilder &Bu::BlobBuilder::operator=( const Blob &rSrc )
206{ 323{
324 set( rSrc );
325 return *this;
207} 326}
208 327
209Bu::BlobBuilder &Bu::BlobBuilder::operator=( const char *pSrc ) 328Bu::BlobBuilder &Bu::BlobBuilder::operator=( const char *pSrc )
210{ 329{
330 set( pSrc );
331 return *this;
211} 332}
212 333
213Bu::BlobBuilder &Bu::BlobBuilder::operator+=( const Blob &rSrc ) 334Bu::BlobBuilder &Bu::BlobBuilder::operator+=( const Blob &rSrc )
214{ 335{
336 append( rSrc );
337 return *this;
215} 338}
216 339
217Bu::BlobBuilder &Bu::BlobBuilder::operator+=( const char *pSrc ) 340Bu::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 );