From 9e4d15b6dec9a7f9358855faeb96b1ac767a15e6 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 25 Jun 2019 16:33:14 -0700 Subject: Got most of the functions in, now to test them. --- src/unstable/blob.cpp | 11 ++++ src/unstable/blob.h | 1 + src/unstable/blobbuilder.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++- 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 @@ */ #include "bu/blob.h" +#include "bu/blobbuilder.h" #include "bu/exceptioninvaliditerator.h" #include "bu/exceptionindexoutofbounds.h" @@ -25,6 +26,16 @@ Bu::Blob::Blob( const Bu::Blob &rSrc ) : memcpy( pData, rSrc.pData, iSize+1 ); } +Bu::Blob::Blob( const class BlobBuilder &rSrc ) : + pData( 0 ), + iSize( 0 ) +{ + iSize = rSrc.getSize(); + pData = new char[iSize]; + + rSrc.copyTo( pData, iSize ); +} + Bu::Blob::Blob( const char *pSrc ) : pData( 0 ), 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 public: Blob(); Blob( const Blob &rSrc ); + Blob( const class BlobBuilder &rSrc ); Blob( const char *pSrc ); Blob( const void *pSrc, int32_t iSize ); 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 ) iLength -= iCopy; } +Bu::BlobBuilderCore::Chunk *Bu::BlobBuilderCore::Chunk::split( int32_t iIndex ) +{ + if( iIndex == 0 ) + return NULL; + + if( iIndex >= iLength ) + return NULL; + + Chunk *pNew = new Chunk( pData+iIndex, iLength-iIndex ); + iLength -= iIndex; + pNew->pNext = pNext; + pNext = pNew; + + return pNew; +} + ///// // BlobBuilderCore // @@ -119,12 +135,83 @@ void Bu::BlobBuilderCore::append( const char *pSrc, int32_t iLength ) } } +void Bu::BlobBuilderCore::prepend( const char *pSrc, int32_t iLength ) +{ + if( pFirst == 0 ) + { + pFirst = pLast = new Chunk( pSrc, iLength ); + } + else + { + Chunk *pNew = new Chunk( pSrc, iLength ); + pNew->pNext = pFirst; + pFirst = pNew; + } +} + +void Bu::BlobBuilderCore::insert( int32_t iBefore, const char *pSrc, + int32_t iLength ) +{ + if( iBefore <= 0 ) + { + prepend( pSrc, iLength ); + return; + } + if( iBefore >= this->iLength ) + { + append( pSrc, iLength ); + return; + } + + Chunk *pCur = pFirst; + while( pCur ) + { + if( iBefore == 0 ) + { + // Insert between chunks, no splitting required. + Chunk *pNew = new Chunk( pSrc, iLength ); + pNew->pNext = pCur->pNext; + pCur->pNext = pNew; + if( pLast == pCur ) + pLast = pNew; + } + if( iBefore < pCur->iLength ) + { + // This is the chunk we need to split. + Chunk *pNew = pCur->split( iBefore ); + if( pLast == pCur ) + pLast = pNew; + continue; + } + pCur = pCur->pNext; + } +} + void Bu::BlobBuilderCore::set( const char *pSrc, int32_t iLength ) { clear(); append( pSrc, iLength ); } +void Bu::BlobBuilderCore::copyTo( void *pDestRaw, int32_t iLength ) const +{ + char *pDest = reinterpret_cast(pDestRaw); + + Chunk *pCur = pFirst; + while( pCur && iLength ) + { + int32_t iChunkLen = pCur->iLength; + if( iChunkLen > iLength ) + iChunkLen = iLength; + + memcpy( pDest, pCur->pData, iChunkLen ); + pDest += iChunkLen; + iLength -= iChunkLen; + + pCur = pCur->pNext; + } +} + ////// // BlobBuilder // @@ -154,6 +241,11 @@ void Bu::BlobBuilder::set( const char *pSrc, int32_t iLength ) core->set( pSrc, iLength ); } +void Bu::BlobBuilder::set( const char *pSrc ) +{ + set( pSrc, strlen( pSrc ) ); +} + void Bu::BlobBuilder::append( const Blob &rSrc ) { _hardCopy(); @@ -166,24 +258,44 @@ void Bu::BlobBuilder::append( const char *pSrc, int32_t iLength ) core->append( pSrc, iLength ); } +void Bu::BlobBuilder::append( const char *pSrc ) +{ + append( pSrc, strlen( pSrc ) ); +} + void Bu::BlobBuilder::prepend( const Blob &rSrc ) { _hardCopy(); + core->prepend( rSrc.getData(), rSrc.getSize() ); } void Bu::BlobBuilder::prepend( const char *pSrc, int32_t iLength ) { _hardCopy(); + core->prepend( pSrc, iLength ); +} + +void Bu::BlobBuilder::prepend( const char *pSrc ) +{ + prepend( pSrc, strlen( pSrc ) ); } void Bu::BlobBuilder::insert( int32_t iBefore, const Blob &rSrc ) { _hardCopy(); + core->insert( iBefore, rSrc.getData(), rSrc.getSize() ); } -void Bu::BlobBuilder::insert( int32_t iBefore, const char *pSrc, const Bu::Blob &rSrc ) +void Bu::BlobBuilder::insert( int32_t iBefore, const char *pSrc, + int32_t iLength ) { _hardCopy(); + core->insert( iBefore, pSrc, iLength ); +} + +void Bu::BlobBuilder::insert( int32_t iBefore, const char *pSrc ) +{ + insert( iBefore, pSrc, strlen( pSrc ) ); } void Bu::BlobBuilder::clear() @@ -199,23 +311,36 @@ int32_t Bu::BlobBuilder::getSize() const Bu::Blob Bu::BlobBuilder::getBlob() const { - Blob bRet(); + return Blob( *this ); +} + +void Bu::BlobBuilder::copyTo( void *pDestRaw, int32_t iDestSize ) const +{ + core->copyTo( pDestRaw, iDestSize ); } Bu::BlobBuilder &Bu::BlobBuilder::operator=( const Blob &rSrc ) { + set( rSrc ); + return *this; } Bu::BlobBuilder &Bu::BlobBuilder::operator=( const char *pSrc ) { + set( pSrc ); + return *this; } Bu::BlobBuilder &Bu::BlobBuilder::operator+=( const Blob &rSrc ) { + append( rSrc ); + return *this; } Bu::BlobBuilder &Bu::BlobBuilder::operator+=( const char *pSrc ) { + append( pSrc ); + return *this; } 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 class Blob; class BlobBuilder; + /** @cond DEVEL */ class BlobBuilderCore { friend class BlobBuilder; @@ -29,6 +30,15 @@ namespace Bu void append( const char *&pSrc, int32_t &iLength ); + /** + * Splits this chunk into two chunks, and fixes the links. + *@param iIndex The first byte to be in the new chunk, if this is + * zero or less then it has no effect. + *@returns A pointer to the new chunk, or null if no work was + * done. + */ + Chunk *split( int32_t iIndex ); + int32_t iLength; char *pData; Chunk *pNext; @@ -40,12 +50,16 @@ namespace Bu void clear(); void append( const char *pSrc, int32_t iLength ); + void prepend( const char *pSrc, int32_t iLength ); + void insert( int32_t iBefore, const char *pSrc, int32_t iLength ); void set( const char *pSrc, int32_t iLength ); + void copyTo( void *pDestRaw, int32_t iLength ) const; Chunk *pFirst; Chunk *pLast; int32_t iLength; }; + /** @endcond */ class BlobBuilder : public Bu::SharedCore { @@ -61,16 +75,21 @@ namespace Bu void set( const Blob &rSrc ); void set( const char *pSrc, int32_t iLength ); + void set( const char *pSrc ); void append( const Blob &rSrc ); void append( const char *pSrc, int32_t iLength ); + void append( const char *pSrc ); void prepend( const Blob &rSrc ); void prepend( const char *pSrc, int32_t iLength ); + void prepend( const char *pSrc ); void insert( int32_t iBefore, const Blob &rSrc ); - void insert( int32_t iBefore, const char *pSrc, const Blob &rSrc ); + void insert( int32_t iBefore, const char *pSrc, int32_t iLength ); + void insert( int32_t iBefore, const char *pSrc ); void clear(); - int32_t getSize() const; + int32_t getSize() const; Blob getBlob() const; + void copyTo( void *pDestRaw, int32_t iDestSize ) const; BlobBuilder &operator=( const Blob &rSrc ); BlobBuilder &operator=( const char *pSrc ); -- cgit v1.2.3