summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2009-06-30 04:28:47 +0000
committerMike Buland <eichlan@xagasoft.com>2009-06-30 04:28:47 +0000
commit89df61f21e525c7a36846ce1a960ffba5501cdca (patch)
tree0789e81c229b8f55521ca1c14e01c74165bae99b
parent4556c5f625ed143a2334acc26505b658b719b451 (diff)
downloadlibbu++-89df61f21e525c7a36846ce1a960ffba5501cdca.tar.gz
libbu++-89df61f21e525c7a36846ce1a960ffba5501cdca.tar.bz2
libbu++-89df61f21e525c7a36846ce1a960ffba5501cdca.tar.xz
libbu++-89df61f21e525c7a36846ce1a960ffba5501cdca.zip
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.
Diffstat (limited to '')
-rw-r--r--src/client.cpp25
-rw-r--r--src/client.h11
-rw-r--r--src/tests/rot13.cpp80
3 files changed, 106 insertions, 10 deletions
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 @@
17#define RBS (1024*2) 17#define RBS (1024*2)
18 18
19Bu::Client::Client( Bu::Socket *pSocket, class Bu::ClientLinkFactory *pfLink ) : 19Bu::Client::Client( Bu::Socket *pSocket, class Bu::ClientLinkFactory *pfLink ) :
20 pTopStream( pSocket ),
20 pSocket( pSocket ), 21 pSocket( pSocket ),
21 pProto( NULL ), 22 pProto( NULL ),
22 nRBOffset( 0 ), 23 nRBOffset( 0 ),
23 bWantsDisconnect( false ), 24 bWantsDisconnect( false ),
24 pfLink( pfLink ) 25 pfLink( pfLink )
25{ 26{
27 lFilts.prepend( pSocket );
26} 28}
27 29
28Bu::Client::~Client() 30Bu::Client::~Client()
29{ 31{
30 delete pSocket; 32 for( FilterList::iterator i = lFilts.begin(); i; i++ )
31 pSocket = NULL; 33 {
34 delete *i;
35 }
36 pTopStream = pSocket = NULL;
32} 37}
33 38
34void Bu::Client::processInput() 39void Bu::Client::processInput()
@@ -40,7 +45,7 @@ void Bu::Client::processInput()
40 { 45 {
41 try 46 try
42 { 47 {
43 nRead = pSocket->read( buf, RBS ); 48 nRead = pTopStream->read( buf, RBS );
44 49
45 if( nRead == 0 ) 50 if( nRead == 0 )
46 { 51 {
@@ -50,13 +55,13 @@ void Bu::Client::processInput()
50 { 55 {
51 nTotal += nRead; 56 nTotal += nRead;
52 sReadBuf.append( buf, nRead ); 57 sReadBuf.append( buf, nRead );
53 if( !pSocket->canRead() ) 58 if( !pTopStream->canRead() )
54 break; 59 break;
55 } 60 }
56 } 61 }
57 catch( Bu::SocketException &e ) 62 catch( Bu::SocketException &e )
58 { 63 {
59 pSocket->close(); 64 pTopStream->close();
60 bWantsDisconnect = true; 65 bWantsDisconnect = true;
61 break; 66 break;
62 } 67 }
@@ -64,7 +69,7 @@ void Bu::Client::processInput()
64 69
65 if( nTotal == 0 ) 70 if( nTotal == 0 )
66 { 71 {
67 pSocket->close(); 72 pTopStream->close();
68 bWantsDisconnect = true; 73 bWantsDisconnect = true;
69 } 74 }
70 75
@@ -79,7 +84,7 @@ void Bu::Client::processOutput()
79 if( sWriteBuf.getSize() > 0 ) 84 if( sWriteBuf.getSize() > 0 )
80 { 85 {
81 int nAmnt = (sWriteBuf.getSize()<2048)?(sWriteBuf.getSize()):(2048); 86 int nAmnt = (sWriteBuf.getSize()<2048)?(sWriteBuf.getSize()):(2048);
82 int nReal = pSocket->write( sWriteBuf.getStr(), nAmnt ); 87 int nReal = pTopStream->write( sWriteBuf.getStr(), nAmnt );
83 sWriteBuf.trimFront( nReal ); 88 sWriteBuf.trimFront( nReal );
84 //sWriteBuf.clear(); 89 //sWriteBuf.clear();
85 } 90 }
@@ -113,8 +118,8 @@ Bu::FString &Bu::Client::getOutput()
113 118
114bool Bu::Client::isOpen() 119bool Bu::Client::isOpen()
115{ 120{
116 if( !pSocket ) return false; 121 if( !pTopStream ) return false;
117 return pSocket->isOpen(); 122 return pTopStream->isOpen();
118} 123}
119 124
120void Bu::Client::write( const Bu::FString &sData ) 125void Bu::Client::write( const Bu::FString &sData )
@@ -235,7 +240,7 @@ bool Bu::Client::wantsDisconnect()
235 240
236void Bu::Client::close() 241void Bu::Client::close()
237{ 242{
238 pSocket->close(); 243 pTopStream->close();
239} 244}
240 245
241Bu::ClientLink *Bu::Client::getLink() 246Bu::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
66 66
67 bool hasOutput() { return !sWriteBuf.isEmpty(); } 67 bool hasOutput() { return !sWriteBuf.isEmpty(); }
68 68
69 template<typename filter>
70 void pushFilter()
71 {
72 filter *pFlt = new filter( *pTopStream );
73 pTopStream = pFlt;
74 lFilts.prepend( pFlt );
75 }
76
69 private: 77 private:
78 typedef Bu::List<Bu::Stream *> FilterList;
79 FilterList lFilts;
80 Bu::Stream *pTopStream;
70 Bu::Socket *pSocket; 81 Bu::Socket *pSocket;
71 Bu::Protocol *pProto; 82 Bu::Protocol *pProto;
72 Bu::FString sReadBuf; 83 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 @@
1#include "bu/protocol.h"
2#include "bu/multiserver.h"
3#include "bu/client.h"
4#include "bu/filter.h"
5
6using namespace Bu;
7
8class Rot13Filter : public Filter
9{
10public:
11 Rot13Filter( Stream &next ) :
12 Filter( next )
13 {
14 }
15
16 virtual ~Rot13Filter()
17 {
18 }
19
20 virtual void start()
21 {
22 }
23
24 virtual size_t stop()
25 {
26 return 0;
27 }
28
29 virtual size_t read( void *pBuf, size_t nBytes )
30 {
31 return rNext.read( pBuf, nBytes );
32 }
33
34 virtual size_t write( const void *pBuf, size_t nBytes )
35 {
36 const char *cBuf = (const char *)pBuf;
37 char *buf = new char[nBytes];
38 for( size_t j = 0; j < nBytes; j++ )
39 {
40 if( cBuf[j] >= 'a' && cBuf[j] <= 'z' )
41 buf[j] = (cBuf[j]-'a'+13)%26+'a';
42 else if( cBuf[j] >= 'A' && cBuf[j] <= 'Z' )
43 buf[j] = (cBuf[j]-'A'+13)%26+'A';
44 else
45 buf[j] = cBuf[j];
46 }
47 rNext.write( buf, nBytes );
48 delete[] buf;
49 return nBytes;
50 }
51};
52
53class Rot13Protocol : public Protocol
54{
55public:
56 void onNewConnection( Bu::Client *pClient )
57 {
58 pClient->pushFilter<Rot13Filter>();
59 }
60
61 void onNewData( Bu::Client *pClient )
62 {
63 pClient->write( pClient->getInput().getStr(), pClient->getInputSize() );
64 pClient->seek( pClient->getInputSize() );
65 }
66};
67
68int main()
69{
70 MultiServer xSrv;
71
72 xSrv.setTimeout( 5 );
73 xSrv.addProtocol( genProtocol<Rot13Protocol>, 9999 );
74
75 for(;;)
76 xSrv.scan();
77
78 return 0;
79}
80