summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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: