summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2010-10-16 03:02:11 +0000
committerMike Buland <eichlan@xagasoft.com>2010-10-16 03:02:11 +0000
commit9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5 (patch)
tree17bc9d96b13d16d79385016c087321fc1267743f /src
parent93c028162318a00b9bd03fc4a48383f830cc529d (diff)
downloadlibbu++-9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5.tar.gz
libbu++-9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5.tar.bz2
libbu++-9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5.tar.xz
libbu++-9031e2af7dd4e65ec70890ee78a7cf600d1b2cc5.zip
Many, many changes. Documentation changes, renamed the socket class to
TcpSocket, fixed many other things, and finally removed ParamProc. Anything that needs it will now have to switch to OptParser.
Diffstat (limited to 'src')
-rw-r--r--src/array.h2
-rw-r--r--src/client.cpp9
-rw-r--r--src/client.h8
-rw-r--r--src/fastcgi.cpp22
-rw-r--r--src/fastcgi.h18
-rw-r--r--src/fbasicstring.h2
-rw-r--r--src/hash.h2
-rw-r--r--src/heap.h2
-rw-r--r--src/httpget.h4
-rw-r--r--src/itoserver.cpp12
-rw-r--r--src/itoserver.h6
-rw-r--r--src/newline.h2
-rw-r--r--src/paramproc.cpp523
-rw-r--r--src/paramproc.h163
-rw-r--r--src/ringbuffer.h2
-rw-r--r--src/server.cpp14
-rw-r--r--src/server.h6
-rw-r--r--src/sharedcore.h47
-rw-r--r--src/tcpserversocket.cpp (renamed from src/serversocket.cpp)36
-rw-r--r--src/tcpserversocket.h (renamed from src/serversocket.h)18
-rw-r--r--src/tcpsocket.cpp (renamed from src/socket.cpp)148
-rw-r--r--src/tcpsocket.h (renamed from src/socket.h)31
-rw-r--r--src/tests/socketblock.cpp10
-rw-r--r--src/tests/socketbreak.cpp10
-rw-r--r--src/tests/tcpsocket.cpp (renamed from src/tests/socket.cpp)4
-rw-r--r--src/variant.h18
26 files changed, 256 insertions, 863 deletions
diff --git a/src/array.h b/src/array.h
index fc4fb12..f225c97 100644
--- a/src/array.h
+++ b/src/array.h
@@ -20,6 +20,7 @@ namespace Bu
20 template<typename value, int inc, typename valuealloc> 20 template<typename value, int inc, typename valuealloc>
21 class Array; 21 class Array;
22 22
23 /** @cond DEVEL */
23 template<typename value, int inc, typename valuealloc> 24 template<typename value, int inc, typename valuealloc>
24 class ArrayCore 25 class ArrayCore
25 { 26 {
@@ -107,6 +108,7 @@ namespace Bu
107 long iSize; 108 long iSize;
108 long iCapacity; 109 long iCapacity;
109 }; 110 };
111 /** @endcond */
110 112
111 /** 113 /**
112 * Array type container, just like a normal array only flexible and keeps 114 * Array type container, just like a normal array only flexible and keeps
diff --git a/src/client.cpp b/src/client.cpp
index becd1bd..b635c8b 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -6,7 +6,7 @@
6 */ 6 */
7 7
8#include "bu/client.h" 8#include "bu/client.h"
9#include "bu/socket.h" 9#include "bu/tcpsocket.h"
10#include <stdlib.h> 10#include <stdlib.h>
11#include <errno.h> 11#include <errno.h>
12#include "bu/protocol.h" 12#include "bu/protocol.h"
@@ -16,7 +16,8 @@
16/** Read buffer size. */ 16/** Read buffer size. */
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::TcpSocket *pSocket,
20 class Bu::ClientLinkFactory *pfLink ) :
20 pTopStream( pSocket ), 21 pTopStream( pSocket ),
21 pSocket( pSocket ), 22 pSocket( pSocket ),
22 pProto( NULL ), 23 pProto( NULL ),
@@ -59,7 +60,7 @@ void Bu::Client::processInput()
59 break; 60 break;
60 } 61 }
61 } 62 }
62 catch( Bu::SocketException &e ) 63 catch( Bu::TcpSocketException &e )
63 { 64 {
64 pTopStream->close(); 65 pTopStream->close();
65 bWantsDisconnect = true; 66 bWantsDisconnect = true;
@@ -195,7 +196,7 @@ long Bu::Client::getOutputSize()
195 return qbWrite.getSize(); 196 return qbWrite.getSize();
196} 197}
197 198
198const Bu::Socket *Bu::Client::getSocket() const 199const Bu::TcpSocket *Bu::Client::getSocket() const
199{ 200{
200 return pSocket; 201 return pSocket;
201} 202}
diff --git a/src/client.h b/src/client.h
index f336524..096df2f 100644
--- a/src/client.h
+++ b/src/client.h
@@ -17,7 +17,7 @@ namespace Bu
17{ 17{
18 class Protocol; 18 class Protocol;
19 class Stream; 19 class Stream;
20 class Socket; 20 class TcpSocket;
21 class ClientLinkFactory; 21 class ClientLinkFactory;
22 22
23 /** 23 /**
@@ -26,7 +26,7 @@ namespace Bu
26 class Client : public Bu::Stream 26 class Client : public Bu::Stream
27 { 27 {
28 public: 28 public:
29 Client( Bu::Socket *pSocket, Bu::ClientLinkFactory *pfLink ); 29 Client( Bu::TcpSocket *pSocket, Bu::ClientLinkFactory *pfLink );
30 virtual ~Client(); 30 virtual ~Client();
31 31
32 void processInput(); 32 void processInput();
@@ -58,7 +58,7 @@ namespace Bu
58 void close(); 58 void close();
59 void tick(); 59 void tick();
60 60
61 const Bu::Socket *getSocket() const; 61 const Bu::TcpSocket *getSocket() const;
62 62
63 void disconnect(); 63 void disconnect();
64 bool wantsDisconnect(); 64 bool wantsDisconnect();
@@ -117,7 +117,7 @@ namespace Bu
117 typedef Bu::List<Bu::Stream *> FilterList; 117 typedef Bu::List<Bu::Stream *> FilterList;
118 FilterList lFilts; 118 FilterList lFilts;
119 Bu::Stream *pTopStream; 119 Bu::Stream *pTopStream;
120 Bu::Socket *pSocket; 120 Bu::TcpSocket *pSocket;
121 Bu::Protocol *pProto; 121 Bu::Protocol *pProto;
122 Bu::QueueBuf qbRead; 122 Bu::QueueBuf qbRead;
123 Bu::QueueBuf qbWrite; 123 Bu::QueueBuf qbWrite;
diff --git a/src/fastcgi.cpp b/src/fastcgi.cpp
index 8168928..ca3010e 100644
--- a/src/fastcgi.cpp
+++ b/src/fastcgi.cpp
@@ -24,14 +24,14 @@ Bu::FastCgi::FastCgi() :
24 pSrv( NULL ), 24 pSrv( NULL ),
25 bRunning( true ) 25 bRunning( true )
26{ 26{
27 pSrv = new Bu::ServerSocket( STDIN_FILENO, false ); 27 pSrv = new Bu::TcpServerSocket( STDIN_FILENO, false );
28} 28}
29 29
30Bu::FastCgi::FastCgi( int iPort ) : 30Bu::FastCgi::FastCgi( int iPort ) :
31 pSrv( NULL ), 31 pSrv( NULL ),
32 bRunning( true ) 32 bRunning( true )
33{ 33{
34 pSrv = new Bu::ServerSocket( iPort ); 34 pSrv = new Bu::TcpServerSocket( iPort );
35} 35}
36 36
37Bu::FastCgi::~FastCgi() 37Bu::FastCgi::~FastCgi()
@@ -64,17 +64,17 @@ bool Bu::FastCgi::isEmbedded()
64#endif 64#endif
65} 65}
66 66
67void Bu::FastCgi::read( Bu::Socket &s, Bu::FastCgi::Record &r ) 67void Bu::FastCgi::read( Bu::TcpSocket &s, Bu::FastCgi::Record &r )
68{ 68{
69 int iRead = s.read( &r, sizeof(Record) ); 69 int iRead = s.read( &r, sizeof(Record) );
70 if( iRead != sizeof(Record) ) 70 if( iRead != sizeof(Record) )
71 throw Bu::SocketException("Hey, the size %d is wrong for Record. (%s)", 71 throw Bu::TcpSocketException("Hey, the size %d is wrong for Record. (%s)",
72 iRead, strerror( errno ) ); 72 iRead, strerror( errno ) );
73 r.uRequestId = ntohs( r.uRequestId ); 73 r.uRequestId = ntohs( r.uRequestId );
74 r.uContentLength = ntohs( r.uContentLength ); 74 r.uContentLength = ntohs( r.uContentLength );
75} 75}
76 76
77void Bu::FastCgi::write( Bu::Socket &s, Bu::FastCgi::Record r ) 77void Bu::FastCgi::write( Bu::TcpSocket &s, Bu::FastCgi::Record r )
78{ 78{
79// sio << "Out -> " << r << sio.nl; 79// sio << "Out -> " << r << sio.nl;
80 r.uRequestId = htons( r.uRequestId ); 80 r.uRequestId = htons( r.uRequestId );
@@ -82,19 +82,19 @@ void Bu::FastCgi::write( Bu::Socket &s, Bu::FastCgi::Record r )
82 s.write( &r, sizeof(Record) ); 82 s.write( &r, sizeof(Record) );
83} 83}
84 84
85void Bu::FastCgi::read( Bu::Socket &s, Bu::FastCgi::BeginRequestBody &b ) 85void Bu::FastCgi::read( Bu::TcpSocket &s, Bu::FastCgi::BeginRequestBody &b )
86{ 86{
87 s.read( &b, sizeof(BeginRequestBody) ); 87 s.read( &b, sizeof(BeginRequestBody) );
88 b.uRole = ntohs( b.uRole ); 88 b.uRole = ntohs( b.uRole );
89} 89}
90 90
91void Bu::FastCgi::write( Bu::Socket &s, Bu::FastCgi::EndRequestBody b ) 91void Bu::FastCgi::write( Bu::TcpSocket &s, Bu::FastCgi::EndRequestBody b )
92{ 92{
93 b.uStatus = htonl( b.uStatus ); 93 b.uStatus = htonl( b.uStatus );
94 s.write( &b, sizeof(b) ); 94 s.write( &b, sizeof(b) );
95} 95}
96 96
97uint32_t Bu::FastCgi::readLen( Bu::Socket &s, uint16_t &uRead ) 97uint32_t Bu::FastCgi::readLen( Bu::TcpSocket &s, uint16_t &uRead )
98{ 98{
99 uint8_t uByte[4]; 99 uint8_t uByte[4];
100 s.read( uByte, 1 ); 100 s.read( uByte, 1 );
@@ -107,7 +107,7 @@ uint32_t Bu::FastCgi::readLen( Bu::Socket &s, uint16_t &uRead )
107 return ((uByte[0]&0x7f)<<24)|(uByte[1]<<16)|(uByte[2]<<8)|(uByte[3]); 107 return ((uByte[0]&0x7f)<<24)|(uByte[1]<<16)|(uByte[2]<<8)|(uByte[3]);
108} 108}
109 109
110void Bu::FastCgi::readPair( Bu::Socket &s, StrHash &hParams, uint16_t &uRead ) 110void Bu::FastCgi::readPair( Bu::TcpSocket &s, StrHash &hParams, uint16_t &uRead )
111{ 111{
112 uint32_t uName = readLen( s, uRead ); 112 uint32_t uName = readLen( s, uRead );
113 uint32_t uValue = readLen( s, uRead ); 113 uint32_t uValue = readLen( s, uRead );
@@ -162,7 +162,7 @@ void Bu::FastCgi::run()
162 if( iSock < 0 ) 162 if( iSock < 0 )
163 continue; 163 continue;
164 164
165 Bu::Socket s( iSock ); 165 Bu::TcpSocket s( iSock );
166 s.setBlocking( true ); 166 s.setBlocking( true );
167// sio << "Got connection, blocking? " << s.isBlocking() << sio.nl; 167// sio << "Got connection, blocking? " << s.isBlocking() << sio.nl;
168 try 168 try
@@ -362,7 +362,7 @@ void Bu::FastCgi::run()
362 } 362 }
363 } 363 }
364 } 364 }
365 catch( Bu::SocketException &e ) 365 catch( Bu::TcpSocketException &e )
366 { 366 {
367// sio << "Bu::SocketException: " << e.what() << sio.nl << 367// sio << "Bu::SocketException: " << e.what() << sio.nl <<
368// "\tSocket open: " << s.isOpen() << sio.nl; 368// "\tSocket open: " << s.isOpen() << sio.nl;
diff --git a/src/fastcgi.h b/src/fastcgi.h
index 262872c..7c1c04c 100644
--- a/src/fastcgi.h
+++ b/src/fastcgi.h
@@ -11,8 +11,8 @@
11#include "bu/fstring.h" 11#include "bu/fstring.h"
12#include "bu/hash.h" 12#include "bu/hash.h"
13#include "bu/array.h" 13#include "bu/array.h"
14#include "bu/socket.h" 14#include "bu/tcpsocket.h"
15#include "bu/serversocket.h" 15#include "bu/tcpserversocket.h"
16 16
17namespace Bu 17namespace Bu
18{ 18{
@@ -109,18 +109,18 @@ namespace Bu
109 virtual void onUninit() { }; 109 virtual void onUninit() { };
110 110
111 private: 111 private:
112 void read( Bu::Socket &s, Record &r ); 112 void read( Bu::TcpSocket &s, Record &r );
113 void read( Bu::Socket &s, BeginRequestBody &b ); 113 void read( Bu::TcpSocket &s, BeginRequestBody &b );
114 uint32_t readLen( Bu::Socket &s, uint16_t &uUsed ); 114 uint32_t readLen( Bu::TcpSocket &s, uint16_t &uUsed );
115 void readPair( Bu::Socket &s, StrHash &hParams, uint16_t &uUsed ); 115 void readPair( Bu::TcpSocket &s, StrHash &hParams, uint16_t &uUsed );
116 116
117 void write( Bu::Socket &s, Record r ); 117 void write( Bu::TcpSocket &s, Record r );
118 void write( Bu::Socket &s, EndRequestBody b ); 118 void write( Bu::TcpSocket &s, EndRequestBody b );
119 119
120 bool hasChannel( int iChan ); 120 bool hasChannel( int iChan );
121 121
122 private: 122 private:
123 Bu::ServerSocket *pSrv; 123 Bu::TcpServerSocket *pSrv;
124 bool bRunning; 124 bool bRunning;
125 Bu::Array<Channel *> aChannel; 125 Bu::Array<Channel *> aChannel;
126 }; 126 };
diff --git a/src/fbasicstring.h b/src/fbasicstring.h
index 82c5137..7167f4a 100644
--- a/src/fbasicstring.h
+++ b/src/fbasicstring.h
@@ -25,6 +25,7 @@
25 25
26namespace Bu 26namespace Bu
27{ 27{
28 /** @cond DEVEL */
28 template< typename chr > 29 template< typename chr >
29 struct FStringChunk 30 struct FStringChunk
30 { 31 {
@@ -166,6 +167,7 @@ namespace Bu
166 nLength += pNewChunk->nLength; 167 nLength += pNewChunk->nLength;
167 } 168 }
168 }; 169 };
170 /** @endcond */
169 171
170 /** 172 /**
171 * Flexible String class. This class was designed with string passing and 173 * Flexible String class. This class was designed with string passing and
diff --git a/src/hash.h b/src/hash.h
index 714a7f7..d251c46 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -54,6 +54,7 @@ namespace Bu
54 typename valuealloc, typename challoc> 54 typename valuealloc, typename challoc>
55 class Hash; 55 class Hash;
56 56
57 /** @cond DEVEL */
57 template<typename key, typename value, typename sizecalc, typename keyalloc, 58 template<typename key, typename value, typename sizecalc, typename keyalloc,
58 typename valuealloc, typename challoc > 59 typename valuealloc, typename challoc >
59 class HashCore 60 class HashCore
@@ -399,6 +400,7 @@ namespace Bu
399 challoc ca; 400 challoc ca;
400 sizecalc szCalc; 401 sizecalc szCalc;
401 }; 402 };
403 /** @endcond */
402 404
403 /** 405 /**
404 * Libbu++ Template Hash Table. This is your average hash table, that uses 406 * Libbu++ Template Hash Table. This is your average hash table, that uses
diff --git a/src/heap.h b/src/heap.h
index 1dac69b..31c2435 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -22,6 +22,7 @@ namespace Bu
22 template<typename item, typename cmpfunc, typename itemalloc> 22 template<typename item, typename cmpfunc, typename itemalloc>
23 class Heap; 23 class Heap;
24 24
25 /** @cond DEVEL */
25 template<typename item, typename cmpfunc, typename itemalloc> 26 template<typename item, typename cmpfunc, typename itemalloc>
26 class HeapCore 27 class HeapCore
27 { 28 {
@@ -183,6 +184,7 @@ namespace Bu
183 cmpfunc cmp; 184 cmpfunc cmp;
184 itemalloc ia; 185 itemalloc ia;
185 }; 186 };
187 /** @endcond */
186 188
187 /** 189 /**
188 * A priority queue that allows for an unlimited number of priorities. All 190 * A priority queue that allows for an unlimited number of priorities. All
diff --git a/src/httpget.h b/src/httpget.h
index 410914c..783f880 100644
--- a/src/httpget.h
+++ b/src/httpget.h
@@ -11,7 +11,7 @@
11#include "bu/stream.h" 11#include "bu/stream.h"
12#include "bu/fstring.h" 12#include "bu/fstring.h"
13#include "bu/url.h" 13#include "bu/url.h"
14#include "bu/socket.h" 14#include "bu/tcpsocket.h"
15#include "bu/hash.h" 15#include "bu/hash.h"
16 16
17namespace Bu 17namespace Bu
@@ -52,7 +52,7 @@ namespace Bu
52 private: 52 private:
53 Bu::Url uSrc; 53 Bu::Url uSrc;
54 Bu::FString sMethod; 54 Bu::FString sMethod;
55 Bu::Socket sSrv; 55 Bu::TcpSocket sSrv;
56 typedef Bu::Hash<Bu::FString,Bu::FString> MimeHash; 56 typedef Bu::Hash<Bu::FString,Bu::FString> MimeHash;
57 MimeHash hMimeIn; 57 MimeHash hMimeIn;
58 MimeHash hMimeOut; 58 MimeHash hMimeOut;
diff --git a/src/itoserver.cpp b/src/itoserver.cpp
index a1d804a..ea737bf 100644
--- a/src/itoserver.cpp
+++ b/src/itoserver.cpp
@@ -7,9 +7,9 @@
7 7
8#include "bu/itoserver.h" 8#include "bu/itoserver.h"
9#include <errno.h> 9#include <errno.h>
10#include "bu/serversocket.h" 10#include "bu/tcpserversocket.h"
11#include "bu/client.h" 11#include "bu/client.h"
12#include "bu/socket.h" 12#include "bu/tcpsocket.h"
13 13
14#include "bu/config.h" 14#include "bu/config.h"
15 15
@@ -41,7 +41,7 @@ Bu::ItoServer::~ItoServer()
41 41
42void Bu::ItoServer::addPort( int nPort, int nPoolSize ) 42void Bu::ItoServer::addPort( int nPort, int nPoolSize )
43{ 43{
44 ServerSocket *s = new ServerSocket( nPort, nPoolSize ); 44 TcpServerSocket *s = new TcpServerSocket( nPort, nPoolSize );
45 int nSocket = s->getSocket(); 45 int nSocket = s->getSocket();
46 FD_SET( nSocket, &fdActive ); 46 FD_SET( nSocket, &fdActive );
47 hServers.insert( nSocket, s ); 47 hServers.insert( nSocket, s );
@@ -49,7 +49,7 @@ void Bu::ItoServer::addPort( int nPort, int nPoolSize )
49 49
50void Bu::ItoServer::addPort( const FString &sAddr, int nPort, int nPoolSize ) 50void Bu::ItoServer::addPort( const FString &sAddr, int nPort, int nPoolSize )
51{ 51{
52 ServerSocket *s = new ServerSocket( sAddr, nPort, nPoolSize ); 52 TcpServerSocket *s = new TcpServerSocket( sAddr, nPort, nPoolSize );
53 int nSocket = s->getSocket(); 53 int nSocket = s->getSocket();
54 FD_SET( nSocket, &fdActive ); 54 FD_SET( nSocket, &fdActive );
55 hServers.insert( nSocket, s ); 55 hServers.insert( nSocket, s );
@@ -92,7 +92,7 @@ void Bu::ItoServer::run()
92 { 92 {
93 if( FD_ISSET( i.getKey(), &fdRead ) ) 93 if( FD_ISSET( i.getKey(), &fdRead ) )
94 { 94 {
95 ServerSocket *pSrv = i.getValue(); 95 TcpServerSocket *pSrv = i.getValue();
96 addClient( pSrv->accept(), pSrv->getPort() ); 96 addClient( pSrv->accept(), pSrv->getPort() );
97 } 97 }
98 } 98 }
@@ -126,7 +126,7 @@ Bu::ItoServer::ItoClient::ItoClient( ItoServer &rSrv, int iSocket, int iPort,
126 FD_SET( iSocket, &fdActive ); 126 FD_SET( iSocket, &fdActive );
127 127
128 pClient = new Client( 128 pClient = new Client(
129 new Bu::Socket( iSocket ), 129 new Bu::TcpSocket( iSocket ),
130 new SrvClientLinkFactory( rSrv ) 130 new SrvClientLinkFactory( rSrv )
131 ); 131 );
132} 132}
diff --git a/src/itoserver.h b/src/itoserver.h
index c08d453..81e42cc 100644
--- a/src/itoserver.h
+++ b/src/itoserver.h
@@ -26,8 +26,8 @@
26 26
27namespace Bu 27namespace Bu
28{ 28{
29 class ServerSocket; 29 class TcpServerSocket;
30 class Socket; 30 class TcpSocket;
31 class Client; 31 class Client;
32 32
33 /** 33 /**
@@ -126,7 +126,7 @@ namespace Bu
126 int nTimeoutSec; 126 int nTimeoutSec;
127 int nTimeoutUSec; 127 int nTimeoutUSec;
128 fd_set fdActive; 128 fd_set fdActive;
129 typedef Hash<int,ServerSocket *> ServerHash; 129 typedef Hash<int,TcpServerSocket *> ServerHash;
130 ServerHash hServers; 130 ServerHash hServers;
131 typedef Hash<int,ItoClient *> ClientHash; 131 typedef Hash<int,ItoClient *> ClientHash;
132 typedef ItoQueue<ItoClient *> ClientQueue; 132 typedef ItoQueue<ItoClient *> ClientQueue;
diff --git a/src/newline.h b/src/newline.h
index b69cdb5..243c876 100644
--- a/src/newline.h
+++ b/src/newline.h
@@ -14,7 +14,7 @@ namespace Bu
14{ 14{
15 /** 15 /**
16 * Converts new-line characters from any standard convention into linefeeds 16 * Converts new-line characters from any standard convention into linefeeds
17 * (\n) on reading, and converts them to either your OS's standard or a 17 * (\\n) on reading, and converts them to either your OS's standard or a
18 * specified standard, depending on how you construct the class. 18 * specified standard, depending on how you construct the class.
19 * 19 *
20 * If you're reading in a text file, then this filter is practically 20 * If you're reading in a text file, then this filter is practically
diff --git a/src/paramproc.cpp b/src/paramproc.cpp
deleted file mode 100644
index f4fd36e..0000000
--- a/src/paramproc.cpp
+++ /dev/null
@@ -1,523 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/paramproc.h"
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#define ptrtype( iitype, iiname ) \
14 Bu::ParamProc::ParamPtr::ParamPtr( iitype *iiname ) : \
15 type( vt ##iiname ) { val.iiname = iiname; }
16
17Bu::ParamProc::ParamPtr::ParamPtr()
18{
19 val.str = NULL;
20 type = vtunset;
21}
22
23ptrtype( Bu::FString, str );
24ptrtype( uint64_t, uint64 );
25ptrtype( uint32_t, uint32 );
26ptrtype( uint16_t, uint16 );
27ptrtype( uint8_t, uint8 );
28ptrtype( int64_t, int64 );
29ptrtype( int32_t, int32 );
30ptrtype( int16_t, int16 );
31ptrtype( int8_t, int8 );
32ptrtype( float, float32 );
33ptrtype( double, float64 );
34ptrtype( long double, float96 );
35ptrtype( bool, bln );
36
37Bu::ParamProc::ParamPtr &Bu::ParamProc::ParamPtr::operator=( ParamProc::ParamPtr &ptr )
38{
39 val = ptr.val;
40 type = ptr.type;
41
42 return *this;
43}
44
45bool Bu::ParamProc::ParamPtr::isSet()
46{
47 return type != vtunset;
48}
49
50Bu::ParamProc::ParamPtr &Bu::ParamProc::ParamPtr::operator=( const char *str )
51{
52 if( !isSet() ) return *this;
53 switch( type )
54 {
55 case vtstr:
56 (*val.str) = str;
57 break;
58
59 case vtuint64:
60 (*val.uint64) = strtoull( str, NULL, 10 );
61 break;
62
63 case vtuint32:
64 (*val.uint32) = strtoul( str, NULL, 10 );
65 break;
66
67 case vtuint16:
68 (*val.uint16) = (uint16_t)strtoul( str, NULL, 10 );
69 break;
70
71 case vtuint8:
72 (*val.uint8) = (uint8_t)strtoul( str, NULL, 10 );
73 break;
74
75 case vtint64:
76 (*val.int64) = strtoll( str, NULL, 10 );
77 break;
78
79 case vtint32:
80 (*val.int32) = strtol( str, NULL, 10 );
81 break;
82
83 case vtint16:
84 (*val.int16) = (int16_t)strtol( str, NULL, 10 );
85 break;
86
87 case vtint8:
88 (*val.int8) = (int8_t)strtol( str, NULL, 10 );
89 break;
90
91 case vtfloat32:
92 (*val.float32) = strtof( str, NULL );
93 break;
94
95 case vtfloat64:
96 (*val.float64) = strtod( str, NULL );
97 break;
98
99 case vtfloat96:
100 (*val.float96) = strtold( str, NULL );
101 break;
102
103 case vtbln:
104 if( strcasecmp("yes", str ) == 0 ||
105 strcasecmp("true", str ) == 0 )
106 {
107 (*val.bln) = true;
108 }
109 else
110 {
111 (*val.bln) = false;
112 }
113 break;
114 }
115
116 return *this;
117}
118
119Bu::ParamProc::ParamProc()
120{
121}
122
123Bu::ParamProc::~ParamProc()
124{
125 for( Bu::List<ArgSpec *>::iterator i = lArg.begin();
126 i != lArg.end(); i++ )
127 {
128 delete *i;
129 }
130
131 for( Bu::List<Banner *>::iterator i = lBan.begin();
132 i != lBan.end(); i++ )
133 {
134 delete *i;
135 }
136
137}
138/*
139void Bu::ParamProc::addParam( const char *lpWord, char cChar, Proc proc, ParamPtr val )
140{
141 printf("Calling callback...\n");
142 val = "Hello there, this is set in the ParamProc";
143 (this->*proc)();
144}*/
145
146void Bu::ParamProc::addParam( const char *lpWord, char cChar, Proc proc,
147 ParamPtr val, const char *lpDesc, const char *lpExtra,
148 const char *lpValue )
149{
150 ArgSpec *as = new ArgSpec;
151 if( lpWord )
152 as->sWord = lpWord;
153
154 as->cChar = cChar;
155 as->proc = proc;
156 as->val = val;
157 if( lpDesc )
158 as->sDesc = lpDesc;
159 if( lpExtra )
160 as->sExtra = lpExtra;
161 if( lpValue )
162 as->sValue = lpValue;
163
164 lArg.append( as );
165
166 if( !lBan.isEmpty() )
167 {
168 if( lBan.last()->pBefore == NULL )
169 lBan.last()->pBefore = as;
170 }
171}
172
173void Bu::ParamProc::addParam( const char *lpWord, char cChar, Proc proc,
174 const char *lpDesc, const char *lpExtra,
175 const char *lpValue )
176{
177 addParam( lpWord, cChar, proc, ParamPtr(), lpDesc, lpExtra, lpValue );
178}
179
180void Bu::ParamProc::addParam( const char *lpWord, char cChar, ParamPtr val,
181 const char *lpDesc, const char *lpExtra,
182 const char *lpValue )
183{
184 addParam( lpWord, cChar, NULL, val, lpDesc, lpExtra, lpValue );
185}
186
187void Bu::ParamProc::addParam( const char *lpWord, Proc proc, ParamPtr val,
188 const char *lpDesc, const char *lpExtra,
189 const char *lpValue )
190{
191 addParam( lpWord, '\0', proc, val, lpDesc, lpExtra, lpValue );
192}
193
194void Bu::ParamProc::addParam( const char *lpWord, Proc proc,
195 const char *lpDesc, const char *lpExtra,
196 const char *lpValue )
197{
198 addParam( lpWord, '\0', proc, ParamPtr(), lpDesc, lpExtra, lpValue );
199}
200
201void Bu::ParamProc::addParam( const char *lpWord, ParamPtr val,
202 const char *lpDesc, const char *lpExtra,
203 const char *lpValue )
204{
205 addParam( lpWord, '\0', NULL, val, lpDesc, lpExtra, lpValue );
206}
207
208void Bu::ParamProc::addParam( char cChar, Proc proc, ParamPtr val,
209 const char *lpDesc, const char *lpExtra,
210 const char *lpValue )
211{
212 addParam( NULL, cChar, proc, val, lpDesc, lpExtra, lpValue );
213}
214
215void Bu::ParamProc::addParam( char cChar, Proc proc,
216 const char *lpDesc, const char *lpExtra,
217 const char *lpValue )
218{
219 addParam( NULL, cChar, proc, ParamPtr(), lpDesc, lpExtra, lpValue );
220}
221
222void Bu::ParamProc::addParam( char cChar, ParamPtr val,
223 const char *lpDesc, const char *lpExtra,
224 const char *lpValue )
225{
226 addParam( NULL, cChar, NULL, val, lpDesc, lpExtra, lpValue );
227}
228
229void Bu::ParamProc::process( int argc, char *argv[] )
230{
231 for( int arg = 1; arg < argc; arg++ )
232 {
233 //printf(":::%d:::%s\n", arg, argv[arg] );
234 if( argv[arg][0] == '-' )
235 {
236 if( argv[arg][1] == '-' )
237 {
238 ArgSpec *s = checkWord( argv[arg]+2 );
239 if( s )
240 {
241 if( argv[arg][s->sWord.getSize()+2] == '=' )
242 {
243 if( s->val.isSet() )
244 {
245 if( s->sValue == "" )
246 {
247 s->val = argv[arg]+s->sWord.getSize()+3;
248 }
249 else
250 {
251 s->val = s->sValue.getStr();
252 }
253 }
254 if( s->proc )
255 {
256 char **tmp = new char*[argc-arg];
257 tmp[0] = argv[arg]+s->sWord.getSize()+3;
258 for( int k = 1; k < argc-arg; k++ )
259 tmp[k] = argv[arg+k];
260 int ret = (this->*s->proc)( argc-arg, tmp );
261 if( ret > 0 )
262 {
263 arg += ret-1;
264 }
265 delete tmp;
266 }
267 }
268 else
269 {
270 int add = 0;
271 if( s->val.isSet() )
272 {
273 if( s->sValue == "" )
274 {
275 if( arg+1 >= argc )
276 {
277 return;
278 }
279 s->val = argv[arg+1];
280 add++;
281 }
282 else
283 {
284 s->val = s->sValue.getStr();
285 }
286 }
287 if( s->proc )
288 {
289 int ret = (this->*s->proc)(
290 argc-arg-1, argv+arg+1 );
291
292 if( ret > add )
293 add = 0;
294 else
295 add -= ret;
296 arg += ret;
297 }
298 arg += add;
299 }
300 continue;
301 }
302 else
303 {
304 unknownParam( argc-arg, argv+arg );
305 }
306 }
307 else
308 {
309 for( int chr = 1; argv[arg][chr]; chr++ )
310 {
311 ArgSpec *s = checkLetr( argv[arg][chr] );
312 if( s )
313 {
314 if( argv[arg][chr+1] != '\0' )
315 {
316 bool bUsed = false;
317 if( s->val.isSet() )
318 {
319 if( s->sValue == "" )
320 {
321 s->val = argv[arg]+chr+1;
322 bUsed = true;
323 }
324 else
325 {
326 s->val = s->sValue.getStr();
327 }
328 }
329 if( s->proc )
330 {
331 char **tmp = new char*[argc-arg];
332 tmp[0] = argv[arg]+chr+1;
333 for( int k = 1; k < argc-arg; k++ )
334 tmp[k] = argv[arg+k];
335 int ret = (this->*s->proc)( argc-arg, tmp );
336 if( ret > 0 )
337 {
338 arg += ret - 1;
339 delete tmp;
340 break;
341 }
342 delete tmp;
343 }
344 if( bUsed )
345 {
346 break;
347 }
348 }
349 else
350 {
351 bool bUsed = false;
352 if( s->val.isSet() )
353 {
354 if( s->sValue == "" )
355 {
356 s->val = argv[arg+1];
357 bUsed = true;
358 }
359 else
360 {
361 s->val = s->sValue.getStr();
362 }
363 }
364 if( s->proc )
365 {
366 int ret = (this->*s->proc)(
367 argc-arg-1, argv+arg+1
368 );
369 if( ret > 0 )
370 {
371 arg += ret;
372 break;
373 }
374 }
375 if( bUsed )
376 {
377 arg++;
378 break;
379 }
380 }
381 }
382 else
383 {
384 unknownParam( argc-arg, argv+arg );
385 }
386 }
387 }
388 }
389 else
390 {
391 cmdParam( argc-arg, argv+arg );
392 }
393 }
394}
395
396Bu::ParamProc::ArgSpec *Bu::ParamProc::checkWord( const char *arg )
397{
398 //printf("Checking \"%s\"...\n", arg );
399 Bu::List<ArgSpec *>::const_iterator i = lArg.begin();
400 for( ; i != lArg.end(); i++ )
401 {
402 if( (*i)->sWord == "" )
403 continue;
404
405 if( !strcmp( (*i)->sWord.getStr(), arg ) )
406 return *i;
407
408 if( (*i)->val.isSet() )
409 {
410 if( !strncmp( (*i)->sWord.getStr(), arg, (*i)->sWord.getSize() ) &&
411 arg[(*i)->sWord.getSize()] == '=' )
412 {
413 return *i;
414 }
415 }
416 }
417
418 return NULL;
419}
420
421Bu::ParamProc::ArgSpec *Bu::ParamProc::checkLetr( const char arg )
422{
423 //printf("Checking \'%c\'...\n", arg );
424 Bu::List<ArgSpec *>::const_iterator i = lArg.begin();
425 for( ; i != lArg.end(); i++ )
426 {
427 if( (*i)->cChar == '\0' )
428 continue;
429
430 if( (*i)->cChar == arg )
431 {
432 return *i;
433 }
434 }
435
436 return NULL;
437}
438
439int Bu::ParamProc::cmdParam( int /*argc*/, char *argv[] )
440{
441 printf("Unhandled command parameter \"%s\" found!\n", argv[0] );
442 return 0;
443}
444
445int Bu::ParamProc::unknownParam( int /*argc*/, char *argv[] )
446{
447 printf("Unknown parameter \"%s\" found!\n", argv[0] );
448 return 0;
449}
450
451int Bu::ParamProc::help( int /*argc*/, char * /*argv*/ [] )
452{
453 Bu::List<Banner *>::const_iterator b = lBan.begin();
454 Bu::List<ArgSpec *>::const_iterator i = lArg.begin();
455 int len=0;
456 for( ; i != lArg.end(); i++ )
457 {
458 if( len < (*i)->sWord.getSize() + (*i)->sExtra.getSize() )
459 len = (*i)->sWord.getSize() + (*i)->sExtra.getSize();
460 }
461 char fmt[10];
462 sprintf( fmt, "%%-%ds ", len );
463
464 for( i = lArg.begin(); i != lArg.end(); i++ )
465 {
466 if( b != lBan.end() )
467 {
468 if( (*b)->pBefore == (*i) )
469 {
470 printf( (*b)->sBanner.getStr() );
471 b++;
472 }
473 }
474 printf(" ");
475 if( (*i)->cChar )
476 {
477 if( (*i)->sWord.getStr() )
478 {
479 printf("-%c, ", (*i)->cChar );
480 }
481 else
482 {
483 printf("-%c ", (*i)->cChar );
484 }
485 }
486 else
487 {
488 printf(" ");
489 }
490 if( (*i)->sWord.getStr() )
491 {
492 printf("--");
493 Bu::FString sTmp = (*i)->sWord.getStr();
494 if( (*i)->sExtra.getStr() )
495 sTmp += (*i)->sExtra.getStr();
496 printf( fmt, sTmp.getStr() );
497 }
498 else
499 {
500 printf(" ");
501 printf(fmt, "" );
502 }
503 printf("%s\n", (*i)->sDesc.getStr() );
504 }
505 if( b != lBan.end() )
506 {
507 if( (*b)->pBefore == NULL )
508 {
509 printf( (*b)->sBanner.getStr() );
510 }
511 }
512
513 exit( 0 );
514}
515
516void Bu::ParamProc::addHelpBanner( const char *sHelpBanner )
517{
518 Banner *pBan = new Banner;
519 pBan->sBanner = sHelpBanner;
520 pBan->pBefore = NULL;
521 lBan.append( pBan );
522}
523
diff --git a/src/paramproc.h b/src/paramproc.h
deleted file mode 100644
index ddc1876..0000000
--- a/src/paramproc.h
+++ /dev/null
@@ -1,163 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_PARAM_PROC_H
9#define BU_PARAM_PROC_H
10
11#include <stdint.h>
12#include "bu/list.h"
13#include "bu/fstring.h"
14
15namespace Bu
16{
17 class ParamProc
18 {
19 public:
20 class ParamPtr
21 {
22 public:
23 ParamPtr();
24 ParamPtr( Bu::FString *str );
25 ParamPtr( uint64_t *uint64 );
26 ParamPtr( uint32_t *uint32 );
27 ParamPtr( uint16_t *uint16 );
28 ParamPtr( uint8_t *uint8 );
29 ParamPtr( int64_t *int64 );
30 ParamPtr( int32_t *int32 );
31 ParamPtr( int16_t *int16 );
32 ParamPtr( int8_t *int8 );
33 ParamPtr( float *float32 );
34 ParamPtr( double *float64 );
35 ParamPtr( long double *float96 );
36 ParamPtr( bool *bln );
37
38 enum
39 {
40 vtunset,
41 vtstr,
42 vtuint64,
43 vtuint32,
44 vtuint16,
45 vtuint8,
46 vtint64,
47 vtint32,
48 vtint16,
49 vtint8,
50 vtfloat32,
51 vtfloat64,
52 vtfloat96,
53 vtbln,
54 };
55 ParamPtr &operator=( ParamPtr &ptr );
56 ParamPtr &operator=( const char *str );
57
58 bool isSet();
59
60 private:
61 int type;
62 union
63 {
64 Bu::FString *str;
65 uint64_t *uint64;
66 uint32_t *uint32;
67 uint16_t *uint16;
68 uint8_t *uint8;
69 int64_t *int64;
70 int32_t *int32;
71 int16_t *int16;
72 int8_t *int8;
73 float *float32;
74 double *float64;
75 long double *float96;
76 bool *bln;
77 } val;
78 };
79
80 typedef int (ParamProc::*Proc)( int, char *[] );
81
82 typedef struct ArgSpec
83 {
84 uint8_t nFlags;
85 Bu::FString sWord;
86 char cChar;
87 Proc proc;
88 ParamProc::ParamPtr val;
89 Bu::FString sExtra;
90 Bu::FString sDesc;
91 Bu::FString sValue;
92 } ArgSpec;
93
94 public:
95 DEPRECATED
96 ParamProc();
97 virtual ~ParamProc();
98
99 void addParam( const char *lpWord, char cChar, Proc proc, ParamPtr val,
100 const char *lpDesc=NULL, const char *lpExtra=NULL,
101 const char *lpValue=NULL
102 );
103 void addParam( const char *lpWord, char cChar, Proc proc,
104 const char *lpDesc=NULL, const char *lpExtra=NULL,
105 const char *lpValue=NULL
106 );
107 void addParam( const char *lpWord, char cChar, ParamPtr val,
108 const char *lpDesc=NULL, const char *lpExtra=NULL,
109 const char *lpValue=NULL
110 );
111
112 void addParam( const char *lpWord, Proc proc, ParamPtr val,
113 const char *lpDesc=NULL, const char *lpExtra=NULL,
114 const char *lpValue=NULL
115 );
116 void addParam( const char *lpWord, Proc proc,
117 const char *lpDesc=NULL, const char *lpExtra=NULL,
118 const char *lpValue=NULL
119 );
120 void addParam( const char *lpWord, ParamPtr val,
121 const char *lpDesc=NULL, const char *lpExtra=NULL,
122 const char *lpValue=NULL
123 );
124
125 void addParam( char cChar, Proc proc, ParamPtr val,
126 const char *lpDesc=NULL, const char *lpExtra=NULL,
127 const char *lpValue=NULL
128 );
129 void addParam( char cChar, Proc proc,
130 const char *lpDesc=NULL, const char *lpExtra=NULL,
131 const char *lpValue=NULL
132 );
133 void addParam( char cChar, ParamPtr val,
134 const char *lpDesc=NULL, const char *lpExtra=NULL,
135 const char *lpValue=NULL
136 );
137
138 void process( int argc, char *argv[] );
139 void addHelpBanner( const char *sHelpBanner );
140
141 private:
142 ArgSpec *checkWord( const char *arg );
143 ArgSpec *checkLetr( const char arg );
144
145 public:
146 virtual int cmdParam( int argc, char *argv[] );
147 virtual int unknownParam( int argc, char *argv[] );
148 virtual int help( int argc, char *argv[] );
149
150 private:
151 typedef struct Banner
152 {
153 Bu::FString sBanner;
154 ArgSpec *pBefore;
155 } Banner;
156 Bu::List<Banner *> lBan;
157 Bu::List<ArgSpec *> lArg;
158 };
159}
160
161#define mkproc( cls ) static_cast<int (Bu::ParamProc::*)( int, char *[])>(&cls)
162
163#endif
diff --git a/src/ringbuffer.h b/src/ringbuffer.h
index 04add42..f4fd58c 100644
--- a/src/ringbuffer.h
+++ b/src/ringbuffer.h
@@ -17,6 +17,7 @@ namespace Bu
17{ 17{
18 template<typename value, typename valuealloc> class RingBuffer; 18 template<typename value, typename valuealloc> class RingBuffer;
19 19
20 /** @cond DEVEL */
20 template<typename value, typename valuealloc> 21 template<typename value, typename valuealloc>
21 class RingBufferCore 22 class RingBufferCore
22 { 23 {
@@ -119,6 +120,7 @@ namespace Bu
119 value *aData; 120 value *aData;
120 valuealloc va; 121 valuealloc va;
121 }; 122 };
123 /** @endcond */
122 124
123 /** 125 /**
124 *@ingroup Containers 126 *@ingroup Containers
diff --git a/src/server.cpp b/src/server.cpp
index 51c056a..e701a69 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -8,9 +8,9 @@
8#include "bu/server.h" 8#include "bu/server.h"
9#include <errno.h> 9#include <errno.h>
10#include <unistd.h> 10#include <unistd.h>
11#include "bu/serversocket.h" 11#include "bu/tcpserversocket.h"
12#include "bu/client.h" 12#include "bu/client.h"
13#include "bu/socket.h" 13#include "bu/tcpsocket.h"
14#include "bu/config.h" 14#include "bu/config.h"
15 15
16Bu::Server::Server() : 16Bu::Server::Server() :
@@ -28,7 +28,7 @@ Bu::Server::~Server()
28 28
29void Bu::Server::addPort( int nPort, int nPoolSize ) 29void Bu::Server::addPort( int nPort, int nPoolSize )
30{ 30{
31 ServerSocket *s = new ServerSocket( nPort, nPoolSize ); 31 TcpServerSocket *s = new TcpServerSocket( nPort, nPoolSize );
32 int nSocket = s->getSocket(); 32 int nSocket = s->getSocket();
33 FD_SET( nSocket, &fdActive ); 33 FD_SET( nSocket, &fdActive );
34 hServers.insert( nSocket, s ); 34 hServers.insert( nSocket, s );
@@ -36,7 +36,7 @@ void Bu::Server::addPort( int nPort, int nPoolSize )
36 36
37void Bu::Server::addPort( const FString &sAddr, int nPort, int nPoolSize ) 37void Bu::Server::addPort( const FString &sAddr, int nPort, int nPoolSize )
38{ 38{
39 ServerSocket *s = new ServerSocket( sAddr, nPort, nPoolSize ); 39 TcpServerSocket *s = new TcpServerSocket( sAddr, nPort, nPoolSize );
40 int nSocket = s->getSocket(); 40 int nSocket = s->getSocket();
41 FD_SET( nSocket, &fdActive ); 41 FD_SET( nSocket, &fdActive );
42 hServers.insert( nSocket, s ); 42 hServers.insert( nSocket, s );
@@ -75,7 +75,7 @@ void Bu::Server::scan()
75 { 75 {
76 if( hServers.has( j ) ) 76 if( hServers.has( j ) )
77 { 77 {
78 ServerSocket *pSrv = hServers.get( j ); 78 TcpServerSocket *pSrv = hServers.get( j );
79 addClient( pSrv->accept(), pSrv->getPort() ); 79 addClient( pSrv->accept(), pSrv->getPort() );
80 } 80 }
81 else 81 else
@@ -97,7 +97,7 @@ void Bu::Server::scan()
97 { 97 {
98 pClient->processOutput(); 98 pClient->processOutput();
99 } 99 }
100 catch( Bu::SocketException &e ) 100 catch( Bu::TcpSocketException &e )
101 { 101 {
102 closeClient( j ); 102 closeClient( j );
103 } 103 }
@@ -136,7 +136,7 @@ void Bu::Server::addClient( int nSocket, int nPort )
136 FD_SET( nSocket, &fdActive ); 136 FD_SET( nSocket, &fdActive );
137 137
138 Client *c = new Client( 138 Client *c = new Client(
139 new Bu::Socket( nSocket ), 139 new Bu::TcpSocket( nSocket ),
140 new SrvClientLinkFactory() 140 new SrvClientLinkFactory()
141 ); 141 );
142 hClients.insert( nSocket, c ); 142 hClients.insert( nSocket, c );
diff --git a/src/server.h b/src/server.h
index 74ee99a..d6726fd 100644
--- a/src/server.h
+++ b/src/server.h
@@ -25,8 +25,8 @@
25 25
26namespace Bu 26namespace Bu
27{ 27{
28 class ServerSocket; 28 class TcpServerSocket;
29 class Socket; 29 class TcpSocket;
30 class Client; 30 class Client;
31 31
32 /** 32 /**
@@ -97,7 +97,7 @@ namespace Bu
97 int nTimeoutSec; 97 int nTimeoutSec;
98 int nTimeoutUSec; 98 int nTimeoutUSec;
99 fd_set fdActive; 99 fd_set fdActive;
100 typedef Hash<int,ServerSocket *> SrvHash; 100 typedef Hash<int,TcpServerSocket *> SrvHash;
101 SrvHash hServers; 101 SrvHash hServers;
102 typedef Hash<int,Client *> ClientHash; 102 typedef Hash<int,Client *> ClientHash;
103 ClientHash hClients; 103 ClientHash hClients;
diff --git a/src/sharedcore.h b/src/sharedcore.h
index ac36606..1887ca2 100644
--- a/src/sharedcore.h
+++ b/src/sharedcore.h
@@ -15,6 +15,53 @@
15 15
16namespace Bu 16namespace Bu
17{ 17{
18 /**
19 * A mechanism for creating classes that perform lazy copies. The concept
20 * behind this is that instead of copying a large object when it is assigned
21 * or passed into a copy constructor we simply copy a pointer internally.
22 * The assumption is that many times when an object is passed by value we
23 * don't really want to keep the object around, we want the recipient to
24 * take ownership without allocating a new object. This allows that to
25 * happen.
26 *
27 * When used properly this makes object copying essentially free (O(1),
28 * that is) and performs the actual copy when a user tries to modify the
29 * object.
30 *
31 * For example, lets look at something like the getKeys function in
32 * Bu::Hash. When this function is called it creates a Bu::List of
33 * appropriate type, fills it with keys, and returns it. This is a good
34 * way for this function to behave, there may be additional issues if the
35 * List object were allocated with new and not on the stack. However,
36 * returning the List at the end of the function could potentially take
37 * a very long time depending on the size of the list and the type of the
38 * key. In this case the getKeys function doesn't want ownership of the
39 * List object, and when it returns it, it's local copy will be destroyed.
40 *
41 * However, List inherits from SharedCore, which means that when it is
42 * returned all we do is copy a pointer to the "core" of the list, which
43 * is a very fast operatorion. For a brief moment, before anyone can do
44 * anything else, there are two objects referencing the core of that single
45 * list. However, the getKeys() function will destroy it's local copy
46 * before the calling function can use it's new copy. That means that by
47 * the time the calling function can use it's new List of keys it is the
48 * only one with a reference to the core, and no copy will need to happen.
49 *
50 * Using SharedCore on your own classes is fairly straight forward. There
51 * are only a couple of steps. First, break the class into two classes.
52 * Move every variable from the original class (generally everything that's
53 * private) into the new class. Then make the original class inherit from
54 * SharedCore. The SharedCore template takes 2 parameters, first is the
55 * class it's inheriting from, second is the new core class. Now, in your
56 * original class you will have one class variable, a pointer named core.
57 * All of your original variables will be accessable through core. The next
58 * step is to access everything you used to through core, and to find
59 * every function that may change data in the core. At the top of every
60 * function that may change data you want to call _hardCopy().
61 *
62 * That's more or less it. A more detailed guide will be written soon.
63 * @todo Write a guide for this.
64 */
18 template<typename Shell, typename Core> 65 template<typename Shell, typename Core>
19 class SharedCore 66 class SharedCore
20 { 67 {
diff --git a/src/serversocket.cpp b/src/tcpserversocket.cpp
index 87d0035..7d7f6e4 100644
--- a/src/serversocket.cpp
+++ b/src/tcpserversocket.cpp
@@ -21,13 +21,13 @@
21#include <sys/types.h> 21#include <sys/types.h>
22//#include <termios.h> 22//#include <termios.h>
23#include <fcntl.h> 23#include <fcntl.h>
24#include "bu/serversocket.h" 24#include "bu/tcpserversocket.h"
25 25
26#include "bu/config.h" 26#include "bu/config.h"
27 27
28namespace Bu { subExceptionDef( ServerSocketException ) } 28namespace Bu { subExceptionDef( TcpServerSocketException ) }
29 29
30Bu::ServerSocket::ServerSocket( int nPort, int nPoolSize ) : 30Bu::TcpServerSocket::TcpServerSocket( int nPort, int nPoolSize ) :
31 nPort( nPort ) 31 nPort( nPort )
32{ 32{
33#ifdef WIN32 33#ifdef WIN32
@@ -48,7 +48,7 @@ Bu::ServerSocket::ServerSocket( int nPort, int nPoolSize ) :
48 startServer( name, nPoolSize ); 48 startServer( name, nPoolSize );
49} 49}
50 50
51Bu::ServerSocket::ServerSocket(const FString &sAddr,int nPort, int nPoolSize) : 51Bu::TcpServerSocket::TcpServerSocket(const FString &sAddr,int nPort, int nPoolSize) :
52 nPort( nPort ) 52 nPort( nPort )
53{ 53{
54#ifdef WIN32 54#ifdef WIN32
@@ -72,7 +72,7 @@ Bu::ServerSocket::ServerSocket(const FString &sAddr,int nPort, int nPoolSize) :
72 startServer( name, nPoolSize ); 72 startServer( name, nPoolSize );
73} 73}
74 74
75Bu::ServerSocket::ServerSocket( int nServer, bool bInit, int nPoolSize ) : 75Bu::TcpServerSocket::TcpServerSocket( int nServer, bool bInit, int nPoolSize ) :
76 nServer( nServer ), 76 nServer( nServer ),
77 nPort( 0 ) 77 nPort( 0 )
78{ 78{
@@ -95,7 +95,7 @@ Bu::ServerSocket::ServerSocket( int nServer, bool bInit, int nPoolSize ) :
95 } 95 }
96} 96}
97 97
98Bu::ServerSocket::ServerSocket( const ServerSocket &rSrc ) 98Bu::TcpServerSocket::TcpServerSocket( const TcpServerSocket &rSrc )
99{ 99{
100#ifdef WIN32 100#ifdef WIN32
101 Bu::Winsock2::getInstance(); 101 Bu::Winsock2::getInstance();
@@ -107,20 +107,20 @@ Bu::ServerSocket::ServerSocket( const ServerSocket &rSrc )
107 FD_SET( nServer, &fdActive ); 107 FD_SET( nServer, &fdActive );
108} 108}
109 109
110Bu::ServerSocket::~ServerSocket() 110Bu::TcpServerSocket::~TcpServerSocket()
111{ 111{
112 if( nServer > -1 ) 112 if( nServer > -1 )
113 ::close( nServer ); 113 ::close( nServer );
114} 114}
115 115
116void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize ) 116void Bu::TcpServerSocket::startServer( struct sockaddr_in &name, int nPoolSize )
117{ 117{
118 /* Create the socket. */ 118 /* Create the socket. */
119 nServer = bu_socket( PF_INET, SOCK_STREAM, 0 ); 119 nServer = bu_socket( PF_INET, SOCK_STREAM, 0 );
120 120
121 if( nServer < 0 ) 121 if( nServer < 0 )
122 { 122 {
123 throw Bu::ServerSocketException("Couldn't create a listen socket."); 123 throw Bu::TcpServerSocketException("Couldn't create a listen socket.");
124 } 124 }
125 125
126 int opt = 1; 126 int opt = 1;
@@ -135,16 +135,16 @@ void Bu::ServerSocket::startServer( struct sockaddr_in &name, int nPoolSize )
135 initServer( name, nPoolSize ); 135 initServer( name, nPoolSize );
136} 136}
137 137
138void Bu::ServerSocket::initServer( struct sockaddr_in &name, int nPoolSize ) 138void Bu::TcpServerSocket::initServer( struct sockaddr_in &name, int nPoolSize )
139{ 139{
140 if( bu_bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 ) 140 if( bu_bind( nServer, (struct sockaddr *) &name, sizeof(name) ) < 0 )
141 { 141 {
142 throw Bu::ServerSocketException("Couldn't bind to the listen socket."); 142 throw Bu::TcpServerSocketException("Couldn't bind to the listen socket.");
143 } 143 }
144 144
145 if( bu_listen( nServer, nPoolSize ) < 0 ) 145 if( bu_listen( nServer, nPoolSize ) < 0 )
146 { 146 {
147 throw Bu::ServerSocketException( 147 throw Bu::TcpServerSocketException(
148 "Couldn't begin listening to the server socket." 148 "Couldn't begin listening to the server socket."
149 ); 149 );
150 } 150 }
@@ -154,12 +154,12 @@ void Bu::ServerSocket::initServer( struct sockaddr_in &name, int nPoolSize )
154 FD_SET( nServer, &fdActive ); 154 FD_SET( nServer, &fdActive );
155} 155}
156 156
157int Bu::ServerSocket::getSocket() 157int Bu::TcpServerSocket::getSocket()
158{ 158{
159 return nServer; 159 return nServer;
160} 160}
161 161
162int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec ) 162int Bu::TcpServerSocket::accept( int nTimeoutSec, int nTimeoutUSec )
163{ 163{
164 fd_set fdRead = fdActive; 164 fd_set fdRead = fdActive;
165 165
@@ -171,7 +171,7 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec )
171 if( TEMP_FAILURE_RETRY( 171 if( TEMP_FAILURE_RETRY(
172 bu_select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 ) 172 bu_select( nServer+1, &fdRead, NULL, NULL, &xT )) < 0 )
173 { 173 {
174 throw Bu::ServerSocketException( 174 throw Bu::TcpServerSocketException(
175 "Error scanning for new connections: %s", strerror( errno ) 175 "Error scanning for new connections: %s", strerror( errno )
176 ); 176 );
177 } 177 }
@@ -200,7 +200,7 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec )
200#endif /* WIN32 */ 200#endif /* WIN32 */
201 if( nClient < 0 ) 201 if( nClient < 0 )
202 { 202 {
203 throw Bu::ServerSocketException( 203 throw Bu::TcpServerSocketException(
204 "Error accepting a new connection: %s", strerror( errno ) 204 "Error accepting a new connection: %s", strerror( errno )
205 ); 205 );
206 } 206 }
@@ -219,7 +219,7 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec )
219 flags |= O_NONBLOCK; 219 flags |= O_NONBLOCK;
220 if( fcntl( nClient, F_SETFL, flags ) < 0) 220 if( fcntl( nClient, F_SETFL, flags ) < 0)
221 { 221 {
222 throw Bu::ServerSocketException( 222 throw Bu::TcpServerSocketException(
223 "Error setting option on client socket: %s", 223 "Error setting option on client socket: %s",
224 strerror( errno ) 224 strerror( errno )
225 ); 225 );
@@ -242,7 +242,7 @@ int Bu::ServerSocket::accept( int nTimeoutSec, int nTimeoutUSec )
242 return -1; 242 return -1;
243} 243}
244 244
245int Bu::ServerSocket::getPort() 245int Bu::TcpServerSocket::getPort()
246{ 246{
247 return nPort; 247 return nPort;
248} 248}
diff --git a/src/serversocket.h b/src/tcpserversocket.h
index ee357a4..b1d7e02 100644
--- a/src/serversocket.h
+++ b/src/tcpserversocket.h
@@ -5,8 +5,8 @@
5 * terms of the license contained in the file LICENSE. 5 * terms of the license contained in the file LICENSE.
6 */ 6 */
7 7
8#ifndef BU_SERVER_SOCKET_H 8#ifndef BU_TCP_SERVER_SOCKET_H
9#define BU_SERVER_SOCKET_H 9#define BU_TCP_SERVER_SOCKET_H
10 10
11#include <stdint.h> 11#include <stdint.h>
12#include "bu/fstring.h" 12#include "bu/fstring.h"
@@ -20,7 +20,7 @@
20 20
21namespace Bu 21namespace Bu
22{ 22{
23 subExceptionDecl( ServerSocketException ); 23 subExceptionDecl( TcpServerSocketException );
24 24
25 /** 25 /**
26 * A single tcp/ip server socket. When created the server socket will bind 26 * A single tcp/ip server socket. When created the server socket will bind
@@ -34,14 +34,14 @@ namespace Bu
34 * 34 *
35 *@ingroup Serving 35 *@ingroup Serving
36 */ 36 */
37 class ServerSocket 37 class TcpServerSocket
38 { 38 {
39 public: 39 public:
40 ServerSocket( int nPort, int nPoolSize=40 ); 40 TcpServerSocket( int nPort, int nPoolSize=40 );
41 ServerSocket( const FString &sAddr, int nPort, int nPoolSize=40 ); 41 TcpServerSocket( const FString &sAddr, int nPort, int nPoolSize=40 );
42 ServerSocket( int nSocket, bool bInit, int nPoolSize=40 ); 42 TcpServerSocket( int nSocket, bool bInit, int nPoolSize=40 );
43 ServerSocket( const ServerSocket &rSrc ); 43 TcpServerSocket( const TcpServerSocket &rSrc );
44 virtual ~ServerSocket(); 44 virtual ~TcpServerSocket();
45 45
46 int accept( int nTimeoutSec=0, int nTimeoutUSec=0 ); 46 int accept( int nTimeoutSec=0, int nTimeoutUSec=0 );
47 int getSocket(); 47 int getSocket();
diff --git a/src/socket.cpp b/src/tcpsocket.cpp
index baf3be3..bbd9cf5 100644
--- a/src/socket.cpp
+++ b/src/tcpsocket.cpp
@@ -14,7 +14,7 @@
14#include <sys/time.h> 14#include <sys/time.h>
15#include <errno.h> 15#include <errno.h>
16#include <fcntl.h> 16#include <fcntl.h>
17#include "bu/socket.h" 17#include "bu/tcpsocket.h"
18 18
19#include "bu/config.h" 19#include "bu/config.h"
20 20
@@ -29,10 +29,10 @@
29 29
30#define RBS (1024*2) 30#define RBS (1024*2)
31 31
32namespace Bu { subExceptionDef( SocketException ) } 32namespace Bu { subExceptionDef( TcpSocketException ) }
33 33
34Bu::Socket::Socket( int nSocket ) : 34Bu::TcpSocket::TcpSocket( int nTcpSocket ) :
35 nSocket( nSocket ), 35 nTcpSocket( nTcpSocket ),
36 bActive( true ), 36 bActive( true ),
37 bBlocking( true ) 37 bBlocking( true )
38{ 38{
@@ -42,8 +42,9 @@ Bu::Socket::Socket( int nSocket ) :
42 setAddress(); 42 setAddress();
43} 43}
44 44
45Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) : 45Bu::TcpSocket::TcpSocket( const Bu::FString &sAddr, int nPort, int nTimeout,
46 nSocket( 0 ), 46 bool bBlocking ) :
47 nTcpSocket( 0 ),
47 bActive( false ), 48 bActive( false ),
48 bBlocking( true ) 49 bBlocking( true )
49{ 50{
@@ -52,9 +53,9 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) :
52#endif 53#endif
53 54
54 /* Create the socket. */ 55 /* Create the socket. */
55 nSocket = bu_socket( PF_INET, SOCK_STREAM, 0 ); 56 nTcpSocket = bu_socket( PF_INET, SOCK_STREAM, 0 );
56 57
57 if( nSocket < 0 ) 58 if( nTcpSocket < 0 )
58 { 59 {
59 throw ExceptionBase("Couldn't create socket.\n"); 60 throw ExceptionBase("Couldn't create socket.\n");
60 } 61 }
@@ -78,12 +79,12 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) :
78 sAddr.getStr(), ibuf, &aiHints, &pAddr )) != 0 ) 79 sAddr.getStr(), ibuf, &aiHints, &pAddr )) != 0 )
79 { 80 {
80 close(); 81 close();
81 throw Bu::SocketException("Couldn't resolve hostname %s (%s).\n", 82 throw Bu::TcpSocketException("Couldn't resolve hostname %s (%s).\n",
82 sAddr.getStr(), bu_gai_strerror(ret)); 83 sAddr.getStr(), bu_gai_strerror(ret));
83 } 84 }
84 85
85 bu_connect( 86 bu_connect(
86 nSocket, 87 nTcpSocket,
87 pAddr->ai_addr, 88 pAddr->ai_addr,
88 pAddr->ai_addrlen 89 pAddr->ai_addrlen
89 ); 90 );
@@ -101,17 +102,17 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) :
101 int retval; 102 int retval;
102 103
103 FD_ZERO(&rfds); 104 FD_ZERO(&rfds);
104 FD_SET(nSocket, &rfds); 105 FD_SET(nTcpSocket, &rfds);
105 FD_ZERO(&wfds); 106 FD_ZERO(&wfds);
106 FD_SET(nSocket, &wfds); 107 FD_SET(nTcpSocket, &wfds);
107 FD_ZERO(&efds); 108 FD_ZERO(&efds);
108 FD_SET(nSocket, &efds); 109 FD_SET(nTcpSocket, &efds);
109 110
110 struct timeval tv; 111 struct timeval tv;
111 tv.tv_sec = nTimeout; 112 tv.tv_sec = nTimeout;
112 tv.tv_usec = 0; 113 tv.tv_usec = 0;
113 114
114 retval = bu_select( nSocket+1, &rfds, &wfds, &efds, &tv ); 115 retval = bu_select( nTcpSocket+1, &rfds, &wfds, &efds, &tv );
115 116
116 if( retval == 0 ) 117 if( retval == 0 )
117 { 118 {
@@ -120,51 +121,54 @@ Bu::Socket::Socket( const Bu::FString &sAddr, int nPort, int nTimeout ) :
120 } 121 }
121 read( NULL, 0 ); // See if we can get any errors out of the way early. 122 read( NULL, 0 ); // See if we can get any errors out of the way early.
122 } 123 }
124
125 if( bBlocking )
126 setBlocking( bBlocking );
123} 127}
124 128
125Bu::Socket::~Socket() 129Bu::TcpSocket::~TcpSocket()
126{ 130{
127 close(); 131 close();
128} 132}
129 133
130void Bu::Socket::close() 134void Bu::TcpSocket::close()
131{ 135{
132 if( bActive ) 136 if( bActive )
133 { 137 {
134#ifndef WIN32 138#ifndef WIN32
135 fsync( nSocket ); 139 fsync( nTcpSocket );
136#endif 140#endif
137#ifdef WIN32 141#ifdef WIN32
138 #ifndef SHUT_RDWR 142 #ifndef SHUT_RDWR
139 #define SHUT_RDWR (SD_BOTH) 143 #define SHUT_RDWR (SD_BOTH)
140 #endif 144 #endif
141#endif 145#endif
142 bu_shutdown( nSocket, SHUT_RDWR ); 146 bu_shutdown( nTcpSocket, SHUT_RDWR );
143 ::close( nSocket ); 147 ::close( nTcpSocket );
144 } 148 }
145 bActive = false; 149 bActive = false;
146} 150}
147 151
148size_t Bu::Socket::read( void *pBuf, size_t nBytes ) 152size_t Bu::TcpSocket::read( void *pBuf, size_t nBytes )
149{ 153{
150 fd_set rfds; 154 fd_set rfds;
151 FD_ZERO(&rfds); 155 FD_ZERO(&rfds);
152 FD_SET(nSocket, &rfds); 156 FD_SET(nTcpSocket, &rfds);
153 struct timeval tv = {0, 0}; 157 struct timeval tv = {0, 0};
154 if( bu_select( nSocket+1, &rfds, NULL, NULL, &tv ) < 0 ) 158 if( bu_select( nTcpSocket+1, &rfds, NULL, NULL, &tv ) < 0 )
155 { 159 {
156 int iErr = errno; 160 int iErr = errno;
157 close(); 161 close();
158 throw SocketException( SocketException::cRead, strerror(iErr) ); 162 throw TcpSocketException( TcpSocketException::cRead, strerror(iErr) );
159 } 163 }
160 if( FD_ISSET( nSocket, &rfds ) || bBlocking ) 164 if( FD_ISSET( nTcpSocket, &rfds ) || bBlocking )
161 { 165 {
162 int nRead = TEMP_FAILURE_RETRY( 166 int nRead = TEMP_FAILURE_RETRY(
163 bu_recv( nSocket, (char *) pBuf, nBytes, 0 ) ); 167 bu_recv( nTcpSocket, (char *) pBuf, nBytes, 0 ) );
164 if( nRead == 0 ) 168 if( nRead == 0 )
165 { 169 {
166 close(); 170 close();
167 throw SocketException( SocketException::cClosed, "Socket closed."); 171 throw TcpSocketException( TcpSocketException::cClosed, "TcpSocket closed.");
168 } 172 }
169 if( nRead < 0 ) 173 if( nRead < 0 )
170 { 174 {
@@ -176,14 +180,14 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes )
176 if( errno == ENETRESET || errno == ECONNRESET ) 180 if( errno == ENETRESET || errno == ECONNRESET )
177 { 181 {
178 close(); 182 close();
179 throw SocketException( SocketException::cClosed, 183 throw TcpSocketException( TcpSocketException::cClosed,
180 strerror(errno) ); 184 strerror(errno) );
181 } 185 }
182 if( errno == EAGAIN ) 186 if( errno == EAGAIN )
183 return 0; 187 return 0;
184 int iErr = errno; 188 int iErr = errno;
185 close(); 189 close();
186 throw SocketException( SocketException::cRead, strerror(iErr) ); 190 throw TcpSocketException( TcpSocketException::cRead, strerror(iErr) );
187#endif 191#endif
188 } 192 }
189 return nRead; 193 return nRead;
@@ -191,7 +195,7 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes )
191 return 0; 195 return 0;
192} 196}
193 197
194size_t Bu::Socket::read( void *pBuf, size_t nBytes, 198size_t Bu::TcpSocket::read( void *pBuf, size_t nBytes,
195 uint32_t nSec, uint32_t nUSec ) 199 uint32_t nSec, uint32_t nUSec )
196{ 200{
197 struct timeval tv; 201 struct timeval tv;
@@ -199,7 +203,7 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
199 203
200 fd_set rfds; 204 fd_set rfds;
201 FD_ZERO(&rfds); 205 FD_ZERO(&rfds);
202 FD_SET(nSocket, &rfds); 206 FD_SET(nTcpSocket, &rfds);
203 207
204#ifdef WIN32 208#ifdef WIN32
205 DWORD dwStart = GetTickCount(); 209 DWORD dwStart = GetTickCount();
@@ -216,7 +220,7 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
216 { 220 {
217 tv.tv_sec = nSec; 221 tv.tv_sec = nSec;
218 tv.tv_usec = nUSec; 222 tv.tv_usec = nUSec;
219 bu_select( nSocket+1, &rfds, NULL, NULL, &tv ); 223 bu_select( nTcpSocket+1, &rfds, NULL, NULL, &tv );
220 nRead += read( ((char *)pBuf)+nRead, nBytes-nRead ); 224 nRead += read( ((char *)pBuf)+nRead, nBytes-nRead );
221 if( nRead >= nBytes ) 225 if( nRead >= nBytes )
222 break; 226 break;
@@ -235,13 +239,13 @@ size_t Bu::Socket::read( void *pBuf, size_t nBytes,
235 return nRead; 239 return nRead;
236} 240}
237 241
238size_t Bu::Socket::write( const void *pBuf, size_t nBytes ) 242size_t Bu::TcpSocket::write( const void *pBuf, size_t nBytes )
239{ 243{
240//#ifdef WIN32 244//#ifdef WIN32
241 int nWrote = TEMP_FAILURE_RETRY( 245 int nWrote = TEMP_FAILURE_RETRY(
242 bu_send( nSocket, (const char *) pBuf, nBytes, 0 ) ); 246 bu_send( nTcpSocket, (const char *) pBuf, nBytes, 0 ) );
243//#else 247//#else
244// int nWrote = TEMP_FAILURE_RETRY( ::write( nSocket, pBuf, nBytes ) ); 248// int nWrote = TEMP_FAILURE_RETRY( ::write( nTcpSocket, pBuf, nBytes ) );
245//#endif 249//#endif
246 if( nWrote < 0 ) 250 if( nWrote < 0 )
247 { 251 {
@@ -252,19 +256,19 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes )
252#else 256#else
253 if( errno == EAGAIN ) return 0; 257 if( errno == EAGAIN ) return 0;
254#endif 258#endif
255 throw SocketException( SocketException::cWrite, strerror(errno) ); 259 throw TcpSocketException( TcpSocketException::cWrite, strerror(errno) );
256 } 260 }
257 return nWrote; 261 return nWrote;
258} 262}
259 263
260size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32_t nUSec ) 264size_t Bu::TcpSocket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32_t nUSec )
261{ 265{
262 struct timeval tv; 266 struct timeval tv;
263 size_t nWrote = 0; 267 size_t nWrote = 0;
264 268
265 fd_set wfds; 269 fd_set wfds;
266 FD_ZERO(&wfds); 270 FD_ZERO(&wfds);
267 FD_SET(nSocket, &wfds); 271 FD_SET(nTcpSocket, &wfds);
268 272
269#ifdef WIN32 273#ifdef WIN32
270 DWORD dwStart = GetTickCount(); 274 DWORD dwStart = GetTickCount();
@@ -281,7 +285,7 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32
281 { 285 {
282 tv.tv_sec = nSec; 286 tv.tv_sec = nSec;
283 tv.tv_usec = nUSec; 287 tv.tv_usec = nUSec;
284 bu_select( nSocket+1, NULL, &wfds, NULL, &tv ); 288 bu_select( nTcpSocket+1, NULL, &wfds, NULL, &tv );
285 nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote ); 289 nWrote += write( ((char *)pBuf)+nWrote, nBytes-nWrote );
286 if( nWrote >= nBytes ) 290 if( nWrote >= nBytes )
287 break; 291 break;
@@ -300,101 +304,101 @@ size_t Bu::Socket::write( const void *pBuf, size_t nBytes, uint32_t nSec, uint32
300 return nWrote; 304 return nWrote;
301} 305}
302 306
303long Bu::Socket::tell() 307long Bu::TcpSocket::tell()
304{ 308{
305 throw UnsupportedException(); 309 throw UnsupportedException();
306} 310}
307 311
308void Bu::Socket::seek( long ) 312void Bu::TcpSocket::seek( long )
309{ 313{
310 throw UnsupportedException(); 314 throw UnsupportedException();
311} 315}
312 316
313void Bu::Socket::setPos( long ) 317void Bu::TcpSocket::setPos( long )
314{ 318{
315 throw UnsupportedException(); 319 throw UnsupportedException();
316} 320}
317 321
318void Bu::Socket::setPosEnd( long ) 322void Bu::TcpSocket::setPosEnd( long )
319{ 323{
320 throw UnsupportedException(); 324 throw UnsupportedException();
321} 325}
322 326
323bool Bu::Socket::isEos() 327bool Bu::TcpSocket::isEos()
324{ 328{
325 return !bActive; 329 return !bActive;
326} 330}
327 331
328bool Bu::Socket::canRead() 332bool Bu::TcpSocket::canRead()
329{ 333{
330 fd_set rfds; 334 fd_set rfds;
331 FD_ZERO(&rfds); 335 FD_ZERO(&rfds);
332 FD_SET(nSocket, &rfds); 336 FD_SET(nTcpSocket, &rfds);
333 struct timeval tv = { 0, 0 }; 337 struct timeval tv = { 0, 0 };
334 int retval = bu_select( nSocket+1, &rfds, NULL, NULL, &tv ); 338 int retval = bu_select( nTcpSocket+1, &rfds, NULL, NULL, &tv );
335 if( retval == -1 ) 339 if( retval == -1 )
336 throw SocketException( 340 throw TcpSocketException(
337 SocketException::cBadRead, 341 TcpSocketException::cBadRead,
338 "Bad Read error" 342 "Bad Read error"
339 ); 343 );
340 344
341 if( !FD_ISSET( nSocket, &rfds ) ) 345 if( !FD_ISSET( nTcpSocket, &rfds ) )
342 return false; 346 return false;
343 return true; 347 return true;
344} 348}
345 349
346bool Bu::Socket::canWrite() 350bool Bu::TcpSocket::canWrite()
347{ 351{
348 fd_set wfds; 352 fd_set wfds;
349 FD_ZERO(&wfds); 353 FD_ZERO(&wfds);
350 FD_SET(nSocket, &wfds); 354 FD_SET(nTcpSocket, &wfds);
351 struct timeval tv = { 0, 0 }; 355 struct timeval tv = { 0, 0 };
352 int retval = bu_select( nSocket+1, NULL, &wfds, NULL, &tv ); 356 int retval = bu_select( nTcpSocket+1, NULL, &wfds, NULL, &tv );
353 if( retval == -1 ) 357 if( retval == -1 )
354 throw SocketException( 358 throw TcpSocketException(
355 SocketException::cBadRead, 359 TcpSocketException::cBadRead,
356 "Bad Read error" 360 "Bad Read error"
357 ); 361 );
358 if( !FD_ISSET( nSocket, &wfds ) ) 362 if( !FD_ISSET( nTcpSocket, &wfds ) )
359 return false; 363 return false;
360 return true; 364 return true;
361} 365}
362 366
363bool Bu::Socket::isReadable() 367bool Bu::TcpSocket::isReadable()
364{ 368{
365 return true; 369 return true;
366} 370}
367 371
368bool Bu::Socket::isWritable() 372bool Bu::TcpSocket::isWritable()
369{ 373{
370 return true; 374 return true;
371} 375}
372 376
373bool Bu::Socket::isSeekable() 377bool Bu::TcpSocket::isSeekable()
374{ 378{
375 return false; 379 return false;
376} 380}
377 381
378bool Bu::Socket::isBlocking() 382bool Bu::TcpSocket::isBlocking()
379{ 383{
380#ifndef WIN32 384#ifndef WIN32
381 return ((fcntl( nSocket, F_GETFL, 0 ) & O_NONBLOCK) != O_NONBLOCK); 385 return ((fcntl( nTcpSocket, F_GETFL, 0 ) & O_NONBLOCK) != O_NONBLOCK);
382#else 386#else
383 return false; 387 return false;
384#endif 388#endif
385} 389}
386 390
387void Bu::Socket::setBlocking( bool bBlocking ) 391void Bu::TcpSocket::setBlocking( bool bBlocking )
388{ 392{
389 this->bBlocking = bBlocking; 393 this->bBlocking = bBlocking;
390#ifndef WIN32 394#ifndef WIN32
391 if( bBlocking ) 395 if( bBlocking )
392 { 396 {
393 fcntl( nSocket, F_SETFL, fcntl( nSocket, F_GETFL, 0 ) & (~O_NONBLOCK) ); 397 fcntl( nTcpSocket, F_SETFL, fcntl( nTcpSocket, F_GETFL, 0 ) & (~O_NONBLOCK) );
394 } 398 }
395 else 399 else
396 { 400 {
397 fcntl( nSocket, F_SETFL, fcntl( nSocket, F_GETFL, 0 ) | O_NONBLOCK ); 401 fcntl( nTcpSocket, F_SETFL, fcntl( nTcpSocket, F_GETFL, 0 ) | O_NONBLOCK );
398 } 402 }
399#else 403#else
400 u_long iMode; 404 u_long iMode;
@@ -408,39 +412,39 @@ void Bu::Socket::setBlocking( bool bBlocking )
408 // socket based on the numerical value of iMode. 412 // socket based on the numerical value of iMode.
409 // If iMode = 0, blocking is enabled; 413 // If iMode = 0, blocking is enabled;
410 // If iMode != 0, non-blocking mode is enabled. 414 // If iMode != 0, non-blocking mode is enabled.
411 bu_ioctlsocket(nSocket, FIONBIO, &iMode); 415 bu_ioctlsocket(nTcpSocket, FIONBIO, &iMode);
412#endif 416#endif
413} 417}
414 418
415void Bu::Socket::setSize( long ) 419void Bu::TcpSocket::setSize( long )
416{ 420{
417} 421}
418 422
419void Bu::Socket::flush() 423void Bu::TcpSocket::flush()
420{ 424{
421} 425}
422 426
423bool Bu::Socket::isOpen() 427bool Bu::TcpSocket::isOpen()
424{ 428{
425 return bActive; 429 return bActive;
426} 430}
427 431
428void Bu::Socket::setAddress() 432void Bu::TcpSocket::setAddress()
429{ 433{
430 struct sockaddr_in addr; 434 struct sockaddr_in addr;
431 socklen_t len = sizeof(addr); 435 socklen_t len = sizeof(addr);
432 addr.sin_family = AF_INET; 436 addr.sin_family = AF_INET;
433 bu_getpeername( nSocket, (sockaddr *)(&addr), &len ); 437 bu_getpeername( nTcpSocket, (sockaddr *)(&addr), &len );
434 sAddress = bu_inet_ntoa( addr.sin_addr ); 438 sAddress = bu_inet_ntoa( addr.sin_addr );
435} 439}
436 440
437Bu::FString Bu::Socket::getAddress() const 441Bu::FString Bu::TcpSocket::getAddress() const
438{ 442{
439 return sAddress; 443 return sAddress;
440} 444}
441 445
442Bu::Socket::operator int() const 446Bu::TcpSocket::operator int() const
443{ 447{
444 return nSocket; 448 return nTcpSocket;
445} 449}
446 450
diff --git a/src/socket.h b/src/tcpsocket.h
index c8f78f0..3361e84 100644
--- a/src/socket.h
+++ b/src/tcpsocket.h
@@ -5,8 +5,8 @@
5 * terms of the license contained in the file LICENSE. 5 * terms of the license contained in the file LICENSE.
6 */ 6 */
7 7
8#ifndef BU_SOCKET_H 8#ifndef BU_TCP_SOCKET_H
9#define BU_SOCKET_H 9#define BU_TCP_SOCKET_H
10 10
11#include <stdint.h> 11#include <stdint.h>
12 12
@@ -16,7 +16,7 @@
16 16
17namespace Bu 17namespace Bu
18{ 18{
19 subExceptionDeclBegin( SocketException ); 19 subExceptionDeclBegin( TcpSocketException );
20 enum { 20 enum {
21 cRead, 21 cRead,
22 cWrite, 22 cWrite,
@@ -40,28 +40,29 @@ namespace Bu
40 * Please note that there is a condition that will occur eventually (at 40 * Please note that there is a condition that will occur eventually (at
41 * least on *nix systems) that will trigger a SIGPIPE condition. This 41 * least on *nix systems) that will trigger a SIGPIPE condition. This
42 * will terminate your program immediately unless handled properly. Most 42 * will terminate your program immediately unless handled properly. Most
43 * people doing any connections with Socket will want to put this in their 43 * people doing any connections with TcpSocket will want to put this in
44 * program somewhere before they use it: 44 * their program somewhere before they use it:
45 *@code 45 *@code
46 #include <signal.h> 46 #include <signal.h>
47 ... 47 ...
48 ... 48 ...
49 ... 49 ...
50 sigset( SIGPIPE, SIG_IGN ); // do this before you use a Bu::Socket 50 sigset( SIGPIPE, SIG_IGN ); // do this before you use a Bu::TcpSocket
51 @endcode 51 @endcode
52 * When this is done, Bu::Socket will simply throw a broken pipe exception 52 * When this is done, Bu::TcpSocket will simply throw a broken pipe
53 * just like every other error condition, allowing your program to handle 53 * exception just like every other error condition, allowing your program
54 * it sanely. 54 * to handle it sanely.
55 * 55 *
56 *@ingroup Serving 56 *@ingroup Serving
57 *@ingroup Streams 57 *@ingroup Streams
58 */ 58 */
59 class Socket : public Stream 59 class TcpSocket : public Stream
60 { 60 {
61 public: 61 public:
62 Socket( int nSocket ); 62 TcpSocket( int nTcpSocket );
63 Socket( const FString &sAddr, int nPort, int nTimeout=30 ); 63 TcpSocket( const FString &sAddr, int nPort, int nTimeout=30,
64 virtual ~Socket(); 64 bool bBlocking=true );
65 virtual ~TcpSocket();
65 66
66 virtual void close(); 67 virtual void close();
67 //virtual void read(); 68 //virtual void read();
@@ -101,9 +102,9 @@ namespace Bu
101 void setAddress(); 102 void setAddress();
102 103
103#ifdef WIN32 104#ifdef WIN32
104 unsigned int nSocket; 105 unsigned int nTcpSocket;
105#else 106#else
106 int nSocket; 107 int nTcpSocket;
107#endif 108#endif
108 bool bActive; 109 bool bActive;
109 bool bBlocking; 110 bool bBlocking;
diff --git a/src/tests/socketblock.cpp b/src/tests/socketblock.cpp
index a1ea18d..793ef96 100644
--- a/src/tests/socketblock.cpp
+++ b/src/tests/socketblock.cpp
@@ -6,8 +6,8 @@
6 */ 6 */
7 7
8#include "bu/ito.h" 8#include "bu/ito.h"
9#include "bu/socket.h" 9#include "bu/tcpsocket.h"
10#include "bu/serversocket.h" 10#include "bu/tcpserversocket.h"
11#include <stdio.h> 11#include <stdio.h>
12#include <unistd.h> 12#include <unistd.h>
13 13
@@ -21,7 +21,7 @@ public:
21 21
22 virtual void run() 22 virtual void run()
23 { 23 {
24 Bu::Socket c = s.accept( 45, 0 ); 24 Bu::TcpSocket c = s.accept( 45, 0 );
25 printf("TstServer: Accetped connection.\n"); fflush( stdout ); 25 printf("TstServer: Accetped connection.\n"); fflush( stdout );
26 26
27 sleep( 1 ); 27 sleep( 1 );
@@ -35,7 +35,7 @@ public:
35 c.close(); 35 c.close();
36 } 36 }
37 37
38 Bu::ServerSocket s; 38 Bu::TcpServerSocket s;
39}; 39};
40 40
41int main() 41int main()
@@ -45,7 +45,7 @@ int main()
45 ts.start(); 45 ts.start();
46 46
47 printf("main: Connecting to server.\n"); fflush( stdout ); 47 printf("main: Connecting to server.\n"); fflush( stdout );
48 Bu::Socket s( "localhost", 55678 ); 48 Bu::TcpSocket s( "localhost", 55678 );
49 49
50 printf("main: Sending 4 bytes.\n"); fflush( stdout ); 50 printf("main: Sending 4 bytes.\n"); fflush( stdout );
51 s.write( "aoeu", 4 ); 51 s.write( "aoeu", 4 );
diff --git a/src/tests/socketbreak.cpp b/src/tests/socketbreak.cpp
index 8339630..7d3c71a 100644
--- a/src/tests/socketbreak.cpp
+++ b/src/tests/socketbreak.cpp
@@ -5,17 +5,17 @@
5 * terms of the license contained in the file LICENSE. 5 * terms of the license contained in the file LICENSE.
6 */ 6 */
7 7
8#include "bu/serversocket.h" 8#include "bu/tcpserversocket.h"
9#include "bu/socket.h" 9#include "bu/tcpsocket.h"
10#include <unistd.h> 10#include <unistd.h>
11 11
12int main() 12int main()
13{ 13{
14 Bu::ServerSocket sSrv( 9987 ); 14 Bu::TcpServerSocket sSrv( 9987 );
15 15
16 Bu::Socket sSend("localhost", 9987 ); 16 Bu::TcpSocket sSend("localhost", 9987 );
17 17
18 Bu::Socket sRecv( sSrv.accept() ); 18 Bu::TcpSocket sRecv( sSrv.accept() );
19 19
20 printf("Connected sockets.\n"); 20 printf("Connected sockets.\n");
21 21
diff --git a/src/tests/socket.cpp b/src/tests/tcpsocket.cpp
index ba4e9b9..30dd22f 100644
--- a/src/tests/socket.cpp
+++ b/src/tests/tcpsocket.cpp
@@ -5,7 +5,7 @@
5 * terms of the license contained in the file LICENSE. 5 * terms of the license contained in the file LICENSE.
6 */ 6 */
7 7
8#include <bu/socket.h> 8#include <bu/tcpsocket.h>
9#include <bu/sio.h> 9#include <bu/sio.h>
10 10
11#include <sys/time.h> 11#include <sys/time.h>
@@ -17,7 +17,7 @@ bool isUp()
17{ 17{
18 try 18 try
19 { 19 {
20 Socket s("xagasoft.com", 9898, 1 ); 20 TcpSocket s("xagasoft.com", 9898, 1 );
21 21
22 char buf[5]; 22 char buf[5];
23 buf[s.read(buf, 2, 1, 0)] = '\0'; 23 buf[s.read(buf, 2, 1, 0)] = '\0';
diff --git a/src/variant.h b/src/variant.h
index 5482ee3..9819f2c 100644
--- a/src/variant.h
+++ b/src/variant.h
@@ -17,6 +17,7 @@ namespace Bu
17{ 17{
18 class Formatter; 18 class Formatter;
19 class Variant; 19 class Variant;
20 /** @cond DEVEL */
20 template<class t> class VariantType; 21 template<class t> class VariantType;
21 22
22 class VariantTypeRoot 23 class VariantTypeRoot
@@ -92,7 +93,22 @@ namespace Bu
92 private: 93 private:
93 t data; 94 t data;
94 }; 95 };
95 96 /** @endcond */
97
98 /**
99 * Store any data type and access it safely. Variant gives you a way to
100 * pass arbitrary data types around without having to worry about what
101 * type a variable is. It allows code to be easily extended and to manage
102 * data without having to know what type it is ahead of time.
103 *
104 * Because of the generic method that this class was implemented it may seem
105 * to have some drawbacks compared to other Variant classes you may have
106 * seen, however it is fairly easy to get it to do just about anything you
107 * may need. It is also very low overhead. On most compilers the class
108 * itself has only 3 words of overhead + the size of the variable you store
109 * in it. And, since many parts of it are templatized they can often be
110 * optimized quite a bit.
111 */
96 class Variant 112 class Variant
97 { 113 {
98 public: 114 public: