From 8b12972092777af56ae21f65b41f4c40d52c2367 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 18 Jun 2007 19:42:34 +0000 Subject: Added the protocol class. servers work, but don't send data, updated the streams to include many more state indicators and caps queries, and everything is working better in general. --- src/bzip2.cpp | 7 +++++- src/bzip2.h | 2 ++ src/client.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/client.h | 20 +++++++++++++--- src/file.cpp | 17 +++++++++++++- src/file.h | 6 ++++- src/filter.cpp | 19 ++++++++++++++-- src/filter.h | 6 ++++- src/protocol.cpp | 12 ++++++++++ src/protocol.h | 26 +++++++++++++++++++++ src/server.cpp | 11 ++++++--- src/server.h | 8 +++++-- src/socket.cpp | 48 ++++++++++++++++++++++++++++++++------- src/socket.h | 6 ++++- src/stream.h | 35 +++++++++++++++++++++++++++- 15 files changed, 266 insertions(+), 26 deletions(-) create mode 100644 src/protocol.cpp create mode 100644 src/protocol.h diff --git a/src/bzip2.cpp b/src/bzip2.cpp index d3f237a..66786e4 100644 --- a/src/bzip2.cpp +++ b/src/bzip2.cpp @@ -128,7 +128,7 @@ size_t Bu::BZip2::read( void *pData, size_t nBytes ) { if( bzState.avail_in > 0 ) { - if( rNext.canSeek() ) + if( rNext.isSeekable() ) { rNext.seek( -bzState.avail_in ); } @@ -185,3 +185,8 @@ size_t Bu::BZip2::write( const void *pData, size_t nBytes ) return sTotalOut; } +bool Bu::BZip2::isOpen() +{ + return (bzState.state != NULL); +} + diff --git a/src/bzip2.h b/src/bzip2.h index a23f07a..25f10c5 100644 --- a/src/bzip2.h +++ b/src/bzip2.h @@ -22,6 +22,8 @@ namespace Bu virtual size_t read( void *pBuf, size_t nBytes ); virtual size_t write( const void *pBuf, size_t nBytes ); + virtual bool isOpen(); + private: void bzError( int code ); bz_stream bzState; diff --git a/src/client.cpp b/src/client.cpp index a33cdc3..cf96424 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1,6 +1,16 @@ -#include "client.h" +#include "bu/client.h" +#include "bu/socket.h" +#include +#include +#include "bu/exceptions.h" +#include "bu/protocol.h" -Bu::Client::Client() +/** Read buffer size. */ +#define RBS (1024*2) + +Bu::Client::Client( Bu::Socket *pSocket ) : + pSocket( pSocket ), + pProto( NULL ) { } @@ -8,3 +18,58 @@ Bu::Client::~Client() { } +void Bu::Client::processInput() +{ + char buf[RBS]; + size_t nRead, nTotal=0; + + for(;;) + { + nRead = pSocket->read( buf, nRead ); + if( nRead < 0 ) + { + throw Bu::ConnectionException( + excodeReadError, + "Read error: %s", + strerror( errno ) + ); + } + else if( nRead == 0 ) + { + break; + } + else + { + nTotal += nRead; + sReadBuf.append( buf, nRead ); + if( !pSocket->canRead() ) + break; + } + } + + if( pProto && nTotal ) + { + pProto->onNewData( this ); + } +} + +void Bu::Client::setProtocol( Protocol *pProto ) +{ + this->pProto = pProto; +} + +Bu::Protocol *Bu::Client::getProtocol() +{ + return pProto; +} + +void Bu::Client::clearProtocol() +{ + pProto = NULL; +} + +Bu::FString &Bu::Client::getInput() +{ + return sReadBuf; +} + diff --git a/src/client.h b/src/client.h index 27fbad4..1a189e2 100644 --- a/src/client.h +++ b/src/client.h @@ -2,21 +2,35 @@ #define CLIENT_H #include -#include "bu/socket.h" + +#include "bu/fstring.h" namespace Bu { + class Protocol; + class Socket; + /** * */ class Client { public: - Client(); + Client( Bu::Socket *pSocket ); virtual ~Client(); - private: + void processInput(); + Bu::FString &getInput(); + + void setProtocol( Protocol *pProto ); + Bu::Protocol *getProtocol(); + void clearProtocol(); + + private: + Bu::Socket *pSocket; + Bu::Protocol *pProto; + Bu::FString sReadBuf; }; } diff --git a/src/file.cpp b/src/file.cpp index 2965afa..368b788 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -109,7 +109,17 @@ bool Bu::File::canWrite() return true; } -bool Bu::File::canSeek() +bool Bu::File::isReadable() +{ + return true; +} + +bool Bu::File::isWritable() +{ + return true; +} + +bool Bu::File::isSeekable() { return true; } @@ -139,3 +149,8 @@ void Bu::File::chmod( mode_t t ) fchmod( fileno( fh ), t ); } +bool Bu::File::isOpen() +{ + return (fh != NULL); +} + diff --git a/src/file.h b/src/file.h index 8107a1b..fe8dbda 100644 --- a/src/file.h +++ b/src/file.h @@ -25,12 +25,16 @@ namespace Bu virtual void setPos( long pos ); virtual void setPosEnd( long pos ); virtual bool isEOS(); + virtual bool isOpen(); virtual void flush(); virtual bool canRead(); virtual bool canWrite(); - virtual bool canSeek(); + + virtual bool isReadable(); + virtual bool isWritable(); + virtual bool isSeekable(); virtual bool isBlocking(); virtual void setBlocking( bool bBlocking=true ); diff --git a/src/filter.cpp b/src/filter.cpp index 693fb9f..96a8694 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -50,6 +50,11 @@ bool Bu::Filter::isEOS() return rNext.isEOS(); } +bool Bu::Filter::isOpen() +{ + return rNext.isOpen(); +} + bool Bu::Filter::canRead() { return rNext.canRead(); @@ -60,9 +65,19 @@ bool Bu::Filter::canWrite() return rNext.canWrite(); } -bool Bu::Filter::canSeek() +bool Bu::Filter::isReadable() +{ + return rNext.isReadable(); +} + +bool Bu::Filter::isWritable() +{ + return rNext.isWritable(); +} + +bool Bu::Filter::isSeekable() { - return rNext.canSeek(); + return rNext.isSeekable(); } bool Bu::Filter::isBlocking() diff --git a/src/filter.h b/src/filter.h index 088d46e..7bb04bc 100644 --- a/src/filter.h +++ b/src/filter.h @@ -40,12 +40,16 @@ namespace Bu virtual void setPos( long pos ); virtual void setPosEnd( long pos ); virtual bool isEOS(); + virtual bool isOpen(); virtual void flush(); virtual bool canRead(); virtual bool canWrite(); - virtual bool canSeek(); + + virtual bool isReadable(); + virtual bool isWritable(); + virtual bool isSeekable(); virtual bool isBlocking(); virtual void setBlocking( bool bBlocking=true ); diff --git a/src/protocol.cpp b/src/protocol.cpp new file mode 100644 index 0000000..0976b3b --- /dev/null +++ b/src/protocol.cpp @@ -0,0 +1,12 @@ +#include "bu/protocol.h" + +using namespace Bu; + +Bu::Protocol::Protocol() +{ +} + +Bu::Protocol::~Protocol() +{ +} + diff --git a/src/protocol.h b/src/protocol.h new file mode 100644 index 0000000..3accd99 --- /dev/null +++ b/src/protocol.h @@ -0,0 +1,26 @@ +#ifndef PROTOCOL_H +#define PROTOCOL_H + +#include + +namespace Bu +{ + class Client; + + /** + * + */ + class Protocol + { + public: + Protocol(); + virtual ~Protocol(); + + virtual void onNewData( Bu::Client *pClient )=0; + + private: + + }; +} + +#endif diff --git a/src/server.cpp b/src/server.cpp index abf4c5b..bceeb81 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,5 +1,8 @@ -#include "server.h" +#include "bu/server.h" #include +#include "bu/serversocket.h" +#include "bu/client.h" +#include "bu/socket.h" Bu::Server::Server() : nTimeoutSec( 0 ), @@ -58,7 +61,7 @@ void Bu::Server::scan() } else { - + hClients.get( j )->processInput(); } } } @@ -68,7 +71,9 @@ void Bu::Server::addClient( int nSocket, int nPort ) { FD_SET( nSocket, &fdActive ); - Client *c = new Client(); + Client *c = new Client( + new Bu::Socket( nSocket ) + ); hClients.insert( nSocket, c ); onNewConnection( c, nPort ); diff --git a/src/server.h b/src/server.h index 942eb32..3331d2c 100644 --- a/src/server.h +++ b/src/server.h @@ -2,12 +2,16 @@ #define SERVER_H #include -#include "bu/serversocket.h" + +#include "bu/fstring.h" #include "bu/list.h" -#include "bu/client.h" namespace Bu { + class ServerSocket; + class Socket; + class Client; + /** * Core of a network server. This class is distinct from a ServerSocket in * that a ServerSocket is one listening socket, nothing more. Socket will diff --git a/src/socket.cpp b/src/socket.cpp index 1832898..bd05024 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -109,13 +109,6 @@ void Bu::Socket::close() ::close( nSocket ); } bActive = false; - //xInputBuf.clearData(); - //xOutputBuf.clearData(); - //if( pProtocol != NULL ) - //{ - // delete pProtocol; - // pProtocol = NULL; - //} } /* @@ -218,15 +211,49 @@ bool Bu::Socket::isEOS() bool Bu::Socket::canRead() { + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(nSocket, &rfds); + struct timeval tv = { 0, 0 }; + int retval = select( nSocket+1, &rfds, NULL, NULL, &tv ); + if( retval == -1 ) + throw ConnectionException( + excodeBadReadError, + "Bad Read error" + ); + if( !FD_ISSET( nSocket, &rfds ) ) + return false; return true; } bool Bu::Socket::canWrite() { + fd_set wfds; + FD_ZERO(&wfds); + FD_SET(nSocket, &wfds); + struct timeval tv = { 0, 0 }; + int retval = select( nSocket+1, NULL, &wfds, NULL, &tv ); + if( retval == -1 ) + throw ConnectionException( + excodeBadReadError, + "Bad Read error" + ); + if( !FD_ISSET( nSocket, &wfds ) ) + return false; return true; } -bool Bu::Socket::canSeek() +bool Bu::Socket::isReadable() +{ + return true; +} + +bool Bu::Socket::isWritable() +{ + return true; +} + +bool Bu::Socket::isSeekable() { return false; } @@ -244,3 +271,8 @@ void Bu::Socket::flush() { } +bool Bu::Socket::isOpen() +{ + return bActive; +} + diff --git a/src/socket.h b/src/socket.h index 30a43fb..c9dbd8d 100644 --- a/src/socket.h +++ b/src/socket.h @@ -28,12 +28,16 @@ namespace Bu virtual void setPos( long pos ); virtual void setPosEnd( long pos ); virtual bool isEOS(); + virtual bool isOpen(); virtual void flush(); virtual bool canRead(); virtual bool canWrite(); - virtual bool canSeek(); + + virtual bool isReadable(); + virtual bool isWritable(); + virtual bool isSeekable(); virtual bool isBlocking(); virtual void setBlocking( bool bBlocking=true ); diff --git a/src/stream.h b/src/stream.h index a80586b..ba070d3 100644 --- a/src/stream.h +++ b/src/stream.h @@ -31,12 +31,45 @@ namespace Bu virtual void setPos( long pos ) = 0; virtual void setPosEnd( long pos ) = 0; virtual bool isEOS() = 0; + virtual bool isOpen() = 0; virtual void flush() = 0; + /** + * In non-blocking streams this indicates if a read operation will + * return data at the moment or not. In blocking streams this should + * return the same value as isEOS(). + */ virtual bool canRead() = 0; + + /** + * In non-blocking streams this indicates if a write operation will + * succeed or fail. In some cases writing is not allowed (e.g. + * internal buffers are full) temporarilly. In blocking streams this + * should return the same value as isWritable. + */ virtual bool canWrite() = 0; - virtual bool canSeek() = 0; + + /** + * Indicates if the stream is capable of read operations. This does not + * indicate if such operations will return useful data, see canRead for + * that. + */ + virtual bool isReadable() = 0; + + /** + * Indicates if the stream is capable of write operations. This does + * not indicate if such operations will succeed or fail, see canWrite + * for that. + */ + virtual bool isWritable() = 0; + + /** + * Indicates if the stream is capable of seek operations. This is + * generally false for non-blocking streams. Some buffered streams may + * support limited in-buffer seeking. + */ + virtual bool isSeekable() = 0; virtual bool isBlocking() = 0; virtual void setBlocking( bool bBlocking=true ) = 0; -- cgit v1.2.3