From 89df61f21e525c7a36846ce1a960ffba5501cdca Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 30 Jun 2009 04:28:47 +0000 Subject: Bu::Client now gives you the option to add additional filters to the filter chain on the base stream, which for the moment is a socket. I also demonstrate this in the new rot13 test, with a rot13 filter, and a simple echo protocol. --- src/client.cpp | 25 ++++++++++------- src/client.h | 11 ++++++++ src/tests/rot13.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 src/tests/rot13.cpp diff --git a/src/client.cpp b/src/client.cpp index 43d1a08..24f9bfb 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -17,18 +17,23 @@ #define RBS (1024*2) Bu::Client::Client( Bu::Socket *pSocket, class Bu::ClientLinkFactory *pfLink ) : + pTopStream( pSocket ), pSocket( pSocket ), pProto( NULL ), nRBOffset( 0 ), bWantsDisconnect( false ), pfLink( pfLink ) { + lFilts.prepend( pSocket ); } Bu::Client::~Client() { - delete pSocket; - pSocket = NULL; + for( FilterList::iterator i = lFilts.begin(); i; i++ ) + { + delete *i; + } + pTopStream = pSocket = NULL; } void Bu::Client::processInput() @@ -40,7 +45,7 @@ void Bu::Client::processInput() { try { - nRead = pSocket->read( buf, RBS ); + nRead = pTopStream->read( buf, RBS ); if( nRead == 0 ) { @@ -50,13 +55,13 @@ void Bu::Client::processInput() { nTotal += nRead; sReadBuf.append( buf, nRead ); - if( !pSocket->canRead() ) + if( !pTopStream->canRead() ) break; } } catch( Bu::SocketException &e ) { - pSocket->close(); + pTopStream->close(); bWantsDisconnect = true; break; } @@ -64,7 +69,7 @@ void Bu::Client::processInput() if( nTotal == 0 ) { - pSocket->close(); + pTopStream->close(); bWantsDisconnect = true; } @@ -79,7 +84,7 @@ void Bu::Client::processOutput() if( sWriteBuf.getSize() > 0 ) { int nAmnt = (sWriteBuf.getSize()<2048)?(sWriteBuf.getSize()):(2048); - int nReal = pSocket->write( sWriteBuf.getStr(), nAmnt ); + int nReal = pTopStream->write( sWriteBuf.getStr(), nAmnt ); sWriteBuf.trimFront( nReal ); //sWriteBuf.clear(); } @@ -113,8 +118,8 @@ Bu::FString &Bu::Client::getOutput() bool Bu::Client::isOpen() { - if( !pSocket ) return false; - return pSocket->isOpen(); + if( !pTopStream ) return false; + return pTopStream->isOpen(); } void Bu::Client::write( const Bu::FString &sData ) @@ -235,7 +240,7 @@ bool Bu::Client::wantsDisconnect() void Bu::Client::close() { - pSocket->close(); + pTopStream->close(); } Bu::ClientLink *Bu::Client::getLink() diff --git a/src/client.h b/src/client.h index b11774e..7ba1ac5 100644 --- a/src/client.h +++ b/src/client.h @@ -66,7 +66,18 @@ namespace Bu bool hasOutput() { return !sWriteBuf.isEmpty(); } + template + void pushFilter() + { + filter *pFlt = new filter( *pTopStream ); + pTopStream = pFlt; + lFilts.prepend( pFlt ); + } + private: + typedef Bu::List FilterList; + FilterList lFilts; + Bu::Stream *pTopStream; Bu::Socket *pSocket; Bu::Protocol *pProto; Bu::FString sReadBuf; diff --git a/src/tests/rot13.cpp b/src/tests/rot13.cpp new file mode 100644 index 0000000..e677440 --- /dev/null +++ b/src/tests/rot13.cpp @@ -0,0 +1,80 @@ +#include "bu/protocol.h" +#include "bu/multiserver.h" +#include "bu/client.h" +#include "bu/filter.h" + +using namespace Bu; + +class Rot13Filter : public Filter +{ +public: + Rot13Filter( Stream &next ) : + Filter( next ) + { + } + + virtual ~Rot13Filter() + { + } + + virtual void start() + { + } + + virtual size_t stop() + { + return 0; + } + + virtual size_t read( void *pBuf, size_t nBytes ) + { + return rNext.read( pBuf, nBytes ); + } + + virtual size_t write( const void *pBuf, size_t nBytes ) + { + const char *cBuf = (const char *)pBuf; + char *buf = new char[nBytes]; + for( size_t j = 0; j < nBytes; j++ ) + { + if( cBuf[j] >= 'a' && cBuf[j] <= 'z' ) + buf[j] = (cBuf[j]-'a'+13)%26+'a'; + else if( cBuf[j] >= 'A' && cBuf[j] <= 'Z' ) + buf[j] = (cBuf[j]-'A'+13)%26+'A'; + else + buf[j] = cBuf[j]; + } + rNext.write( buf, nBytes ); + delete[] buf; + return nBytes; + } +}; + +class Rot13Protocol : public Protocol +{ +public: + void onNewConnection( Bu::Client *pClient ) + { + pClient->pushFilter(); + } + + void onNewData( Bu::Client *pClient ) + { + pClient->write( pClient->getInput().getStr(), pClient->getInputSize() ); + pClient->seek( pClient->getInputSize() ); + } +}; + +int main() +{ + MultiServer xSrv; + + xSrv.setTimeout( 5 ); + xSrv.addProtocol( genProtocol, 9999 ); + + for(;;) + xSrv.scan(); + + return 0; +} + -- cgit v1.2.3