diff options
author | Mike Buland <eichlan@xagasoft.com> | 2007-05-17 05:56:26 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2007-05-17 05:56:26 +0000 |
commit | e0e7932a122614a0ff566fbfd8de5776de8b9f6d (patch) | |
tree | ae87ab46b677bfd05f340051a56f1edbc94862a9 /src | |
parent | dda94f3b53e02e117e6eb5758afa1410e1664c9f (diff) | |
download | libbu++-e0e7932a122614a0ff566fbfd8de5776de8b9f6d.tar.gz libbu++-e0e7932a122614a0ff566fbfd8de5776de8b9f6d.tar.bz2 libbu++-e0e7932a122614a0ff566fbfd8de5776de8b9f6d.tar.xz libbu++-e0e7932a122614a0ff566fbfd8de5776de8b9f6d.zip |
Lots of cool new stuff, the Server class actually works for everything except
actually interacting with clients, and the Client class is almost there, except
that it doesn't really do anything yet.
Diffstat (limited to 'src')
-rw-r--r-- | src/client.cpp | 9 | ||||
-rw-r--r-- | src/client.h | 23 | ||||
-rw-r--r-- | src/file.cpp | 10 | ||||
-rw-r--r-- | src/file.h | 3 | ||||
-rw-r--r-- | src/list.h | 5 | ||||
-rw-r--r-- | src/old/singleton.h | 59 | ||||
-rw-r--r-- | src/server.cpp | 73 | ||||
-rw-r--r-- | src/server.h | 49 | ||||
-rw-r--r-- | src/serversocket.cpp | 5 | ||||
-rw-r--r-- | src/serversocket.h | 3 | ||||
-rw-r--r-- | src/singleton.h | 62 | ||||
-rw-r--r-- | src/socket.cpp | 9 | ||||
-rw-r--r-- | src/socket.h | 3 | ||||
-rw-r--r-- | src/stream.h | 3 | ||||
-rw-r--r-- | src/tests/hash.cpp | 24 |
15 files changed, 279 insertions, 61 deletions
diff --git a/src/client.cpp b/src/client.cpp new file mode 100644 index 0000000..a048ca3 --- /dev/null +++ b/src/client.cpp | |||
@@ -0,0 +1,9 @@ | |||
1 | #include "client.h" | ||
2 | |||
3 | Bu::Client::Client() | ||
4 | { | ||
5 | } | ||
6 | |||
7 | Bu::Client::~Client() | ||
8 | { | ||
9 | } | ||
diff --git a/src/client.h b/src/client.h new file mode 100644 index 0000000..27fbad4 --- /dev/null +++ b/src/client.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef CLIENT_H | ||
2 | #define CLIENT_H | ||
3 | |||
4 | #include <stdint.h> | ||
5 | #include "bu/socket.h" | ||
6 | |||
7 | namespace Bu | ||
8 | { | ||
9 | /** | ||
10 | * | ||
11 | */ | ||
12 | class Client | ||
13 | { | ||
14 | public: | ||
15 | Client(); | ||
16 | virtual ~Client(); | ||
17 | |||
18 | private: | ||
19 | |||
20 | }; | ||
21 | } | ||
22 | |||
23 | #endif | ||
diff --git a/src/file.cpp b/src/file.cpp index 5de5f6c..26986a5 100644 --- a/src/file.cpp +++ b/src/file.cpp | |||
@@ -98,3 +98,13 @@ bool Bu::File::canSeek() | |||
98 | return true; | 98 | return true; |
99 | } | 99 | } |
100 | 100 | ||
101 | bool Bu::File::isBlocking() | ||
102 | { | ||
103 | return true; | ||
104 | } | ||
105 | |||
106 | void Bu::File::setBlocking( bool bBlocking ) | ||
107 | { | ||
108 | return; | ||
109 | } | ||
110 | |||
@@ -27,6 +27,9 @@ namespace Bu | |||
27 | virtual bool canWrite(); | 27 | virtual bool canWrite(); |
28 | virtual bool canSeek(); | 28 | virtual bool canSeek(); |
29 | 29 | ||
30 | virtual bool isBlocking(); | ||
31 | virtual void setBlocking( bool bBlocking=true ); | ||
32 | |||
30 | private: | 33 | private: |
31 | FILE *fh; | 34 | FILE *fh; |
32 | 35 | ||
@@ -217,6 +217,11 @@ namespace Bu | |||
217 | { | 217 | { |
218 | } | 218 | } |
219 | 219 | ||
220 | const_iterator( const iterator &i ) : | ||
221 | pLink( i.pLink ) | ||
222 | { | ||
223 | } | ||
224 | |||
220 | public: | 225 | public: |
221 | bool operator==( const const_iterator &oth ) const | 226 | bool operator==( const const_iterator &oth ) const |
222 | { | 227 | { |
diff --git a/src/old/singleton.h b/src/old/singleton.h deleted file mode 100644 index 47adbd5..0000000 --- a/src/old/singleton.h +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | #ifndef SINGLETON_H | ||
2 | #define SINGLETON_H | ||
3 | |||
4 | #include <stdio.h> | ||
5 | |||
6 | /** | ||
7 | * Provides singleton functionality in a modular sort of way. Make this the | ||
8 | * base class of any other class and you immediately gain singleton | ||
9 | * functionality. Be sure to make your constructor and various functions use | ||
10 | * intellegent scoping. Cleanup and instantiation are performed automatically | ||
11 | * for you at first use and program exit. There are two things that you must | ||
12 | * do when using this template, first is to inherit from it with the name of | ||
13 | * your class filling in for T and then make this class a friend of your class. | ||
14 | *@code | ||
15 | * // Making the Single Singleton: | ||
16 | * class Single : public Singleton<Single> | ||
17 | * { | ||
18 | * friend class Singleton<Single>; | ||
19 | * protected: | ||
20 | * Single(); | ||
21 | * ... | ||
22 | * }; | ||
23 | @endcode | ||
24 | * You can still add public functions and variables to your new Singleton child | ||
25 | * class, but your constructor should be protected (hence the need for the | ||
26 | * friend decleration). | ||
27 | *@author Mike Buland | ||
28 | */ | ||
29 | template <class T> | ||
30 | class Singleton | ||
31 | { | ||
32 | protected: | ||
33 | /** | ||
34 | * Private constructor. This constructor is empty but has a body so that | ||
35 | * you can make your own override of it. Be sure that you're override is | ||
36 | * also protected. | ||
37 | */ | ||
38 | Singleton() {}; | ||
39 | |||
40 | private: | ||
41 | /** | ||
42 | * Copy constructor, defined so that you could write your own as well. | ||
43 | */ | ||
44 | Singleton( const Singleton& ); | ||
45 | |||
46 | public: | ||
47 | /** | ||
48 | * Get a handle to the contained instance of the contained class. It is | ||
49 | * a reference. | ||
50 | *@returns A reference to the contained object. | ||
51 | */ | ||
52 | static T &getInstance() | ||
53 | { | ||
54 | static T i; | ||
55 | return i; | ||
56 | } | ||
57 | }; | ||
58 | |||
59 | #endif | ||
diff --git a/src/server.cpp b/src/server.cpp new file mode 100644 index 0000000..f93238c --- /dev/null +++ b/src/server.cpp | |||
@@ -0,0 +1,73 @@ | |||
1 | #include "server.h" | ||
2 | #include <errno.h> | ||
3 | |||
4 | Bu::Server::Server() : | ||
5 | nTimeoutSec( 0 ), | ||
6 | nTimeoutUSec( 0 ) | ||
7 | { | ||
8 | FD_ZERO( &fdActive ); | ||
9 | } | ||
10 | |||
11 | Bu::Server::~Server() | ||
12 | { | ||
13 | } | ||
14 | |||
15 | void Bu::Server::addPort( int nPort, int nPoolSize ) | ||
16 | { | ||
17 | ServerSocket *s = new ServerSocket( nPort, nPoolSize ); | ||
18 | int nSocket = s->getSocket(); | ||
19 | FD_SET( nSocket, &fdActive ); | ||
20 | hServers.insert( nSocket, s ); | ||
21 | } | ||
22 | |||
23 | void Bu::Server::addPort( const FString &sAddr, int nPort, int nPoolSize ) | ||
24 | { | ||
25 | ServerSocket *s = new ServerSocket( sAddr, nPort, nPoolSize ); | ||
26 | int nSocket = s->getSocket(); | ||
27 | FD_SET( nSocket, &fdActive ); | ||
28 | hServers.insert( nSocket, s ); | ||
29 | } | ||
30 | |||
31 | void Bu::Server::setTimeout( int nTimeoutSec, int nTimeoutUSec ) | ||
32 | { | ||
33 | this->nTimeoutSec = nTimeoutSec; | ||
34 | this->nTimeoutUSec = nTimeoutUSec; | ||
35 | } | ||
36 | |||
37 | void Bu::Server::scan() | ||
38 | { | ||
39 | struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec }; | ||
40 | |||
41 | fd_set fdRead = fdActive; | ||
42 | fd_set fdWrite = fdActive; | ||
43 | fd_set fdException = fdActive; | ||
44 | |||
45 | if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, &fdRead, NULL, &fdException, &xTimeout ) ) < 0 ) | ||
46 | { | ||
47 | throw ExceptionBase("Error attempting to scan open connections."); | ||
48 | } | ||
49 | |||
50 | for( int j = 0; j < FD_SETSIZE; j++ ) | ||
51 | { | ||
52 | if( FD_ISSET( j, &fdRead ) ) | ||
53 | { | ||
54 | if( hServers.has( j ) ) | ||
55 | { | ||
56 | addClient( hServers.get( j )->accept() ); | ||
57 | } | ||
58 | else | ||
59 | { | ||
60 | |||
61 | } | ||
62 | } | ||
63 | } | ||
64 | } | ||
65 | |||
66 | void Bu::Server::addClient( int nSocket ) | ||
67 | { | ||
68 | FD_SET( nSocket, &fdActive ); | ||
69 | |||
70 | Client *c = new Client(); | ||
71 | hClients.insert( nSocket, c ); | ||
72 | } | ||
73 | |||
diff --git a/src/server.h b/src/server.h new file mode 100644 index 0000000..9f4f459 --- /dev/null +++ b/src/server.h | |||
@@ -0,0 +1,49 @@ | |||
1 | #ifndef SERVER_H | ||
2 | #define SERVER_H | ||
3 | |||
4 | #include <stdint.h> | ||
5 | #include "bu/serversocket.h" | ||
6 | #include "bu/list.h" | ||
7 | #include "bu/client.h" | ||
8 | |||
9 | namespace Bu | ||
10 | { | ||
11 | /** | ||
12 | * Core of a network server. This class is distinct from a ServerSocket in | ||
13 | * that a ServerSocket is one listening socket, nothing more. Socket will | ||
14 | * manage a pool of both ServerSockets and connected Sockets along with | ||
15 | * their protocols and buffers. | ||
16 | * | ||
17 | * To start serving on a new port, use the addPort functions. Each call to | ||
18 | * addPort creates a new ServerSocket, starts it listening, and adds it to | ||
19 | * the server pool. | ||
20 | * | ||
21 | * All of the real work is done by scan, which will wait for up | ||
22 | * to the timeout set by setTimeout before returning if there is no data | ||
23 | * pending. scan should probably be called in some sort of tight | ||
24 | * loop, possibly in it's own thread, or in the main control loop. | ||
25 | */ | ||
26 | class Server | ||
27 | { | ||
28 | public: | ||
29 | Server(); | ||
30 | virtual ~Server(); | ||
31 | |||
32 | void addPort( int nPort, int nPoolSize=40 ); | ||
33 | void addPort( const FString &sAddr, int nPort, int nPoolSize=40 ); | ||
34 | |||
35 | void scan(); | ||
36 | void setTimeout( int nTimeoutSec, int nTimeoutUSec=0 ); | ||
37 | |||
38 | void addClient( int nSocket ); | ||
39 | |||
40 | private: | ||
41 | int nTimeoutSec; | ||
42 | int nTimeoutUSec; | ||
43 | fd_set fdActive; | ||
44 | Hash<int,ServerSocket *> hServers; | ||
45 | Hash<int,Client *> hClients; | ||
46 | }; | ||
47 | } | ||
48 | |||
49 | #endif | ||
diff --git a/src/serversocket.cpp b/src/serversocket.cpp index c53c80d..9c8f743 100644 --- a/src/serversocket.cpp +++ b/src/serversocket.cpp | |||
@@ -85,6 +85,11 @@ void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) | |||
85 | FD_SET( nServer, &fdActive ); | 85 | FD_SET( nServer, &fdActive ); |
86 | } | 86 | } |
87 | 87 | ||
88 | int Bu::ServerSocket::getSocket() | ||
89 | { | ||
90 | return nServer; | ||
91 | } | ||
92 | |||
88 | int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) | 93 | int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) |
89 | { | 94 | { |
90 | fd_set fdRead = fdActive; | 95 | fd_set fdRead = fdActive; |
diff --git a/src/serversocket.h b/src/serversocket.h index f146d91..d2601e4 100644 --- a/src/serversocket.h +++ b/src/serversocket.h | |||
@@ -23,7 +23,8 @@ namespace Bu | |||
23 | ServerSocket( const FString &sAddr, int nPort, int nPoolSize=40 ); | 23 | ServerSocket( const FString &sAddr, int nPort, int nPoolSize=40 ); |
24 | virtual ~ServerSocket(); | 24 | virtual ~ServerSocket(); |
25 | 25 | ||
26 | int accept( int nTimeoutSec, int nTimeoutUSec ); | 26 | int accept( int nTimeoutSec=0, int nTimeoutUSec=0 ); |
27 | int getSocket(); | ||
27 | 28 | ||
28 | private: | 29 | private: |
29 | void startServer( struct sockaddr_in &name, int nPoolSize ); | 30 | void startServer( struct sockaddr_in &name, int nPoolSize ); |
diff --git a/src/singleton.h b/src/singleton.h new file mode 100644 index 0000000..4976a61 --- /dev/null +++ b/src/singleton.h | |||
@@ -0,0 +1,62 @@ | |||
1 | #ifndef SINGLETON_H | ||
2 | #define SINGLETON_H | ||
3 | |||
4 | #include <stdio.h> | ||
5 | |||
6 | namespace Bu | ||
7 | { | ||
8 | /** | ||
9 | * Provides singleton functionality in a modular sort of way. Make this the | ||
10 | * base class of any other class and you immediately gain singleton | ||
11 | * functionality. Be sure to make your constructor and various functions use | ||
12 | * intellegent scoping. Cleanup and instantiation are performed automatically | ||
13 | * for you at first use and program exit. There are two things that you must | ||
14 | * do when using this template, first is to inherit from it with the name of | ||
15 | * your class filling in for T and then make this class a friend of your class. | ||
16 | *@code | ||
17 | * // Making the Single Singleton: | ||
18 | * class Single : public Singleton<Single> | ||
19 | * { | ||
20 | * friend class Singleton<Single>; | ||
21 | * protected: | ||
22 | * Single(); | ||
23 | * ... | ||
24 | * }; | ||
25 | @endcode | ||
26 | * You can still add public functions and variables to your new Singleton child | ||
27 | * class, but your constructor should be protected (hence the need for the | ||
28 | * friend decleration). | ||
29 | *@author Mike Buland | ||
30 | */ | ||
31 | template <class T> | ||
32 | class Singleton | ||
33 | { | ||
34 | protected: | ||
35 | /** | ||
36 | * Private constructor. This constructor is empty but has a body so that | ||
37 | * you can make your own override of it. Be sure that you're override is | ||
38 | * also protected. | ||
39 | */ | ||
40 | Singleton() {}; | ||
41 | |||
42 | private: | ||
43 | /** | ||
44 | * Copy constructor, defined so that you could write your own as well. | ||
45 | */ | ||
46 | Singleton( const Singleton& ); | ||
47 | |||
48 | public: | ||
49 | /** | ||
50 | * Get a handle to the contained instance of the contained class. It is | ||
51 | * a reference. | ||
52 | *@returns A reference to the contained object. | ||
53 | */ | ||
54 | static T &getInstance() | ||
55 | { | ||
56 | static T i; | ||
57 | return i; | ||
58 | } | ||
59 | }; | ||
60 | } | ||
61 | |||
62 | #endif | ||
diff --git a/src/socket.cpp b/src/socket.cpp index 455b5c8..441678a 100644 --- a/src/socket.cpp +++ b/src/socket.cpp | |||
@@ -231,3 +231,12 @@ bool Bu::Socket::canSeek() | |||
231 | return false; | 231 | return false; |
232 | } | 232 | } |
233 | 233 | ||
234 | bool Bu::Socket::isBlocking() | ||
235 | { | ||
236 | return false; | ||
237 | } | ||
238 | |||
239 | void Bu::Socket::setBlocking( bool bBlocking ) | ||
240 | { | ||
241 | } | ||
242 | |||
diff --git a/src/socket.h b/src/socket.h index 568cad6..e65eb74 100644 --- a/src/socket.h +++ b/src/socket.h | |||
@@ -33,7 +33,8 @@ namespace Bu | |||
33 | virtual bool canWrite(); | 33 | virtual bool canWrite(); |
34 | virtual bool canSeek(); | 34 | virtual bool canSeek(); |
35 | 35 | ||
36 | 36 | virtual bool isBlocking(); | |
37 | virtual void setBlocking( bool bBlocking=true ); | ||
37 | 38 | ||
38 | private: | 39 | private: |
39 | int nSocket; | 40 | int nSocket; |
diff --git a/src/stream.h b/src/stream.h index e640959..5f586e6 100644 --- a/src/stream.h +++ b/src/stream.h | |||
@@ -36,6 +36,9 @@ namespace Bu | |||
36 | virtual bool canWrite() = 0; | 36 | virtual bool canWrite() = 0; |
37 | virtual bool canSeek() = 0; | 37 | virtual bool canSeek() = 0; |
38 | 38 | ||
39 | virtual bool isBlocking() = 0; | ||
40 | virtual void setBlocking( bool bBlocking=true ) = 0; | ||
41 | |||
39 | private: | 42 | private: |
40 | 43 | ||
41 | }; | 44 | }; |
diff --git a/src/tests/hash.cpp b/src/tests/hash.cpp new file mode 100644 index 0000000..73cfb27 --- /dev/null +++ b/src/tests/hash.cpp | |||
@@ -0,0 +1,24 @@ | |||
1 | #include "bu/hash.h" | ||
2 | #include "bu/sptr.h" | ||
3 | |||
4 | typedef struct Bob | ||
5 | { | ||
6 | int nID; | ||
7 | } Bob; | ||
8 | |||
9 | int main() | ||
10 | { | ||
11 | Bu::Hash<int, Bu::SPtr<const Bob> > lb; | ||
12 | for( int j = 0; j < 10; j++ ) | ||
13 | { | ||
14 | Bob *b = new Bob; | ||
15 | b->nID = j; | ||
16 | lb.insert( j, b ); | ||
17 | } | ||
18 | |||
19 | for( int j = 0; j < 10; j++ ) | ||
20 | { | ||
21 | printf("%d\n", lb[j].value()->nID ); | ||
22 | } | ||
23 | } | ||
24 | |||