From 611f1c821f9d882f935ac62b0c566d4988f26d1c Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sun, 22 Aug 2010 05:34:12 +0000 Subject: Bu::StreamStack works, it's tested, reasonably, it will be used first in the gats project in Gats::ProtocolGats. --- default.bld | 2 +- src/streamstack.cpp | 120 ++++++++++++++++++++++++++++++++++++++++++++++ src/streamstack.h | 89 +++++++++++++++++++++++++++++++++- src/tests/streamstack.cpp | 93 +++++++++++++++++++++++++++++++++++ 4 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 src/tests/streamstack.cpp diff --git a/default.bld b/default.bld index cb5a4d9..857e988 100644 --- a/default.bld +++ b/default.bld @@ -97,7 +97,7 @@ target files("src/tests/*.cpp").replace("src/","").replace(".cpp","") // Some tests need extra libs and whatnot, that goes here. -target "tests/bzip2" +target ["tests/bzip2", "tests/streamstack"] { LDFLAGS += "-lbz2"; } diff --git a/src/streamstack.cpp b/src/streamstack.cpp index 9e45cc4..c7f8af5 100644 --- a/src/streamstack.cpp +++ b/src/streamstack.cpp @@ -4,83 +4,203 @@ Bu::StreamStack::StreamStack() { } +Bu::StreamStack::StreamStack( Bu::Stream *pStream ) +{ + lFilts.prepend( pStream ); +} + Bu::StreamStack::~StreamStack() { + clearStack(); +} + +bool Bu::StreamStack::isEmpty() +{ + return lFilts.isEmpty(); +} + +bool Bu::StreamStack::hasStream() +{ + return !lFilts.isEmpty(); +} + +void Bu::StreamStack::setStream( Bu::Stream *pStream ) +{ + if( !lFilts.isEmpty() ) + throw Bu::ExceptionBase("There is already a stream set."); + + lFilts.prepend( pStream ); +} + +void Bu::StreamStack::clearStack() +{ + for( FilterList::iterator i = lFilts.begin(); i; i++ ) + { + delete *i; + } + + lFilts.clear(); +} + +void Bu::StreamStack::popFilter() +{ + if( lFilts.isEmpty() ) + return; + + delete lFilts.first(); + lFilts.erase( lFilts.begin() ); +} + +Bu::Stream *Bu::StreamStack::getTop() +{ + checkStack(); + + return lFilts.first(); +} + +Bu::Stream *Bu::StreamStack::getStream() +{ + checkStack(); + + return lFilts.last(); } void Bu::StreamStack::close() { + checkStack(); + + lFilts.first()->close(); } size_t Bu::StreamStack::read( void *pBuf, size_t nBytes ) { + checkStack(); + + return lFilts.first()->read( pBuf, nBytes ); } size_t Bu::StreamStack::write( const void *pBuf, size_t nBytes ) { + checkStack(); + + return lFilts.first()->write( pBuf, nBytes ); } size_t Bu::StreamStack::write( const Bu::FString &sBuf ) { + checkStack(); + + return lFilts.first()->write( sBuf ); } long Bu::StreamStack::tell() { + checkStack(); + + return lFilts.first()->tell(); } void Bu::StreamStack::seek( long offset ) { + checkStack(); + + lFilts.first()->seek( offset ); } void Bu::StreamStack::setPos( long pos ) { + checkStack(); + + lFilts.first()->setPos( pos ); } void Bu::StreamStack::setPosEnd( long pos ) { + checkStack(); + + lFilts.first()->setPosEnd( pos ); } bool Bu::StreamStack::isEos() { + checkStack(); + + return lFilts.first()->isEos(); } bool Bu::StreamStack::isOpen() { + checkStack(); + + return lFilts.first()->isOpen(); } void Bu::StreamStack::flush() { + checkStack(); + + lFilts.first()->flush(); } bool Bu::StreamStack::canRead() { + checkStack(); + + return lFilts.first()->canRead(); } bool Bu::StreamStack::canWrite() { + checkStack(); + + return lFilts.first()->canWrite(); } bool Bu::StreamStack::isReadable() { + checkStack(); + + return lFilts.first()->isReadable(); } bool Bu::StreamStack::isWritable() { + checkStack(); + + return lFilts.first()->isWritable(); } bool Bu::StreamStack::isSeekable() { + checkStack(); + + return lFilts.first()->isSeekable(); } bool Bu::StreamStack::isBlocking() { + checkStack(); + + return lFilts.first()->isBlocking(); } void Bu::StreamStack::setBlocking( bool bBlocking ) { + checkStack(); + + lFilts.first()->setBlocking( bBlocking ); } void Bu::StreamStack::setSize( long iSize ) { + checkStack(); + + lFilts.first()->setSize( iSize ); +} + +inline void Bu::StreamStack::checkStack() +{ + if( lFilts.isEmpty() ) + throw Bu::ExceptionBase("StreamStack is empty."); } diff --git a/src/streamstack.h b/src/streamstack.h index 03d8d8f..89e683d 100644 --- a/src/streamstack.h +++ b/src/streamstack.h @@ -3,14 +3,99 @@ #include "bu/stream.h" +#include + namespace Bu { class StreamStack : public Bu::Stream { + private: + typedef Bu::List FilterList; + public: StreamStack(); + StreamStack( Bu::Stream *pStream ); virtual ~StreamStack(); + bool isEmpty(); + bool hasStream(); + void setStream( Bu::Stream *pStream ); + + void clearStack(); + void popFilter(); + Bu::Stream *getTop(); + + Bu::Stream *getStream(); + + template + Bu::Stream *findFilter() + { + for( FilterList::iterator i = lFilts.begin(); i; i++ ) + { + if( typeid(**i) == typeid( filter ) ) + { + return *i; + } + } + + throw Bu::ExceptionBase("Filter not found."); + } + + template + void pushFilter() + { + checkStack(); + + filter *pFlt = new filter( *lFilts.first() ); + lFilts.prepend( pFlt ); + } + + template + void pushFilter( p1t p1 ) + { + checkStack(); + + filter *pFlt = new filter( *lFilts.first(), p1 ); + lFilts.prepend( pFlt ); + } + + template + void pushFilter( p1t p1, p2t p2 ) + { + checkStack(); + + filter *pFlt = new filter( *lFilts.first(), p1, p2 ); + lFilts.prepend( pFlt ); + } + + template + void pushFilter( p1t p1, p2t p2, p3t p3 ) + { + checkStack(); + + filter *pFlt = new filter( *lFilts.first(), p1, p2, p3 ); + lFilts.prepend( pFlt ); + } + + template + void pushFilter( p1t p1, p2t p2, p3t p3, p4t p4 ) + { + checkStack(); + + filter *pFlt = new filter( *lFilts.first(), p1, p2, p3, p4 ); + lFilts.prepend( pFlt ); + } + + template + void pushFilter( p1t p1, p2t p2, p3t p3, p4t p4, p5t p5 ) + { + checkStack(); + + filter *pFlt = new filter( *lFilts.first(), p1, p2, p3, p4, p5 ); + lFilts.prepend( pFlt ); + } // // Everything below here merely passes on the call to the top of the @@ -39,7 +124,9 @@ namespace Bu virtual void setSize( long iSize ); private: - typedef Bu::List FilterList; + void checkStack(); + + private: FilterList lFilts; }; }; diff --git a/src/tests/streamstack.cpp b/src/tests/streamstack.cpp new file mode 100644 index 0000000..56a7076 --- /dev/null +++ b/src/tests/streamstack.cpp @@ -0,0 +1,93 @@ +#include "bu/streamstack.h" + +#include "bu/file.h" +#include "bu/base64.h" +#include "bu/bzip2.h" + +#include "bu/sio.h" + +#include + +using namespace Bu; + +class DoStuff +{ +public: + DoStuff( Bu::Stream &rStream ) : + rStream( rStream ) + { + } + + virtual ~DoStuff() + { + } + + void write() + { + Bu::FString s; + time_t tNow = time( NULL ); + s = ctime( &tNow ); + long lSize = s.getSize()-1; + rStream.write( &lSize, sizeof(long) ); + rStream.write( s.getStr(), lSize ); + } + + void read() + { + Bu::FString s; + long lSize; + rStream.read( &lSize, sizeof(long) ); + s.setSize( lSize ); + rStream.read( s.getStr(), lSize ); + sio << "Read str(" << lSize << ") = '" << s << "'" << sio.nl; + } + +private: + Bu::Stream &rStream; +}; + +int main() +{ + Bu::StreamStack ss; + + DoStuff ds( ss ); + + try + { + ds.write(); + sio << "This shouldn't have worked." << sio.nl; + } + catch( Bu::ExceptionBase &e ) + { + sio << "Got exception, this is good: " << e.what() << sio.nl; + } + + ss.setStream( new Bu::File("Hello.test", Bu::File::WriteNew ) ); + + ds.write(); + + ss.pushFilter(); + + ds.write(); + + ss.pushFilter(); + + ds.write(); + + ss.clearStack(); + + ss.setStream( new Bu::File("Hello.test", Bu::File::Read ) ); + + ds.read(); + + ss.pushFilter(); + + ds.read(); + + ss.pushFilter(); + + ds.read(); + + return 0; +} + -- cgit v1.2.3