From c4c34c1bfe568b653399cb5349ce54b5ee1c519b Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sat, 25 May 2019 15:47:58 -0700 Subject: Augmented UnitSuite, added more to Blob, and added tests. --- src/unstable/blob.cpp | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/unstable/blob.h | 37 ++++++- 2 files changed, 307 insertions(+), 1 deletion(-) (limited to 'src/unstable') diff --git a/src/unstable/blob.cpp b/src/unstable/blob.cpp index 51a3b93..f8cf1b0 100644 --- a/src/unstable/blob.cpp +++ b/src/unstable/blob.cpp @@ -7,6 +7,7 @@ #include "bu/blob.h" #include "bu/exceptioninvaliditerator.h" +#include "bu/exceptionindexoutofbounds.h" #include @@ -63,6 +64,37 @@ char *Bu::Blob::c_str() const return pData; } +char &Bu::Blob::operator[]( int32_t iIndex ) +{ + if( iIndex < 0 || iIndex >= iSize || pData == NULL ) + throw Bu::ExceptionIndexOutOfBounds(); + + return pData[iIndex]; +} + +char Bu::Blob::operator[]( int32_t iIndex ) const +{ + if( iIndex < 0 || iIndex >= iSize || pData == NULL ) + throw Bu::ExceptionIndexOutOfBounds(); + + return pData[iIndex]; +} + +bool Bu::Blob::isEmpty() const +{ + return pData != NULL && iSize == 0; +} + +bool Bu::Blob::isNull() const +{ + return pData == NULL; +} + +bool Bu::Blob::isNullOrEmpty() const +{ + return pData == NULL || iSize == 0; +} + Bu::Blob &Bu::Blob::operator=( const Bu::Blob &rRhs ) { delete[] pData; @@ -85,6 +117,210 @@ Bu::Blob &Bu::Blob::operator=( const char *pRhs ) return *this; } +bool Bu::Blob::operator==( const Bu::Blob &rRhs ) const +{ + if( pData == rRhs.pData ) + return true; + + if( iSize != rRhs.iSize ) + return false; + + for( int32_t j = 0; j < iSize; j++ ) + { + if( pData[j] != rRhs.pData[j] ) + return false; + } + + return true; +} + +bool Bu::Blob::operator==( const char *pRhs ) const +{ + if( pData == pRhs ) + return true; + + for( int32_t j = 0; j < iSize && pRhs[j]; j++ ) + { + if( pData[j] != pRhs[j] ) + return false; + } + + if( pRhs[iSize] == '\0' ) + return true; + + return false; +} + +bool Bu::Blob::operator!=( const Bu::Blob &rRhs ) const +{ + if( pData == rRhs.pData ) + return false; + + if( iSize != rRhs.iSize ) + return true; + + for( int32_t j = 0; j < iSize; j++ ) + { + if( pData[j] != rRhs.pData[j] ) + return true; + } + + return false; +} + +bool Bu::Blob::operator!=( const char *pRhs ) const +{ + if( pData == pRhs ) + return false; + + for( int32_t j = 0; j < iSize && pRhs[j]; j++ ) + { + if( pData[j] != pRhs[j] ) + return true; + } + + if( pRhs[iSize] == '\0' ) + return false; + + return true; +} + +bool Bu::Blob::operator<( const Bu::Blob &rRhs ) const +{ + if( pData == rRhs.pData ) + return false; + + for( int32_t j = 0; j < iSize && j < rRhs.iSize; j++ ) + { + if( pData[j] != rRhs.pData[j] ) + return pData[j] < rRhs.pData[j]; + } + + if( iSize < rRhs.iSize ) + return true; + + return false; +} + +bool Bu::Blob::operator<( const char *pRhs ) const +{ + if( pData == pRhs ) + return false; + + for( int32_t j = 0; j < iSize && pRhs[j]; j++ ) + { + if( pData[j] != pRhs[j] ) + return pData[j] < pRhs[j]; + } + + if( pRhs[iSize] == '\0' ) + return false; + + return true; +} + +bool Bu::Blob::operator<=( const Bu::Blob &rRhs ) const +{ + if( pData == rRhs.pData ) + return true; + + for( int32_t j = 0; j < iSize && j < rRhs.iSize; j++ ) + { + if( pData[j] != rRhs.pData[j] ) + return pData[j] < rRhs.pData[j]; + } + + return iSize <= rRhs.iSize; +} + +bool Bu::Blob::operator<=( const char *pRhs ) const +{ + if( pData == pRhs ) + return true; + + for( int32_t j = 0; j < iSize && pRhs[j]; j++ ) + { + if( pData[j] != pRhs[j] ) + return pData[j] < pRhs[j]; + } + + if( pRhs[iSize] == '\0' ) + return true; + + return true; +} + +bool Bu::Blob::operator>( const Bu::Blob &rRhs ) const +{ + if( pData == rRhs.pData ) + return false; + + for( int32_t j = 0; j < iSize && j < rRhs.iSize; j++ ) + { + if( pData[j] != rRhs.pData[j] ) + return pData[j] > rRhs.pData[j]; + } + + if( iSize > rRhs.iSize ) + return true; + + return false; +} + +bool Bu::Blob::operator>( const char *pRhs ) const +{ + if( pData == pRhs ) + return false; + + int32_t j; + for( j = 0; j < iSize && pRhs[j]; j++ ) + { + if( pData[j] != pRhs[j] ) + return pData[j] > pRhs[j]; + } + + if( pRhs[iSize] == '\0' && iSize-1 > j ) + return true; + + return false; +} + +bool Bu::Blob::operator>=( const Bu::Blob &rRhs ) const +{ + if( pData == rRhs.pData ) + return true; + + for( int32_t j = 0; j < iSize && j < rRhs.iSize; j++ ) + { + if( pData[j] != rRhs.pData[j] ) + return pData[j] > rRhs.pData[j]; + } + + return iSize >= rRhs.iSize; +} + +bool Bu::Blob::operator>=( const char *pRhs ) const +{ + if( pData == pRhs ) + return true; + + for( int32_t j = 0; j < iSize && pRhs[j]; j++ ) + { + if( pData[j] != pRhs[j] ) + return pData[j] > pRhs[j]; + } + + if( pRhs[iSize] == '\0' ) + return true; + + return true; +} + + +///// +// Iterators +// + Bu::Blob::iterator::iterator( Bu::Blob *pBlob, bool bForward ) : pBlob( pBlob ), iIndex( bForward?0:pBlob->iSize-1 ), @@ -400,4 +636,39 @@ Bu::Blob::const_iterator Bu::Blob::rend() const return const_iterator(); } +//// +// Helper functions +// +template<> uint32_t Bu::__calcHashCode( const Bu::Blob &k ) +{ + int32_t sz = k.getSize(); + const char *s = k.getData(); + + uint32_t iPos = 0; + for( int32_t j = 0; j < sz; j++, s++ ) + { + iPos = *s + (iPos << 6) + (iPos << 16) - iPos; + } + + return iPos; +} + +template<> bool Bu::__cmpHashKeys( + const Bu::Blob &a, const Bu::Blob &b ) +{ + return a == b; +} + +#include +template<> void Bu::__tracer_format( const Bu::Blob &v ) +{ + printf("(%d)\"%s\"", v.getSize(), v.getData() ); +} + +#include "bu/formatter.h" +Bu::Formatter &Bu::operator<<( Bu::Formatter &rOut, const Bu::Blob &b ) +{ + rOut.write( b.getData(), b.getSize() ); + return rOut; +} diff --git a/src/unstable/blob.h b/src/unstable/blob.h index 5b8cabd..6ce0c67 100644 --- a/src/unstable/blob.h +++ b/src/unstable/blob.h @@ -33,12 +33,31 @@ namespace Bu int32_t getSize() const; char *getData() const; - char *c_str() const; + char &operator[]( int32_t iIndex ); + char operator[]( int32_t iIndex ) const; + + bool isEmpty() const; + bool isNull() const; + bool isNullOrEmpty() const; + Blob &operator=( const Blob &rRhs ); Blob &operator=( const char *pRhs ); + bool operator==( const Blob &rRhs ) const; + bool operator==( const char *rRhs ) const; + bool operator!=( const Blob &rRhs ) const; + bool operator!=( const char *rRhs ) const; + bool operator<( const Blob &rRhs ) const; + bool operator<( const char *rRhs ) const; + bool operator<=( const Blob &rRhs ) const; + bool operator<=( const char *rRhs ) const; + bool operator>( const Blob &rRhs ) const; + bool operator>( const char *rRhs ) const; + bool operator>=( const Blob &rRhs ) const; + bool operator>=( const char *rRhs ) const; + class const_iterator; class iterator { @@ -119,6 +138,22 @@ namespace Bu char *pData; int32_t iSize; }; + + template + uint32_t __calcHashCode( const T &k ); + + template + bool __cmpHashKeys( const T &a, const T &b ); + + template<> uint32_t __calcHashCode( const Blob &k ); + template<> bool __cmpHashKeys( + const Blob &a, const Blob &b ); + + template void __tracer_format( const t &v ); + template<> void __tracer_format( const Blob &v ); + + class Formatter; + Formatter &operator<<( Formatter &rOut, const Blob &b ); } #endif -- cgit v1.2.3