This commit is contained in:
David Rose
2007-02-08 23:44:25 +00:00
parent 46e3aa267c
commit f05b41cc96
13 changed files with 2584 additions and 2584 deletions

View File

@@ -1,3 +1,3 @@
#include "socket_base.h"
#include "socket_base.h"

View File

@@ -1,16 +1,16 @@
#ifndef __SOCKET_BASE_H__
#define __SOCKET_BASE_H__
////////////////////////////////////////////
// Quick way to get all the network code defined
////////////////////////////////////////////
#include "socket_portable.h"
#include "socket_address.h"
#include "socket_ip.h"
#include "socket_tcp.h"
#include "socket_tcp_listen.h"
#include "socket_udp_incoming.h"
#include "socket_udp_outgoing.h"
#include "socket_fdset.h"
#include "socket_selector.h"
#endif //__SOCKET_BASE_H__
#ifndef __SOCKET_BASE_H__
#define __SOCKET_BASE_H__
////////////////////////////////////////////
// Quick way to get all the network code defined
////////////////////////////////////////////
#include "socket_portable.h"
#include "socket_address.h"
#include "socket_ip.h"
#include "socket_tcp.h"
#include "socket_tcp_listen.h"
#include "socket_udp_incoming.h"
#include "socket_udp_outgoing.h"
#include "socket_fdset.h"
#include "socket_selector.h"
#endif //__SOCKET_BASE_H__

View File

@@ -1,202 +1,202 @@
#ifndef __SOCKET_FDSET_H__
#define __SOCKET_FDSET_H__
////////////////////////////////////////////////////
//
//rhh
// This class needs to be broken into 2 classes: the gathering class and the processing functions.
// The functions should be set up as template functions
//
// Add a helper class socket_select. May want to totally separate the select and collect functionality
// fits more with the normal Berkeley mind set... ** Not ** Should think about using POLL() on BSD-based systems
//
//////////////////////////////////////////////////////////
#include "time_base.h"
class Socket_fdset
{
public:
inline Socket_fdset();
inline void setForSocket(const Socket_IP &incon);
inline bool IsSetFor(const Socket_IP & incon) const;
inline int WaitForRead(bool zeroFds, UINT32 sleep_time = 0xffffffff);
inline int WaitForWrite(bool zeroFds, UINT32 sleep_time = 0xffffffff);
inline int WaitForError(bool zeroFds, UINT32 sleep_time = 0xffffffff);
inline int WaitForRead(bool zeroFds, const Time_Span & timeout);
inline void clear();
private:
inline void setForSocketNative(const SOCKET inid);
inline bool isSetForNative(const SOCKET inid) const;
friend struct Socket_Selector;
SOCKET _maxid;
fd_set _the_set;
};
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::Socket_fdset
// Description : The constructor
////////////////////////////////////////////////////////////////////
inline Socket_fdset::Socket_fdset()
{
clear();
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::setForSocketNative
// Description : This does the physical manipulation of the set getting read for the base call
////////////////////////////////////////////////////////////////////
inline void Socket_fdset::setForSocketNative(SOCKET inid)
{
assert( inid >= 0);
#ifndef WIN32
assert(inid < FD_SETSIZE);
#endif
FD_SET(inid, &_the_set);
if (_maxid < inid)
_maxid = inid;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::isSetForNative
// Description : Answer the question: was the socket marked for reading
// there's a subtle difference in the NSPR version: it will respond if
// the socket had an error
////////////////////////////////////////////////////////////////////
inline bool Socket_fdset::isSetForNative(SOCKET inid) const
{
assert( inid >= 0);
#ifndef WIN32
assert(inid < FD_SETSIZE);
#endif
return (FD_ISSET(inid, &_the_set) != 0);
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::IsSetFor
// Description : check to see if a socket object has been marked for reading
////////////////////////////////////////////////////////////////////
inline bool Socket_fdset::IsSetFor(const Socket_IP & incon) const
{
return isSetForNative(incon.GetSocket());
}
////////////////////////////////////////////////////////////////////
// Function name : WaitForRead
// Description :
////////////////////////////////////////////////////////////////////
inline int Socket_fdset::WaitForRead(bool zeroFds, UINT32 sleep_time)
{
int retVal = 0;
if (sleep_time == 0xffffffff)
{
retVal = DO_SELECT(_maxid + 1, &_the_set, NULL, NULL, NULL);
}
else
{
timeval timeoutValue;
timeoutValue.tv_sec = sleep_time / 1000;
timeoutValue.tv_usec = (sleep_time % 1000) * 1000;
retVal = DO_SELECT(_maxid + 1, &_the_set, NULL, NULL, &timeoutValue);
}
if (zeroFds)
clear();
return retVal;
}
//////////////////////////////////////////////////////////////
// Function name : Socket_fdset::WaitForRead
// Description :
//////////////////////////////////////////////////////////////
inline int Socket_fdset::WaitForRead(bool zeroFds, const Time_Span & timeout)
{
timeval localtv = timeout.GetTval();
int retVal = DO_SELECT(_maxid + 1, &_the_set, NULL, NULL, &localtv);
if (zeroFds)
clear();
return retVal;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::zeroOut
// Description : Marks the content as empty
////////////////////////////////////////////////////////////////////
inline void Socket_fdset::clear()
{
_maxid = 0;
FD_ZERO(&_the_set);
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::setForSocket
// Description :
////////////////////////////////////////////////////////////////////
inline void Socket_fdset::setForSocket(const Socket_IP &incon)
{
setForSocketNative(incon.GetSocket());
}
////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::WaitForWrite
// Description : This is the function that will wait till
// one of the sockets is ready for writing
////////////////////////////////////////////////////////////////////
inline int Socket_fdset::WaitForWrite(bool zeroFds, UINT32 sleep_time)
{
int retVal = 0;
if (sleep_time == 0xffffffff)
{
retVal = DO_SELECT(_maxid + 1, NULL, &_the_set, NULL, NULL);
}
else
{
timeval timeoutValue;
timeoutValue.tv_sec = sleep_time / 1000;
timeoutValue.tv_usec = (sleep_time % 1000) * 1000;
retVal = DO_SELECT(_maxid + 1, NULL, &_the_set, NULL, &timeoutValue);
}
if (zeroFds)
clear();
return retVal;
}
//////////////////////////////////////////////////////////////
// Function name : Socket_fdset::WaitForError
// Description : This is the function that will wait till
// one of the sockets is in error state
//////////////////////////////////////////////////////////////
inline int Socket_fdset::WaitForError(bool zeroFds, UINT32 sleep_time)
{
int retVal = 0;
if (sleep_time == 0xffffffff)
{
retVal = DO_SELECT(_maxid + 1, NULL, NULL, &_the_set, NULL);
}
else
{
timeval timeoutValue;
timeoutValue.tv_sec = sleep_time / 1000;
timeoutValue.tv_usec = (sleep_time % 1000) * 1000;
retVal = DO_SELECT(_maxid + 1, NULL, NULL, &_the_set, &timeoutValue);
}
if (zeroFds)
clear();
return retVal;
}
#endif //__SOCKET_FDSET_H__
#ifndef __SOCKET_FDSET_H__
#define __SOCKET_FDSET_H__
////////////////////////////////////////////////////
//
//rhh
// This class needs to be broken into 2 classes: the gathering class and the processing functions.
// The functions should be set up as template functions
//
// Add a helper class socket_select. May want to totally separate the select and collect functionality
// fits more with the normal Berkeley mind set... ** Not ** Should think about using POLL() on BSD-based systems
//
//////////////////////////////////////////////////////////
#include "time_base.h"
class Socket_fdset
{
public:
inline Socket_fdset();
inline void setForSocket(const Socket_IP &incon);
inline bool IsSetFor(const Socket_IP & incon) const;
inline int WaitForRead(bool zeroFds, UINT32 sleep_time = 0xffffffff);
inline int WaitForWrite(bool zeroFds, UINT32 sleep_time = 0xffffffff);
inline int WaitForError(bool zeroFds, UINT32 sleep_time = 0xffffffff);
inline int WaitForRead(bool zeroFds, const Time_Span & timeout);
inline void clear();
private:
inline void setForSocketNative(const SOCKET inid);
inline bool isSetForNative(const SOCKET inid) const;
friend struct Socket_Selector;
SOCKET _maxid;
fd_set _the_set;
};
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::Socket_fdset
// Description : The constructor
////////////////////////////////////////////////////////////////////
inline Socket_fdset::Socket_fdset()
{
clear();
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::setForSocketNative
// Description : This does the physical manipulation of the set getting read for the base call
////////////////////////////////////////////////////////////////////
inline void Socket_fdset::setForSocketNative(SOCKET inid)
{
assert( inid >= 0);
#ifndef WIN32
assert(inid < FD_SETSIZE);
#endif
FD_SET(inid, &_the_set);
if (_maxid < inid)
_maxid = inid;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::isSetForNative
// Description : Answer the question: was the socket marked for reading
// there's a subtle difference in the NSPR version: it will respond if
// the socket had an error
////////////////////////////////////////////////////////////////////
inline bool Socket_fdset::isSetForNative(SOCKET inid) const
{
assert( inid >= 0);
#ifndef WIN32
assert(inid < FD_SETSIZE);
#endif
return (FD_ISSET(inid, &_the_set) != 0);
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::IsSetFor
// Description : check to see if a socket object has been marked for reading
////////////////////////////////////////////////////////////////////
inline bool Socket_fdset::IsSetFor(const Socket_IP & incon) const
{
return isSetForNative(incon.GetSocket());
}
////////////////////////////////////////////////////////////////////
// Function name : WaitForRead
// Description :
////////////////////////////////////////////////////////////////////
inline int Socket_fdset::WaitForRead(bool zeroFds, UINT32 sleep_time)
{
int retVal = 0;
if (sleep_time == 0xffffffff)
{
retVal = DO_SELECT(_maxid + 1, &_the_set, NULL, NULL, NULL);
}
else
{
timeval timeoutValue;
timeoutValue.tv_sec = sleep_time / 1000;
timeoutValue.tv_usec = (sleep_time % 1000) * 1000;
retVal = DO_SELECT(_maxid + 1, &_the_set, NULL, NULL, &timeoutValue);
}
if (zeroFds)
clear();
return retVal;
}
//////////////////////////////////////////////////////////////
// Function name : Socket_fdset::WaitForRead
// Description :
//////////////////////////////////////////////////////////////
inline int Socket_fdset::WaitForRead(bool zeroFds, const Time_Span & timeout)
{
timeval localtv = timeout.GetTval();
int retVal = DO_SELECT(_maxid + 1, &_the_set, NULL, NULL, &localtv);
if (zeroFds)
clear();
return retVal;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::zeroOut
// Description : Marks the content as empty
////////////////////////////////////////////////////////////////////
inline void Socket_fdset::clear()
{
_maxid = 0;
FD_ZERO(&_the_set);
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::setForSocket
// Description :
////////////////////////////////////////////////////////////////////
inline void Socket_fdset::setForSocket(const Socket_IP &incon)
{
setForSocketNative(incon.GetSocket());
}
////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function name : Socket_fdset::WaitForWrite
// Description : This is the function that will wait till
// one of the sockets is ready for writing
////////////////////////////////////////////////////////////////////
inline int Socket_fdset::WaitForWrite(bool zeroFds, UINT32 sleep_time)
{
int retVal = 0;
if (sleep_time == 0xffffffff)
{
retVal = DO_SELECT(_maxid + 1, NULL, &_the_set, NULL, NULL);
}
else
{
timeval timeoutValue;
timeoutValue.tv_sec = sleep_time / 1000;
timeoutValue.tv_usec = (sleep_time % 1000) * 1000;
retVal = DO_SELECT(_maxid + 1, NULL, &_the_set, NULL, &timeoutValue);
}
if (zeroFds)
clear();
return retVal;
}
//////////////////////////////////////////////////////////////
// Function name : Socket_fdset::WaitForError
// Description : This is the function that will wait till
// one of the sockets is in error state
//////////////////////////////////////////////////////////////
inline int Socket_fdset::WaitForError(bool zeroFds, UINT32 sleep_time)
{
int retVal = 0;
if (sleep_time == 0xffffffff)
{
retVal = DO_SELECT(_maxid + 1, NULL, NULL, &_the_set, NULL);
}
else
{
timeval timeoutValue;
timeoutValue.tv_sec = sleep_time / 1000;
timeoutValue.tv_usec = (sleep_time % 1000) * 1000;
retVal = DO_SELECT(_maxid + 1, NULL, NULL, &_the_set, &timeoutValue);
}
if (zeroFds)
clear();
return retVal;
}
#endif //__SOCKET_FDSET_H__

View File

@@ -1,366 +1,366 @@
#ifndef __SOCKET_PORTABLE_H__
#define __SOCKET_PORTABLE_H__
//////////////////////////////////////////////////////////////////
// Lots of stuff to make network socket-based io transparent across multiple
// platforms
//////////////////////////////////////////////////////////////////
const int ALL_OK = 0;
const int BASIC_ERROR = -1;
/************************************************************************
* HP SOCKET LIBRARY STUFF
************************************************************************/
#if defined(HP_SOCK)
#ifndef _INCLUDE_HPUX_SOURCE
#define _INCLUDE_HPUX_SOURCE
#define _INCLUDE_POSIX_SOURCE
#define _INCLUDE_XOPEN_SOURCE
#endif
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#define socket_read read
#define socket_write write
#define socket_close close
#define DO_CONNECT(a,b,c) connect(a,b,c)
#define DO_SOCKET_READ(a,b,c,d) socket_read(a,b,c)
#define DO_SOCKET_WRITE(a,b,c,d) socket_write(a,b,c)
#define GETERROR() errno
#define SOCKIOCTL ioctl
typedef unsigned long SOCKET;
#define BAD_SOCKET 0xffffffff
/************************************************************************
* WINSOCK 32 bit STUFF
************************************************************************/
#elif defined(WIN32) || defined(WIN32_VC)
#include <winsock2.h>
#include <Ws2tcpip.h>
inline int DO_SELECT(SOCKET n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,struct timeval *timeout)
{
return select((int) n, readfds, writefds, exceptfds,timeout);
}
inline int DO_CONNECT( const SOCKET a, const struct sockaddr_in *b)
{
return connect(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_SOCKET_READ(const SOCKET a, char * buf, const int size)
{
return recv(a, buf, size, 0);
}
inline int DO_SOCKET_WRITE(const SOCKET a, const char * buff, const int len)
{
return send(a, buff, len, 0);
}
inline int DO_SOCKET_WRITE_TO(const SOCKET a, const char * buffer, const int buf_len, const sockaddr_in * addr)
{
return sendto(a, buffer, buf_len, 0, reinterpret_cast<const struct ::sockaddr *>(addr), sizeof(sockaddr));
}
inline SOCKET DO_NEWUDP()
{
return socket(AF_INET, SOCK_DGRAM, 0);
}
inline SOCKET DO_NEWTCP()
{
return socket(AF_INET, SOCK_STREAM, 0);
}
inline int DO_BIND(const SOCKET a, const sockaddr_in *b)
{
return bind(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_CLOSE(const SOCKET a)
{
return closesocket(a);
}
inline SOCKET DO_ACCEPT(SOCKET sck, sockaddr_in * adr)
{
int adrlen = sizeof(sockaddr);
return accept(sck, reinterpret_cast<sockaddr *>(adr), &adrlen);
};
inline int DO_RECV_FROM(SOCKET sck, char * data, int len, sockaddr_in * addr)
{
int plen = sizeof(sockaddr);
return recvfrom(sck, data, len, 0, reinterpret_cast<sockaddr *>(addr), &plen);
}
inline int DO_LISTEN(const SOCKET a, const int size)
{
return listen(a, size);
}
inline int GETERROR()
{
return WSAGetLastError();
}
inline int SOCKIOCTL(const SOCKET s, const long flags, unsigned long * val)
{
return ioctlsocket(s, flags, val);
}
inline int init_network()
{
static struct WSAData mydata;
int answer = WSAStartup(0x0101, &mydata);
if (answer != 0)
return BASIC_ERROR;
return ALL_OK;
}
inline bool do_shutdown_send(SOCKET s)
{
return (shutdown(s,SD_SEND) == 0);
};
typedef int socklen_t ;
const long LOCAL_NONBLOCK = 1;
const long LOCAL_FL_SET = FIONBIO ;
const int LOCAL_BLOCKING_ERROR = WSAEWOULDBLOCK;
const int LOCAL_CONNECT_BLOCKING = WSAEWOULDBLOCK;
const int LOCAL_NOTCONNECTED_ERROR = WSAENOTCONN;
const int LOCAL_TIMEOUT_ERROR = WSAETIMEDOUT;
const SOCKET BAD_SOCKET = 0xffffffff;
/************************************************************************
* Solaris 2.6 and Irix 6.4 STUFF
************************************************************************/
#elif defined(SunOS) || defined(SUNNEW) || defined(IRIX64)
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/filio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef int SOCKET;
const SOCKET BAD_SOCKET = 0xffffffff;
//#define DO_CONNECT(a,b) connect(a,(sockaddr *)b,sizeof(sockaddr))
//#define DO_SOCKET_READ(a,b,c) recv(a,b,c,0)
//#define DO_SOCKET_WRITE(a,b,c) send(a,b,c,0)
inline int DO_CONNECT(const SOCKET a, const sockaddr_in *b)
{
return connect(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_SOCKET_READ(const SOCKET a, char * buf, const int size)
{
return recv(a, buf, size, 0);
}
inline int DO_SOCKET_WRITE(const SOCKET a, const char * buff, const int len)
{
return send(a, buff, len, 0);
}
//#define DO_SOCKET_WRITE_TO(a,b,c,d) sendto(a,b,c,0,(sockaddr *)d,sizeof(sockaddr))
//#define DO_NEWUDP() socket(AF_INET, SOCK_DGRAM, 0)
//#define DO_NEWTCP() socket(AF_INET, SOCK_STREAM, 0)
//#define DO_BIND(a,b) bind(a,(sockaddr *)b,sizeof(sockaddr))
//#/define DO_CLOSE(a) close(a)
inline int DO_SOCKET_WRITE_TO(const SOCKET a, const char * buffer, const int buf_len, const sockaddr_in * addr)
{
return sendto(a, buffer, buf_len, 0, reinterpret_cast<const struct ::sockaddr *>(addr), sizeof(sockaddr));
}
inline SOCKET DO_NEWUDP()
{
return socket(AF_INET, SOCK_DGRAM, 0);
}
inline SOCKET DO_NEWTCP()
{
return socket(AF_INET, SOCK_STREAM, 0);
}
inline int DO_BIND(const SOCKET a, const sockaddr_in *b)
{
return bind(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_CLOSE(const SOCKET a)
{
return close(a);
}
inline int DO_ACCEPT(SOCKET sck, sockaddr_in * adr)
{
int adrlen = sizeof(sockaddr);
return accept(sck, ( sockaddr *)adr, &adrlen);
};
inline int DO_RECV_FROM(SOCKET sck, char * data, int len, sockaddr_in * addr)
{
int plen = sizeof(sockaddr);
return recvfrom(sck, data, len, 0, (sockaddr *)addr, &plen);
}
inline int DO_LISTEN(const SOCKET a, const int size)
{
return listen(a, size);
}
inline int GETERROR()
{
return errno;
}
inline int SOCKIOCTL(const SOCKET s, const long flags, void * val)
{
return ioctl(s, flags, val);
}
inline int init_network()
{
return ALL_OK;
}
#ifndef INADDR_NONE
const INADDR_NONE = -1;
#endif
const long LOCAL_NONBLOCK = 1;
const long LOCAL_FL_SET = FIONBIO ;
const int LOCAL_BLOCKING_ERROR = EAGAIN;
const int LOCAL_CONNECT_BLOCKING = EINPROGRESS;
/************************************************************************
* LINUX and FreeBSD STUFF
************************************************************************/
#elif defined(Linux) || defined(FreeBSD) ||defined(LINUX)
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <netinet/in_systm.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
typedef int SOCKET;
const SOCKET BAD_SOCKET = -1;
inline int DO_SELECT(SOCKET n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,struct timeval *timeout)
{
return select((int) n, readfds, writefds, exceptfds,timeout);
}
inline int DO_CONNECT(const SOCKET a, const sockaddr_in *b)
{
return connect(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_SOCKET_READ(const SOCKET a, char * buf, const int size)
{
return recv(a, buf, size, 0);
}
inline int DO_SOCKET_WRITE(const SOCKET a, const char * buff, const int len)
{
return send(a, buff, len, 0);
}
///////////////////////////////////////////////
inline int DO_SOCKET_WRITE_TO(const SOCKET a, const char * buffer, const int buf_len, const sockaddr_in * addr)
{
return sendto(a, buffer, buf_len, 0, reinterpret_cast<const struct ::sockaddr *>(addr), sizeof(sockaddr));
}
inline SOCKET DO_NEWUDP()
{
return socket(AF_INET, SOCK_DGRAM, 0);
}
inline SOCKET DO_NEWTCP()
{
return socket(AF_INET, SOCK_STREAM, 0);
}
inline int DO_BIND(const SOCKET a, const sockaddr_in *b)
{
return bind(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_CLOSE(const SOCKET a)
{
return close(a);
}
inline int DO_ACCEPT(SOCKET sck, sockaddr_in * adr)
{
unsigned int adrlen = sizeof(sockaddr);
return accept(sck, ( sockaddr *)adr, &adrlen);
};
inline int DO_RECV_FROM(SOCKET sck, char * data, int len, sockaddr_in * addr)
{
unsigned int plen = sizeof(sockaddr);
return recvfrom(sck, data, len, 0, (sockaddr *)addr, &plen);
}
inline int init_network()
{
signal(SIGPIPE, SIG_IGN); // hmm do i still need this ...
return ALL_OK;
}
inline int DO_LISTEN(const SOCKET a, const int size)
{
return listen(a, size);
}
inline int GETERROR()
{
return errno;
}
inline int SOCKIOCTL(const SOCKET s, const long flags, void * val)
{
return ioctl(s, flags, val);
}
inline bool do_shutdown_send(SOCKET s)
{
return (shutdown(s,SHUT_WR) == 0);
};
#define BSDBLOCK
const long LOCAL_NONBLOCK = 1;
const long LOCAL_FL_SET = FIONBIO ;
const int LOCAL_BLOCKING_ERROR = EAGAIN;
const int LOCAL_CONNECT_BLOCKING = EINPROGRESS;
#else
/************************************************************************
* NO DEFINITION => GIVE COMPILATION ERROR
************************************************************************/
No Host Type defined !!
#error Fatal
#endif
#endif //__SOCKET_PORTABLE_H__
#ifndef __SOCKET_PORTABLE_H__
#define __SOCKET_PORTABLE_H__
//////////////////////////////////////////////////////////////////
// Lots of stuff to make network socket-based io transparent across multiple
// platforms
//////////////////////////////////////////////////////////////////
const int ALL_OK = 0;
const int BASIC_ERROR = -1;
/************************************************************************
* HP SOCKET LIBRARY STUFF
************************************************************************/
#if defined(HP_SOCK)
#ifndef _INCLUDE_HPUX_SOURCE
#define _INCLUDE_HPUX_SOURCE
#define _INCLUDE_POSIX_SOURCE
#define _INCLUDE_XOPEN_SOURCE
#endif
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#define socket_read read
#define socket_write write
#define socket_close close
#define DO_CONNECT(a,b,c) connect(a,b,c)
#define DO_SOCKET_READ(a,b,c,d) socket_read(a,b,c)
#define DO_SOCKET_WRITE(a,b,c,d) socket_write(a,b,c)
#define GETERROR() errno
#define SOCKIOCTL ioctl
typedef unsigned long SOCKET;
#define BAD_SOCKET 0xffffffff
/************************************************************************
* WINSOCK 32 bit STUFF
************************************************************************/
#elif defined(WIN32) || defined(WIN32_VC)
#include <winsock2.h>
#include <Ws2tcpip.h>
inline int DO_SELECT(SOCKET n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,struct timeval *timeout)
{
return select((int) n, readfds, writefds, exceptfds,timeout);
}
inline int DO_CONNECT( const SOCKET a, const struct sockaddr_in *b)
{
return connect(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_SOCKET_READ(const SOCKET a, char * buf, const int size)
{
return recv(a, buf, size, 0);
}
inline int DO_SOCKET_WRITE(const SOCKET a, const char * buff, const int len)
{
return send(a, buff, len, 0);
}
inline int DO_SOCKET_WRITE_TO(const SOCKET a, const char * buffer, const int buf_len, const sockaddr_in * addr)
{
return sendto(a, buffer, buf_len, 0, reinterpret_cast<const struct ::sockaddr *>(addr), sizeof(sockaddr));
}
inline SOCKET DO_NEWUDP()
{
return socket(AF_INET, SOCK_DGRAM, 0);
}
inline SOCKET DO_NEWTCP()
{
return socket(AF_INET, SOCK_STREAM, 0);
}
inline int DO_BIND(const SOCKET a, const sockaddr_in *b)
{
return bind(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_CLOSE(const SOCKET a)
{
return closesocket(a);
}
inline SOCKET DO_ACCEPT(SOCKET sck, sockaddr_in * adr)
{
int adrlen = sizeof(sockaddr);
return accept(sck, reinterpret_cast<sockaddr *>(adr), &adrlen);
};
inline int DO_RECV_FROM(SOCKET sck, char * data, int len, sockaddr_in * addr)
{
int plen = sizeof(sockaddr);
return recvfrom(sck, data, len, 0, reinterpret_cast<sockaddr *>(addr), &plen);
}
inline int DO_LISTEN(const SOCKET a, const int size)
{
return listen(a, size);
}
inline int GETERROR()
{
return WSAGetLastError();
}
inline int SOCKIOCTL(const SOCKET s, const long flags, unsigned long * val)
{
return ioctlsocket(s, flags, val);
}
inline int init_network()
{
static struct WSAData mydata;
int answer = WSAStartup(0x0101, &mydata);
if (answer != 0)
return BASIC_ERROR;
return ALL_OK;
}
inline bool do_shutdown_send(SOCKET s)
{
return (shutdown(s,SD_SEND) == 0);
};
typedef int socklen_t ;
const long LOCAL_NONBLOCK = 1;
const long LOCAL_FL_SET = FIONBIO ;
const int LOCAL_BLOCKING_ERROR = WSAEWOULDBLOCK;
const int LOCAL_CONNECT_BLOCKING = WSAEWOULDBLOCK;
const int LOCAL_NOTCONNECTED_ERROR = WSAENOTCONN;
const int LOCAL_TIMEOUT_ERROR = WSAETIMEDOUT;
const SOCKET BAD_SOCKET = 0xffffffff;
/************************************************************************
* Solaris 2.6 and Irix 6.4 STUFF
************************************************************************/
#elif defined(SunOS) || defined(SUNNEW) || defined(IRIX64)
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/filio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef int SOCKET;
const SOCKET BAD_SOCKET = 0xffffffff;
//#define DO_CONNECT(a,b) connect(a,(sockaddr *)b,sizeof(sockaddr))
//#define DO_SOCKET_READ(a,b,c) recv(a,b,c,0)
//#define DO_SOCKET_WRITE(a,b,c) send(a,b,c,0)
inline int DO_CONNECT(const SOCKET a, const sockaddr_in *b)
{
return connect(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_SOCKET_READ(const SOCKET a, char * buf, const int size)
{
return recv(a, buf, size, 0);
}
inline int DO_SOCKET_WRITE(const SOCKET a, const char * buff, const int len)
{
return send(a, buff, len, 0);
}
//#define DO_SOCKET_WRITE_TO(a,b,c,d) sendto(a,b,c,0,(sockaddr *)d,sizeof(sockaddr))
//#define DO_NEWUDP() socket(AF_INET, SOCK_DGRAM, 0)
//#define DO_NEWTCP() socket(AF_INET, SOCK_STREAM, 0)
//#define DO_BIND(a,b) bind(a,(sockaddr *)b,sizeof(sockaddr))
//#/define DO_CLOSE(a) close(a)
inline int DO_SOCKET_WRITE_TO(const SOCKET a, const char * buffer, const int buf_len, const sockaddr_in * addr)
{
return sendto(a, buffer, buf_len, 0, reinterpret_cast<const struct ::sockaddr *>(addr), sizeof(sockaddr));
}
inline SOCKET DO_NEWUDP()
{
return socket(AF_INET, SOCK_DGRAM, 0);
}
inline SOCKET DO_NEWTCP()
{
return socket(AF_INET, SOCK_STREAM, 0);
}
inline int DO_BIND(const SOCKET a, const sockaddr_in *b)
{
return bind(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_CLOSE(const SOCKET a)
{
return close(a);
}
inline int DO_ACCEPT(SOCKET sck, sockaddr_in * adr)
{
int adrlen = sizeof(sockaddr);
return accept(sck, ( sockaddr *)adr, &adrlen);
};
inline int DO_RECV_FROM(SOCKET sck, char * data, int len, sockaddr_in * addr)
{
int plen = sizeof(sockaddr);
return recvfrom(sck, data, len, 0, (sockaddr *)addr, &plen);
}
inline int DO_LISTEN(const SOCKET a, const int size)
{
return listen(a, size);
}
inline int GETERROR()
{
return errno;
}
inline int SOCKIOCTL(const SOCKET s, const long flags, void * val)
{
return ioctl(s, flags, val);
}
inline int init_network()
{
return ALL_OK;
}
#ifndef INADDR_NONE
const INADDR_NONE = -1;
#endif
const long LOCAL_NONBLOCK = 1;
const long LOCAL_FL_SET = FIONBIO ;
const int LOCAL_BLOCKING_ERROR = EAGAIN;
const int LOCAL_CONNECT_BLOCKING = EINPROGRESS;
/************************************************************************
* LINUX and FreeBSD STUFF
************************************************************************/
#elif defined(Linux) || defined(FreeBSD) ||defined(LINUX)
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <netinet/in_systm.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
typedef int SOCKET;
const SOCKET BAD_SOCKET = -1;
inline int DO_SELECT(SOCKET n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,struct timeval *timeout)
{
return select((int) n, readfds, writefds, exceptfds,timeout);
}
inline int DO_CONNECT(const SOCKET a, const sockaddr_in *b)
{
return connect(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_SOCKET_READ(const SOCKET a, char * buf, const int size)
{
return recv(a, buf, size, 0);
}
inline int DO_SOCKET_WRITE(const SOCKET a, const char * buff, const int len)
{
return send(a, buff, len, 0);
}
///////////////////////////////////////////////
inline int DO_SOCKET_WRITE_TO(const SOCKET a, const char * buffer, const int buf_len, const sockaddr_in * addr)
{
return sendto(a, buffer, buf_len, 0, reinterpret_cast<const struct ::sockaddr *>(addr), sizeof(sockaddr));
}
inline SOCKET DO_NEWUDP()
{
return socket(AF_INET, SOCK_DGRAM, 0);
}
inline SOCKET DO_NEWTCP()
{
return socket(AF_INET, SOCK_STREAM, 0);
}
inline int DO_BIND(const SOCKET a, const sockaddr_in *b)
{
return bind(a, reinterpret_cast<const struct ::sockaddr *>(b), sizeof(sockaddr));
}
inline int DO_CLOSE(const SOCKET a)
{
return close(a);
}
inline int DO_ACCEPT(SOCKET sck, sockaddr_in * adr)
{
unsigned int adrlen = sizeof(sockaddr);
return accept(sck, ( sockaddr *)adr, &adrlen);
};
inline int DO_RECV_FROM(SOCKET sck, char * data, int len, sockaddr_in * addr)
{
unsigned int plen = sizeof(sockaddr);
return recvfrom(sck, data, len, 0, (sockaddr *)addr, &plen);
}
inline int init_network()
{
signal(SIGPIPE, SIG_IGN); // hmm do i still need this ...
return ALL_OK;
}
inline int DO_LISTEN(const SOCKET a, const int size)
{
return listen(a, size);
}
inline int GETERROR()
{
return errno;
}
inline int SOCKIOCTL(const SOCKET s, const long flags, void * val)
{
return ioctl(s, flags, val);
}
inline bool do_shutdown_send(SOCKET s)
{
return (shutdown(s,SHUT_WR) == 0);
};
#define BSDBLOCK
const long LOCAL_NONBLOCK = 1;
const long LOCAL_FL_SET = FIONBIO ;
const int LOCAL_BLOCKING_ERROR = EAGAIN;
const int LOCAL_CONNECT_BLOCKING = EINPROGRESS;
#else
/************************************************************************
* NO DEFINITION => GIVE COMPILATION ERROR
************************************************************************/
No Host Type defined !!
#error Fatal
#endif
#endif //__SOCKET_PORTABLE_H__

View File

@@ -1,88 +1,88 @@
#ifndef __SOCKET_SELECTOR_H__
#define __SOCKET_SELECTOR_H__
////////////////////////////////////////////////////
// This is a structure on purpose. only used as a helper class to save on typing
//
////////////////////////////////////////////////////
struct Socket_Selector
{
Socket_fdset _read;
Socket_fdset _write;
Socket_fdset _error;
int _answer;
Socket_Selector() : _answer( -1)
{
}
Socket_Selector(const Socket_fdset &fd) : _read(fd), _write(fd), _error(fd) , _answer( -1)
{
}
int WaitFor(const Time_Span &timeout);
int WaitFor_All(const Socket_fdset & fd, const Time_Span & timeout);
int WaitFor_Read_Error(const Socket_fdset & fd, const Time_Span & timeout);
int WaitFor_Write_Error(const Socket_fdset & fd, const Time_Span & timeout);
};
//////////////////////////////////////////////////////////////
// Function name : Socket_Selector::WaitFor
// Description : This function is the reason this call exists..
// It will wait for a read, write or error condition
// on a socket or it will time out
//////////////////////////////////////////////////////////////
inline int Socket_Selector::WaitFor(const Time_Span &timeout)
{
SOCKET local_max = 0;
if (local_max < _read._maxid)
local_max = _read._maxid;
if (local_max < _write._maxid)
local_max = _write._maxid;
if (local_max < _error._maxid)
local_max = _error._maxid;
timeval localtv = timeout.GetTval();
_answer = DO_SELECT(local_max + 1, &_read._the_set, &_write._the_set, &_error._the_set, &localtv);
return _answer;
}
//////////////////////////////////////////////////////////////
// Function name : Socket_Selector::WaitFor_All
// Description : Helper function to utilize the WaitFor function
//////////////////////////////////////////////////////////////
inline int Socket_Selector::WaitFor_All(const Socket_fdset & fd, const Time_Span & timeout)
{
_read = fd;
_write = fd;
_error = fd;
return WaitFor(timeout);
}
//////////////////////////////////////////////////////////////
// Function name : Socket_Selector::WaitFor_Read_Error
// Description : Helper function for WaitFor
// Only looks for readability and errors
//////////////////////////////////////////////////////////////
inline int Socket_Selector::WaitFor_Read_Error(const Socket_fdset & fd, const Time_Span & timeout)
{
_read = fd;
_write.clear();
_error = fd;
return WaitFor(timeout);
}
//////////////////////////////////////////////////////////////
// Function name : Socket_Selector::WaitFor_Write_Error
// Description : Helper function for WaitFor
// Only looks for writability and errors
//////////////////////////////////////////////////////////////
inline int Socket_Selector::WaitFor_Write_Error(const Socket_fdset & fd, const Time_Span & timeout)
{
_read.clear();
_write = fd;
_error = fd;
return WaitFor(timeout);
}
#endif //__SOCKET_SELECTOR_H__
#ifndef __SOCKET_SELECTOR_H__
#define __SOCKET_SELECTOR_H__
////////////////////////////////////////////////////
// This is a structure on purpose. only used as a helper class to save on typing
//
////////////////////////////////////////////////////
struct Socket_Selector
{
Socket_fdset _read;
Socket_fdset _write;
Socket_fdset _error;
int _answer;
Socket_Selector() : _answer( -1)
{
}
Socket_Selector(const Socket_fdset &fd) : _read(fd), _write(fd), _error(fd) , _answer( -1)
{
}
int WaitFor(const Time_Span &timeout);
int WaitFor_All(const Socket_fdset & fd, const Time_Span & timeout);
int WaitFor_Read_Error(const Socket_fdset & fd, const Time_Span & timeout);
int WaitFor_Write_Error(const Socket_fdset & fd, const Time_Span & timeout);
};
//////////////////////////////////////////////////////////////
// Function name : Socket_Selector::WaitFor
// Description : This function is the reason this call exists..
// It will wait for a read, write or error condition
// on a socket or it will time out
//////////////////////////////////////////////////////////////
inline int Socket_Selector::WaitFor(const Time_Span &timeout)
{
SOCKET local_max = 0;
if (local_max < _read._maxid)
local_max = _read._maxid;
if (local_max < _write._maxid)
local_max = _write._maxid;
if (local_max < _error._maxid)
local_max = _error._maxid;
timeval localtv = timeout.GetTval();
_answer = DO_SELECT(local_max + 1, &_read._the_set, &_write._the_set, &_error._the_set, &localtv);
return _answer;
}
//////////////////////////////////////////////////////////////
// Function name : Socket_Selector::WaitFor_All
// Description : Helper function to utilize the WaitFor function
//////////////////////////////////////////////////////////////
inline int Socket_Selector::WaitFor_All(const Socket_fdset & fd, const Time_Span & timeout)
{
_read = fd;
_write = fd;
_error = fd;
return WaitFor(timeout);
}
//////////////////////////////////////////////////////////////
// Function name : Socket_Selector::WaitFor_Read_Error
// Description : Helper function for WaitFor
// Only looks for readability and errors
//////////////////////////////////////////////////////////////
inline int Socket_Selector::WaitFor_Read_Error(const Socket_fdset & fd, const Time_Span & timeout)
{
_read = fd;
_write.clear();
_error = fd;
return WaitFor(timeout);
}
//////////////////////////////////////////////////////////////
// Function name : Socket_Selector::WaitFor_Write_Error
// Description : Helper function for WaitFor
// Only looks for writability and errors
//////////////////////////////////////////////////////////////
inline int Socket_Selector::WaitFor_Write_Error(const Socket_fdset & fd, const Time_Span & timeout)
{
_read.clear();
_write = fd;
_error = fd;
return WaitFor(timeout);
}
#endif //__SOCKET_SELECTOR_H__

View File

@@ -1,304 +1,304 @@
#ifndef __SOCKET_TCP_SSL_H__
#define __SOCKET_TCP_SSL_H__
/////////////////////////////////////////////////////////////////////
// Class : Socket_TCP
//
// Description : Base functionality for a TCP connected socket
// This class is pretty useless by itself but it does hide some of the
// platform differences from machine to machine
//
/////////////////////////////////////////////////////////////////////
#include <openssl/rsa.h> /* SSLeay stuff */
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
extern SSL_CTX *global_ssl_ctx;
struct SSlStartup
{
SSlStartup()
{
SSL_METHOD *meth;
SSLeay_add_ssl_algorithms();
//meth = SSLv23_server_method();
meth = SSLv23_method();
SSL_load_error_strings();
global_ssl_ctx = SSL_CTX_new (meth);
}
~SSlStartup()
{
SSL_CTX_free (global_ssl_ctx);
global_ssl_ctx = NULL;
}
bool isactive() { return global_ssl_ctx != NULL; };
};
class Socket_TCP_SSL : public Socket_IP
{
public:
inline Socket_TCP_SSL(SOCKET);
inline Socket_TCP_SSL() : _ssl(NULL) {}
virtual inline ~Socket_TCP_SSL()
{
CleanSslUp();
}
inline int SetNoDelay();
inline int SetLinger(int interval_seconds = 0);
inline int DontLinger();
inline int SetSendBufferSize(int insize);
inline bool ActiveOpen(const Socket_Address & theaddress);
inline int SendData(const char * data, int size);
inline int RecvData(char * data, int size);
inline bool ErrorIs_WouldBlocking(int err);
inline SSL * get_ssl() { return _ssl; };
inline void DetailErrorFormat(void);
private:
SSL* _ssl;
void CleanSslUp()
{
if(_ssl != NULL)
{
SSL_shutdown(_ssl);
SSL_free(_ssl);
_ssl = NULL;
}
}
};
//////////////////////////////////////////////////////////////
// Function name : Socket_TCP_SSL::Socket_TCP_SSL
// Description :
//////////////////////////////////////////////////////////////
// right know this will only work for a
// accepted ie a server socket ??
inline Socket_TCP_SSL::Socket_TCP_SSL(SOCKET sck) : ::Socket_IP(sck)
{
SetNonBlocking(); // maybe should be blocking?
_ssl = SSL_new (global_ssl_ctx);
if(_ssl == NULL)
return;
SSL_set_fd (_ssl,(int)GetSocket() );
int err = SSL_accept(_ssl);
ERR_clear_error();
// printf(" Ssl Accept = %d \n",err);
}
////////////////////////////////////////////////////////////////////
// Function name : SetNoDelay
// Description : Disable Nagle algorithm. Don't delay send to coalesce packets
////////////////////////////////////////////////////////////////////
inline int Socket_TCP_SSL::SetNoDelay()
{
int nodel = 1;
int ret1;
ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *) & nodel, sizeof(nodel));
if (ret1 != 0)
return BASIC_ERROR;
return ALL_OK;
}
////////////////////////////////////////////////////////////////////
// Function name : SetLinger
// Description : will control the behavior of SO_LINGER for a TCP socket
////////////////////////////////////////////////////////////////////
int Socket_TCP_SSL::SetLinger(int interval_seconds)
{
linger ll;
ll.l_linger = interval_seconds;
ll.l_onoff = 1;
int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
if (ret1 != 0)
return BASIC_ERROR;
return ALL_OK;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_TCP_SSL::DontLinger
// Description : Turn off the linger flag. The socket will quickly release
// buffered items and free up OS resources. You may lose
// a stream if you use this flag and do not negotiate the close
// at the application layer.
////////////////////////////////////////////////////////////////////
int Socket_TCP_SSL::DontLinger()
{
linger ll;
ll.l_linger = 0;
ll.l_onoff = 0;
int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
if (ret1 != 0)
return BASIC_ERROR;
return ALL_OK;
}
////////////////////////////////////////////////////////////////////
// Function name : SetSendBufferSize
// Description : Just like it sounds. Sets a buffered socket recv buffer size.
// This function does not refuse ranges outside hard-coded OS
// limits
////////////////////////////////////////////////////////////////////
int Socket_TCP_SSL::SetSendBufferSize(int insize)
{
if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_SNDBUF, (char *) &insize, sizeof(int)))
return BASIC_ERROR;
return ALL_OK;
}
////////////////////////////////////////////////////////////////////
// Function name : ActiveOpen
// Description : This function will try and set the socket up for active open to a specified
// address and port provided by the input parameter
////////////////////////////////////////////////////////////////////
bool Socket_TCP_SSL::ActiveOpen(const Socket_Address & theaddress)
{
_socket = DO_NEWTCP();
if (_socket == BAD_SOCKET)
return false;
if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0)
return ErrorClose();
_ssl = SSL_new (global_ssl_ctx);
if(_ssl == NULL)
return false;
SSL_set_fd (_ssl,(int)GetSocket() );
if(SSL_connect(_ssl) == -1)
return false;
return true;
//return SetSslUp();
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_TCP_SSL::SendData
// Description : Ok Lets Send the Data
//
// Return type : int
// - if error
// 0 if socket closed for write or lengh is 0
// + bytes writen ( May be smaller than requested)
////////////////////////////////////////////////////////////////////
inline int Socket_TCP_SSL::SendData(const char * data, int size)
{
if(_ssl == NULL)
return -1;
// ERR_clear_error();
return SSL_write(_ssl, data, size);
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_TCP_SSL::RecvData
// Description : Read the data from the connection
//
// Return type : int
// - if error
// 0 if socket closed for read or length is 0
// + bytes read ( May be smaller than requested)
////////////////////////////////////////////////////////////////////
inline int Socket_TCP_SSL::RecvData(char * data, int len)
{
if(_ssl == NULL)
return -1;
ERR_clear_error();
return SSL_read(_ssl, data, len);
}
////////////////////////////////////////////////////////////////////
// Function name : ErrorIs_WouldBlocking
// Description : Is last error a blocking error ??
//
// Return type : Bool
// True is last error was a blocking error
////////////////////////////////////////////////////////////////////
inline bool Socket_TCP_SSL::ErrorIs_WouldBlocking(int err)
{
if(_ssl == NULL || err >= 0)
{
LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking->Called With Error numebr %d or _ssl is NULL",err);
return false;
}
int ssl_error_code = SSL_get_error(_ssl,err);
bool answer = false;
switch(ssl_error_code)
{
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_CONNECT:
// case SSL_ERROR_WANT_ACCEPT:
answer = true;
break;
// hmm not sure we need this .. hmmmm
case SSL_ERROR_SYSCALL:
if(GETERROR() == LOCAL_BLOCKING_ERROR)
answer = true;
else
{
DetailErrorFormat();
// LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking-> Not A blocking Error1 SSl_CODe=[%d] OS=[%d]",ssl_error_code,GETERROR());
}
break;
default:
DetailErrorFormat();
// LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking-> Not A blocking Error2 SSl_CODe=[%d] OS=[%d]",ssl_error_code,GETERROR());
answer = false;
break;
}
// ERR_clear_error();
return answer;
}
inline void Socket_TCP_SSL::DetailErrorFormat(void)
{
return; // turn on fir debuging
UINT32 l;
char buf[256];
char buf2[4096];
const char *file,*data;
int line,flags;
UINT32 es;
es=CRYPTO_thread_id();
while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
{
ERR_error_string_n(l, buf, sizeof( buf) );
BIO_snprintf(buf2, sizeof(buf2), "***%lu:%s:%s:%d:%s\n", es, buf,file, line, (flags & ERR_TXT_STRING) ? data : "NoText");
LOGWARNING("Socket_TCP_SSL::DetailErrorFormat->[%s]",buf2);
}
}
#endif //__SOCKET_TCP_SSL_H__
#ifndef __SOCKET_TCP_SSL_H__
#define __SOCKET_TCP_SSL_H__
/////////////////////////////////////////////////////////////////////
// Class : Socket_TCP
//
// Description : Base functionality for a TCP connected socket
// This class is pretty useless by itself but it does hide some of the
// platform differences from machine to machine
//
/////////////////////////////////////////////////////////////////////
#include <openssl/rsa.h> /* SSLeay stuff */
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
extern SSL_CTX *global_ssl_ctx;
struct SSlStartup
{
SSlStartup()
{
SSL_METHOD *meth;
SSLeay_add_ssl_algorithms();
//meth = SSLv23_server_method();
meth = SSLv23_method();
SSL_load_error_strings();
global_ssl_ctx = SSL_CTX_new (meth);
}
~SSlStartup()
{
SSL_CTX_free (global_ssl_ctx);
global_ssl_ctx = NULL;
}
bool isactive() { return global_ssl_ctx != NULL; };
};
class Socket_TCP_SSL : public Socket_IP
{
public:
inline Socket_TCP_SSL(SOCKET);
inline Socket_TCP_SSL() : _ssl(NULL) {}
virtual inline ~Socket_TCP_SSL()
{
CleanSslUp();
}
inline int SetNoDelay();
inline int SetLinger(int interval_seconds = 0);
inline int DontLinger();
inline int SetSendBufferSize(int insize);
inline bool ActiveOpen(const Socket_Address & theaddress);
inline int SendData(const char * data, int size);
inline int RecvData(char * data, int size);
inline bool ErrorIs_WouldBlocking(int err);
inline SSL * get_ssl() { return _ssl; };
inline void DetailErrorFormat(void);
private:
SSL* _ssl;
void CleanSslUp()
{
if(_ssl != NULL)
{
SSL_shutdown(_ssl);
SSL_free(_ssl);
_ssl = NULL;
}
}
};
//////////////////////////////////////////////////////////////
// Function name : Socket_TCP_SSL::Socket_TCP_SSL
// Description :
//////////////////////////////////////////////////////////////
// right know this will only work for a
// accepted ie a server socket ??
inline Socket_TCP_SSL::Socket_TCP_SSL(SOCKET sck) : ::Socket_IP(sck)
{
SetNonBlocking(); // maybe should be blocking?
_ssl = SSL_new (global_ssl_ctx);
if(_ssl == NULL)
return;
SSL_set_fd (_ssl,(int)GetSocket() );
int err = SSL_accept(_ssl);
ERR_clear_error();
// printf(" Ssl Accept = %d \n",err);
}
////////////////////////////////////////////////////////////////////
// Function name : SetNoDelay
// Description : Disable Nagle algorithm. Don't delay send to coalesce packets
////////////////////////////////////////////////////////////////////
inline int Socket_TCP_SSL::SetNoDelay()
{
int nodel = 1;
int ret1;
ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *) & nodel, sizeof(nodel));
if (ret1 != 0)
return BASIC_ERROR;
return ALL_OK;
}
////////////////////////////////////////////////////////////////////
// Function name : SetLinger
// Description : will control the behavior of SO_LINGER for a TCP socket
////////////////////////////////////////////////////////////////////
int Socket_TCP_SSL::SetLinger(int interval_seconds)
{
linger ll;
ll.l_linger = interval_seconds;
ll.l_onoff = 1;
int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
if (ret1 != 0)
return BASIC_ERROR;
return ALL_OK;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_TCP_SSL::DontLinger
// Description : Turn off the linger flag. The socket will quickly release
// buffered items and free up OS resources. You may lose
// a stream if you use this flag and do not negotiate the close
// at the application layer.
////////////////////////////////////////////////////////////////////
int Socket_TCP_SSL::DontLinger()
{
linger ll;
ll.l_linger = 0;
ll.l_onoff = 0;
int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *) & ll, sizeof(linger));
if (ret1 != 0)
return BASIC_ERROR;
return ALL_OK;
}
////////////////////////////////////////////////////////////////////
// Function name : SetSendBufferSize
// Description : Just like it sounds. Sets a buffered socket recv buffer size.
// This function does not refuse ranges outside hard-coded OS
// limits
////////////////////////////////////////////////////////////////////
int Socket_TCP_SSL::SetSendBufferSize(int insize)
{
if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_SNDBUF, (char *) &insize, sizeof(int)))
return BASIC_ERROR;
return ALL_OK;
}
////////////////////////////////////////////////////////////////////
// Function name : ActiveOpen
// Description : This function will try and set the socket up for active open to a specified
// address and port provided by the input parameter
////////////////////////////////////////////////////////////////////
bool Socket_TCP_SSL::ActiveOpen(const Socket_Address & theaddress)
{
_socket = DO_NEWTCP();
if (_socket == BAD_SOCKET)
return false;
if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0)
return ErrorClose();
_ssl = SSL_new (global_ssl_ctx);
if(_ssl == NULL)
return false;
SSL_set_fd (_ssl,(int)GetSocket() );
if(SSL_connect(_ssl) == -1)
return false;
return true;
//return SetSslUp();
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_TCP_SSL::SendData
// Description : Ok Lets Send the Data
//
// Return type : int
// - if error
// 0 if socket closed for write or lengh is 0
// + bytes writen ( May be smaller than requested)
////////////////////////////////////////////////////////////////////
inline int Socket_TCP_SSL::SendData(const char * data, int size)
{
if(_ssl == NULL)
return -1;
// ERR_clear_error();
return SSL_write(_ssl, data, size);
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_TCP_SSL::RecvData
// Description : Read the data from the connection
//
// Return type : int
// - if error
// 0 if socket closed for read or length is 0
// + bytes read ( May be smaller than requested)
////////////////////////////////////////////////////////////////////
inline int Socket_TCP_SSL::RecvData(char * data, int len)
{
if(_ssl == NULL)
return -1;
ERR_clear_error();
return SSL_read(_ssl, data, len);
}
////////////////////////////////////////////////////////////////////
// Function name : ErrorIs_WouldBlocking
// Description : Is last error a blocking error ??
//
// Return type : Bool
// True is last error was a blocking error
////////////////////////////////////////////////////////////////////
inline bool Socket_TCP_SSL::ErrorIs_WouldBlocking(int err)
{
if(_ssl == NULL || err >= 0)
{
LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking->Called With Error numebr %d or _ssl is NULL",err);
return false;
}
int ssl_error_code = SSL_get_error(_ssl,err);
bool answer = false;
switch(ssl_error_code)
{
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_CONNECT:
// case SSL_ERROR_WANT_ACCEPT:
answer = true;
break;
// hmm not sure we need this .. hmmmm
case SSL_ERROR_SYSCALL:
if(GETERROR() == LOCAL_BLOCKING_ERROR)
answer = true;
else
{
DetailErrorFormat();
// LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking-> Not A blocking Error1 SSl_CODe=[%d] OS=[%d]",ssl_error_code,GETERROR());
}
break;
default:
DetailErrorFormat();
// LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking-> Not A blocking Error2 SSl_CODe=[%d] OS=[%d]",ssl_error_code,GETERROR());
answer = false;
break;
}
// ERR_clear_error();
return answer;
}
inline void Socket_TCP_SSL::DetailErrorFormat(void)
{
return; // turn on fir debuging
UINT32 l;
char buf[256];
char buf2[4096];
const char *file,*data;
int line,flags;
UINT32 es;
es=CRYPTO_thread_id();
while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
{
ERR_error_string_n(l, buf, sizeof( buf) );
BIO_snprintf(buf2, sizeof(buf2), "***%lu:%s:%s:%d:%s\n", es, buf,file, line, (flags & ERR_TXT_STRING) ? data : "NoText");
LOGWARNING("Socket_TCP_SSL::DetailErrorFormat->[%s]",buf2);
}
}
#endif //__SOCKET_TCP_SSL_H__

View File

@@ -1,146 +1,146 @@
#ifndef __SOCKET_UDP_INCOMING_H__
#define __SOCKET_UDP_INCOMING_H__
/////////////////////////////////////////////////////////////////////
// Class : Socket_UDP_Incoming
//
// Description : Base functionality for a UDP Reader
//
//
/////////////////////////////////////////////////////////////////////
class Socket_UDP_Incoming : public Socket_IP
{
public:
PUBLISHED:
inline bool OpenForInput(Socket_Address & address);
inline bool OpenForInputMCast(Socket_Address & address );
inline bool GetPacket(char * data, int *max_len, Socket_Address & address);
inline bool SendTo(const char * data, int len, const Socket_Address & address);
inline bool InitNoAddress();
inline bool SetToBroadCast();
};
//////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::tToBroadCast
// Description : Flips the OS bits that allow for brodcast
// packets to com in on this port
//
// Return type : bool
// Argument : void
//////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::SetToBroadCast()
{
int optval = 1;
if (setsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0)
return false;
return true;
}
//////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::InitNoAddress
// Description : Set this socket to work with out a bound external address..
// Return type : inline bool
// Argument : void
//////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::InitNoAddress()
{
Close();
_socket = DO_NEWUDP();
if (_socket == BAD_SOCKET)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::OpenForInput
// Description : Starts a UDP socket listening on a port
//
// Return type : bool
// Argument : NetAddress & address
////////////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::OpenForInput(Socket_Address & address)
{
Close();
_socket = DO_NEWUDP();
if (_socket == BAD_SOCKET)
return ErrorClose();
if (DO_BIND(_socket, &address.GetAddressInfo()) != 0)
return ErrorClose();
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::OpenForInput
// Description : Starts a UDP socket listening on a port
//
// Return type : bool
// Argument : NetAddress & address
////////////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::OpenForInputMCast(Socket_Address & address)
{
Close();
_socket = DO_NEWUDP();
if (_socket == BAD_SOCKET)
return ErrorClose();
Socket_Address wa1(address.get_port());
if (DO_BIND(_socket, &wa1.GetAddressInfo()) != 0)
return ErrorClose();
struct ip_mreq imreq;
memset(&imreq,0,sizeof(imreq));
imreq.imr_multiaddr.s_addr = address.GetAddressInfo().sin_addr.s_addr;
imreq.imr_interface.s_addr = INADDR_ANY; // use DEFAULT interface
int status = setsockopt(GetSocket(), IPPROTO_IP, IP_ADD_MEMBERSHIP,
(const char *)&imreq, sizeof(struct ip_mreq));
if(status != 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::GetPacket
// Description : Grabs a dataset off the listening UDP socket
// and fills in the source address information
//
// Return type : bool
// Argument : char * data
// Argument : int *max_len
// Argument : NetAddress & address
////////////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::GetPacket(char * data, int *max_len, Socket_Address & address)
{
int val = DO_RECV_FROM(_socket, data, *max_len, &address.GetAddressInfo());
*max_len = 0;
if (val <= 0)
{
if (GetLastError() != LOCAL_BLOCKING_ERROR) // im treating a blocking error as a 0 lenght read
return false;
} else
*max_len = val;
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : SocketUDP_Outgoing::SendTo
// Description : Send data to specified address
//
// Return type : inline bool
// Argument : char * data
// Argument : int len
// Argument : NetAddress & address
////////////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::SendTo(const char * data, int len, const Socket_Address & address)
{
return (DO_SOCKET_WRITE_TO(_socket, data, len, &address.GetAddressInfo()) == len);
}
#endif //__SOCKET_UDP_INCOMING_H__
#ifndef __SOCKET_UDP_INCOMING_H__
#define __SOCKET_UDP_INCOMING_H__
/////////////////////////////////////////////////////////////////////
// Class : Socket_UDP_Incoming
//
// Description : Base functionality for a UDP Reader
//
//
/////////////////////////////////////////////////////////////////////
class Socket_UDP_Incoming : public Socket_IP
{
public:
PUBLISHED:
inline bool OpenForInput(Socket_Address & address);
inline bool OpenForInputMCast(Socket_Address & address );
inline bool GetPacket(char * data, int *max_len, Socket_Address & address);
inline bool SendTo(const char * data, int len, const Socket_Address & address);
inline bool InitNoAddress();
inline bool SetToBroadCast();
};
//////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::tToBroadCast
// Description : Flips the OS bits that allow for brodcast
// packets to com in on this port
//
// Return type : bool
// Argument : void
//////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::SetToBroadCast()
{
int optval = 1;
if (setsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0)
return false;
return true;
}
//////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::InitNoAddress
// Description : Set this socket to work with out a bound external address..
// Return type : inline bool
// Argument : void
//////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::InitNoAddress()
{
Close();
_socket = DO_NEWUDP();
if (_socket == BAD_SOCKET)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::OpenForInput
// Description : Starts a UDP socket listening on a port
//
// Return type : bool
// Argument : NetAddress & address
////////////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::OpenForInput(Socket_Address & address)
{
Close();
_socket = DO_NEWUDP();
if (_socket == BAD_SOCKET)
return ErrorClose();
if (DO_BIND(_socket, &address.GetAddressInfo()) != 0)
return ErrorClose();
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::OpenForInput
// Description : Starts a UDP socket listening on a port
//
// Return type : bool
// Argument : NetAddress & address
////////////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::OpenForInputMCast(Socket_Address & address)
{
Close();
_socket = DO_NEWUDP();
if (_socket == BAD_SOCKET)
return ErrorClose();
Socket_Address wa1(address.get_port());
if (DO_BIND(_socket, &wa1.GetAddressInfo()) != 0)
return ErrorClose();
struct ip_mreq imreq;
memset(&imreq,0,sizeof(imreq));
imreq.imr_multiaddr.s_addr = address.GetAddressInfo().sin_addr.s_addr;
imreq.imr_interface.s_addr = INADDR_ANY; // use DEFAULT interface
int status = setsockopt(GetSocket(), IPPROTO_IP, IP_ADD_MEMBERSHIP,
(const char *)&imreq, sizeof(struct ip_mreq));
if(status != 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_UDP_Incoming::GetPacket
// Description : Grabs a dataset off the listening UDP socket
// and fills in the source address information
//
// Return type : bool
// Argument : char * data
// Argument : int *max_len
// Argument : NetAddress & address
////////////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::GetPacket(char * data, int *max_len, Socket_Address & address)
{
int val = DO_RECV_FROM(_socket, data, *max_len, &address.GetAddressInfo());
*max_len = 0;
if (val <= 0)
{
if (GetLastError() != LOCAL_BLOCKING_ERROR) // im treating a blocking error as a 0 lenght read
return false;
} else
*max_len = val;
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : SocketUDP_Outgoing::SendTo
// Description : Send data to specified address
//
// Return type : inline bool
// Argument : char * data
// Argument : int len
// Argument : NetAddress & address
////////////////////////////////////////////////////////////////////
inline bool Socket_UDP_Incoming::SendTo(const char * data, int len, const Socket_Address & address)
{
return (DO_SOCKET_WRITE_TO(_socket, data, len, &address.GetAddressInfo()) == len);
}
#endif //__SOCKET_UDP_INCOMING_H__

View File

@@ -1,113 +1,113 @@
#ifndef __TIME_ACCUMULATOR_H__
#define __TIME_ACCUMULATOR_H__
///////////////////////////////////////////
//
// Think of this as a stopwatch that can be restarted.
//
///////////////////////////////////////////
class Time_Accumulator
{
public:
Time_Accumulator();
~Time_Accumulator();
void Start();
void Stop();
void Reset();
void Set(const Time_Span & in);
Time_Span Report();
private:
Time_Span _total_time; // the collected time from previous start/stops
Time_Clock *_accum_start; // the time of day the clock started
};
//////////////////////////////////////////////////////////
// you can set the internal accumilator to a value..
////////////////////////////////////////////////////////
inline void Time_Accumulator::Set(const Time_Span & in)
{
_total_time = in;
//
// this seems to make the most since ..
// if you are running the clock right know... assume the timespane you
// are passing in is inclusive.. but keep clock running..
//
// May need to rethink this...
//
if(_accum_start != NULL)
{
Stop();
Start();
}
}
//////////////////////////////////////////////////////////////
// Function name : Time_Accumulator::Time_Accumulator
// Description :
//////////////////////////////////////////////////////////////
inline Time_Accumulator::Time_Accumulator() : _total_time(0,0,0,0,0), _accum_start(NULL)
{
}
//////////////////////////////////////////////////////////////
// Function name : Time_Accumulator::~Time_Accumulator
// Description :
//////////////////////////////////////////////////////////////
inline Time_Accumulator::~Time_Accumulator()
{
if(_accum_start != NULL)
delete _accum_start;
}
//////////////////////////////////////////////////////////////
// Function name : void Time_Accumulator::Start
// Description :
//////////////////////////////////////////////////////////////
inline void Time_Accumulator::Start()
{
if(_accum_start == NULL)
_accum_start = new Time_Clock();
}
//////////////////////////////////////////////////////////////
// Function name : void Time_Accumulator::Stop
// Description :
//////////////////////////////////////////////////////////////
inline void Time_Accumulator::Stop()
{
if(_accum_start != NULL)
{
Time_Span work1(Time_Clock::GetCurrentTime() - *_accum_start);
_total_time += work1;
delete _accum_start;
_accum_start = NULL;
}
}
//////////////////////////////////////////////////////////////
// Function name : Time_Accumulator::Reset
// Description :
//////////////////////////////////////////////////////////////
void Time_Accumulator::Reset()
{
if(_accum_start != NULL)
{
delete _accum_start;
_accum_start = NULL;
}
_total_time.Set(0,0,0,0,0);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Accumulator::Report
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span Time_Accumulator::Report()
{
Time_Span answer(_total_time);
if(_accum_start != NULL)
{
Time_Span ww(Time_Clock::GetCurrentTime() - *_accum_start);
answer += ww;
}
return answer;
}
#endif //__TIME_ACCUMULATOR_H__
#ifndef __TIME_ACCUMULATOR_H__
#define __TIME_ACCUMULATOR_H__
///////////////////////////////////////////
//
// Think of this as a stopwatch that can be restarted.
//
///////////////////////////////////////////
class Time_Accumulator
{
public:
Time_Accumulator();
~Time_Accumulator();
void Start();
void Stop();
void Reset();
void Set(const Time_Span & in);
Time_Span Report();
private:
Time_Span _total_time; // the collected time from previous start/stops
Time_Clock *_accum_start; // the time of day the clock started
};
//////////////////////////////////////////////////////////
// you can set the internal accumilator to a value..
////////////////////////////////////////////////////////
inline void Time_Accumulator::Set(const Time_Span & in)
{
_total_time = in;
//
// this seems to make the most since ..
// if you are running the clock right know... assume the timespane you
// are passing in is inclusive.. but keep clock running..
//
// May need to rethink this...
//
if(_accum_start != NULL)
{
Stop();
Start();
}
}
//////////////////////////////////////////////////////////////
// Function name : Time_Accumulator::Time_Accumulator
// Description :
//////////////////////////////////////////////////////////////
inline Time_Accumulator::Time_Accumulator() : _total_time(0,0,0,0,0), _accum_start(NULL)
{
}
//////////////////////////////////////////////////////////////
// Function name : Time_Accumulator::~Time_Accumulator
// Description :
//////////////////////////////////////////////////////////////
inline Time_Accumulator::~Time_Accumulator()
{
if(_accum_start != NULL)
delete _accum_start;
}
//////////////////////////////////////////////////////////////
// Function name : void Time_Accumulator::Start
// Description :
//////////////////////////////////////////////////////////////
inline void Time_Accumulator::Start()
{
if(_accum_start == NULL)
_accum_start = new Time_Clock();
}
//////////////////////////////////////////////////////////////
// Function name : void Time_Accumulator::Stop
// Description :
//////////////////////////////////////////////////////////////
inline void Time_Accumulator::Stop()
{
if(_accum_start != NULL)
{
Time_Span work1(Time_Clock::GetCurrentTime() - *_accum_start);
_total_time += work1;
delete _accum_start;
_accum_start = NULL;
}
}
//////////////////////////////////////////////////////////////
// Function name : Time_Accumulator::Reset
// Description :
//////////////////////////////////////////////////////////////
void Time_Accumulator::Reset()
{
if(_accum_start != NULL)
{
delete _accum_start;
_accum_start = NULL;
}
_total_time.Set(0,0,0,0,0);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Accumulator::Report
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span Time_Accumulator::Report()
{
Time_Span answer(_total_time);
if(_accum_start != NULL)
{
Time_Span ww(Time_Clock::GetCurrentTime() - *_accum_start);
answer += ww;
}
return answer;
}
#endif //__TIME_ACCUMULATOR_H__

View File

@@ -1,117 +1,117 @@
#ifndef __TIME_BASE_H__
#define __TIME_BASE_H__
/////////////////////////////////////////////////////////////////////
// Functions To support General Time Managment. And to allow for cross platform use.
//
//
// Today Really Two Base classes and one convience class
//
// Time_Clock = The clock time down to micro seconds..
//
// Time_Span = Delta Time to the Mico Second..
//
// Time_Out = Help timer ............count down a duration.
//
// I realize TimeClock is really an implied delta to EPOCH. I have chosen to implement it this way.
// it may be apropriate to convert it all to delta times with an EPOCk constant and
// functions that can handle the EPOCK to current time.
// All though this is probably the "right" implementation most coders do not
// think of clock time in this fashon.
//
//
// General Observation..
//
// Windows 2k and Linux are really slow (~250k a sec) at returning the current system time ??
// So use time functions that grab the current system time sparingly ??
//
////////////////////////////////////////////////////////////////////////////////
#ifdef WIN32
#include <winsock2.h>
#include <wtypes.h>
#include <sys/types.h>
#include <sys/timeb.h>
#else
#include <sys/time.h>
#endif
#include <time.h>
#include <string>
#include <assert.h>
enum { USEC = 1000000 };
//////////////////////////////////////////////////////////////
// Function name : NormalizeTime
// Description :
// Return type : inline void
// Argument : timeval &in
//////////////////////////////////////////////////////////////
inline void NormalizeTime(timeval &in)
{
while (in.tv_usec >= USEC)
{
in.tv_usec -= USEC;
in.tv_sec++;
}
while (in.tv_usec < 0)
{
in.tv_usec += USEC;
in.tv_sec--;
}
}
//////////////////////////////////////////////////////////////
// Function name : TimeDif
// Description :
// Return type : inline void
// Argument : const struct timeval &start
// Argument : const struct timeval &fin
// Argument : struct timeval &answer
//////////////////////////////////////////////////////////////
inline void TimeDif(const struct timeval &start, const struct timeval &fin, struct timeval &answer)
{
answer.tv_usec = fin.tv_usec - start.tv_usec;
answer.tv_sec = fin.tv_sec - start.tv_sec;
NormalizeTime(answer);
}
//////////////////////////////////////////////////////////////
// Function name : TimeAdd
// Description :
// Return type : inline void
// Argument : const struct timeval &start
// Argument : const struct timeval &delta
// Argument : struct timeval &answer
//////////////////////////////////////////////////////////////
inline void TimeAdd(const struct timeval &start, const struct timeval &delta, struct timeval &answer)
{
answer.tv_usec = start.tv_usec + delta.tv_usec;
answer.tv_sec = start.tv_sec + delta.tv_sec;
NormalizeTime(answer);
}
#ifdef WIN32
////////////////////////////////////////////////////////////////
//
// Lets make Windows think it is a unix machine :)
//
//////////////////////////////////////////////////////////////
// Function name : gettimeofday
// Description :
// Return type : inline int
// Argument : struct timeval *tv
// Argument : void * trash
//////////////////////////////////////////////////////////////
inline int gettimeofday(struct timeval *tv, void * trash)
{
struct timeb timeb;
ftime( &timeb);
tv->tv_sec = (long)timeb.time;
tv->tv_usec = (unsigned int)timeb.millitm * 1000;
return 0;
}
#endif
#include "time_clock.h"
#include "time_span.h"
#include "time_general.h"
#include "time_out.h"
#endif //__TIME_BASE_H__
#ifndef __TIME_BASE_H__
#define __TIME_BASE_H__
/////////////////////////////////////////////////////////////////////
// Functions To support General Time Managment. And to allow for cross platform use.
//
//
// Today Really Two Base classes and one convience class
//
// Time_Clock = The clock time down to micro seconds..
//
// Time_Span = Delta Time to the Mico Second..
//
// Time_Out = Help timer ............count down a duration.
//
// I realize TimeClock is really an implied delta to EPOCH. I have chosen to implement it this way.
// it may be apropriate to convert it all to delta times with an EPOCk constant and
// functions that can handle the EPOCK to current time.
// All though this is probably the "right" implementation most coders do not
// think of clock time in this fashon.
//
//
// General Observation..
//
// Windows 2k and Linux are really slow (~250k a sec) at returning the current system time ??
// So use time functions that grab the current system time sparingly ??
//
////////////////////////////////////////////////////////////////////////////////
#ifdef WIN32
#include <winsock2.h>
#include <wtypes.h>
#include <sys/types.h>
#include <sys/timeb.h>
#else
#include <sys/time.h>
#endif
#include <time.h>
#include <string>
#include <assert.h>
enum { USEC = 1000000 };
//////////////////////////////////////////////////////////////
// Function name : NormalizeTime
// Description :
// Return type : inline void
// Argument : timeval &in
//////////////////////////////////////////////////////////////
inline void NormalizeTime(timeval &in)
{
while (in.tv_usec >= USEC)
{
in.tv_usec -= USEC;
in.tv_sec++;
}
while (in.tv_usec < 0)
{
in.tv_usec += USEC;
in.tv_sec--;
}
}
//////////////////////////////////////////////////////////////
// Function name : TimeDif
// Description :
// Return type : inline void
// Argument : const struct timeval &start
// Argument : const struct timeval &fin
// Argument : struct timeval &answer
//////////////////////////////////////////////////////////////
inline void TimeDif(const struct timeval &start, const struct timeval &fin, struct timeval &answer)
{
answer.tv_usec = fin.tv_usec - start.tv_usec;
answer.tv_sec = fin.tv_sec - start.tv_sec;
NormalizeTime(answer);
}
//////////////////////////////////////////////////////////////
// Function name : TimeAdd
// Description :
// Return type : inline void
// Argument : const struct timeval &start
// Argument : const struct timeval &delta
// Argument : struct timeval &answer
//////////////////////////////////////////////////////////////
inline void TimeAdd(const struct timeval &start, const struct timeval &delta, struct timeval &answer)
{
answer.tv_usec = start.tv_usec + delta.tv_usec;
answer.tv_sec = start.tv_sec + delta.tv_sec;
NormalizeTime(answer);
}
#ifdef WIN32
////////////////////////////////////////////////////////////////
//
// Lets make Windows think it is a unix machine :)
//
//////////////////////////////////////////////////////////////
// Function name : gettimeofday
// Description :
// Return type : inline int
// Argument : struct timeval *tv
// Argument : void * trash
//////////////////////////////////////////////////////////////
inline int gettimeofday(struct timeval *tv, void * trash)
{
struct timeb timeb;
ftime( &timeb);
tv->tv_sec = (long)timeb.time;
tv->tv_usec = (unsigned int)timeb.millitm * 1000;
return 0;
}
#endif
#include "time_clock.h"
#include "time_span.h"
#include "time_general.h"
#include "time_out.h"
#endif //__TIME_BASE_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,168 +1,168 @@
#ifndef __TIME_GENERAL_H__
#define __TIME_GENERAL_H__
Time_Span TimeDifference(const Time_Clock &time1, const Time_Clock &time2);
Time_Clock TimeDifference( const Time_Clock &time1, const Time_Span &Time_Span);
Time_Clock TimeAddition(const Time_Clock &time1, Time_Span &Time_Span);
Time_Clock operator+(const Time_Clock &tm, const Time_Span &ts);
Time_Clock operator-(const Time_Clock &tm, const Time_Span &ts);
bool SetFromTimeStr(const char * str, Time_Clock & outtime);
std::string GetTimeStr(const Time_Clock & intime);
//////////////////////////////////////////////////////////////
// Function name : TimeDifference
// Description :
// Return type : inline Time_Span
// Argument : const Time_Clock &time1
// Argument : const Time_Clock &time2
//////////////////////////////////////////////////////////////
inline Time_Span TimeDifference(const Time_Clock &time1, const Time_Clock &time2)
{
timeval ans;
TimeDif(time2.GetTval(), time1.GetTval(), ans);
return Time_Span(ans);
}
//////////////////////////////////////////////////////////////
// Function name : TimeDifference
// Description :
// Return type :
// Argument : const Time_Clock &time1
// Argument : const Time_Span &Time_Span
//////////////////////////////////////////////////////////////
inline Time_Clock TimeDifference( const Time_Clock &time1, const Time_Span &Time_Span)
{
timeval ans;
TimeDif(Time_Span.GetTval(), time1.GetTval(), ans);
return Time_Clock(ans);
}
//////////////////////////////////////////////////////////////
// Function name : TimeAddition
// Description :
// Return type :
// Argument : const Time_Clock &time1
// Argument : Time_Span &Time_Span
//////////////////////////////////////////////////////////////
inline Time_Clock TimeAddition(const Time_Clock &time1, Time_Span &Time_Span)
{
timeval ans;
TimeAdd(time1.GetTval(), Time_Span.GetTval(), ans);
return Time_Clock(ans);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Clock& Time_Clock::operator+=
// Description :
// Return type : inline const
// Argument : Time_Span &Time_Span
//////////////////////////////////////////////////////////////
inline const Time_Clock& Time_Clock::operator+=(const Time_Span &Time_Span)
{
_my_time.tv_usec += Time_Span._my_time.tv_usec;
_my_time.tv_sec += Time_Span._my_time.tv_sec;
NormalizeTime(_my_time);
return *this;
}
//////////////////////////////////////////////////////////////
// Function name : operator+
// Description :
// Return type : inline Time_Clock
// Argument : const Time_Clock &tm
// Argument : const Time_Span &ts
//////////////////////////////////////////////////////////////
inline Time_Clock operator+(const Time_Clock &tm, const Time_Span &ts)
{
Time_Clock work(tm);
work += ts;
return work;
}
//////////////////////////////////////////////////////////////
// Function name : operator-
// Description :
// Return type : inline Time_Clock
// Argument : const Time_Clock &tm
// Argument : const Time_Span &ts
//////////////////////////////////////////////////////////////
inline Time_Clock operator-(const Time_Clock &tm, const Time_Span &ts)
{
return TimeDifference(tm, ts);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Clock& Time_Clock::operator-=
// Description :
// Return type : inline const
// Argument : Time_Span &Time_Span
//////////////////////////////////////////////////////////////
inline const Time_Clock& Time_Clock::operator-=(const Time_Span &Time_Span)
{
_my_time.tv_usec -= Time_Span._my_time.tv_usec;
_my_time.tv_sec -= Time_Span._my_time.tv_sec;
NormalizeTime(_my_time);
return *this;
}
//////////////////////////////////////////////////////////////
// Function name : operator-
// Description :
// Return type : inline Time_Span
// Argument : const Time_Clock &tm1
// Argument : const Time_Clock &tm2
//////////////////////////////////////////////////////////////
inline Time_Span operator-(const Time_Clock &tm1, const Time_Clock &tm2)
{
return TimeDifference(tm1, tm2);
}
//////////////////////////////////////////////////////////////
// Function name : char * GetTimeStr
// Description :
// Return type : inline const
// Argument : const Time_Clock & intime
//////////////////////////////////////////////////////////////
inline std::string GetTimeStr(const Time_Clock & intime)
{
static std::string ts;
static Time_Clock prev_time;
if (prev_time != intime || ts.empty())
{
ts = intime.Format("%Y-%m-%d %H:%M:%S");
prev_time = intime;
}
return ts;
}
//////////////////////////////////////////////////////////////
// Function name : GetTimeStr
// Description :
// Return type : inline std::string
// Argument : void
//////////////////////////////////////////////////////////////
inline std::string GetTimeStr()
{
return GetTimeStr(Time_Clock::GetCurrentTime());
}
//////////////////////////////////////////////////////////////
// Function name : SetFromTimeStr
// Description :
// Return type : inline bool
// Argument : const char * str
// Argument : Time_Clock & outtime
//////////////////////////////////////////////////////////////
inline bool SetFromTimeStr(const char * str, Time_Clock & outtime)
{
int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int min = 0;
int sec = 0;
if (sscanf(str, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec) != 6)
return false;
outtime.Set(year, month, day, hour, min, sec);
return true;
}
#endif //__TIME_GENERAL_H__
#ifndef __TIME_GENERAL_H__
#define __TIME_GENERAL_H__
Time_Span TimeDifference(const Time_Clock &time1, const Time_Clock &time2);
Time_Clock TimeDifference( const Time_Clock &time1, const Time_Span &Time_Span);
Time_Clock TimeAddition(const Time_Clock &time1, Time_Span &Time_Span);
Time_Clock operator+(const Time_Clock &tm, const Time_Span &ts);
Time_Clock operator-(const Time_Clock &tm, const Time_Span &ts);
bool SetFromTimeStr(const char * str, Time_Clock & outtime);
std::string GetTimeStr(const Time_Clock & intime);
//////////////////////////////////////////////////////////////
// Function name : TimeDifference
// Description :
// Return type : inline Time_Span
// Argument : const Time_Clock &time1
// Argument : const Time_Clock &time2
//////////////////////////////////////////////////////////////
inline Time_Span TimeDifference(const Time_Clock &time1, const Time_Clock &time2)
{
timeval ans;
TimeDif(time2.GetTval(), time1.GetTval(), ans);
return Time_Span(ans);
}
//////////////////////////////////////////////////////////////
// Function name : TimeDifference
// Description :
// Return type :
// Argument : const Time_Clock &time1
// Argument : const Time_Span &Time_Span
//////////////////////////////////////////////////////////////
inline Time_Clock TimeDifference( const Time_Clock &time1, const Time_Span &Time_Span)
{
timeval ans;
TimeDif(Time_Span.GetTval(), time1.GetTval(), ans);
return Time_Clock(ans);
}
//////////////////////////////////////////////////////////////
// Function name : TimeAddition
// Description :
// Return type :
// Argument : const Time_Clock &time1
// Argument : Time_Span &Time_Span
//////////////////////////////////////////////////////////////
inline Time_Clock TimeAddition(const Time_Clock &time1, Time_Span &Time_Span)
{
timeval ans;
TimeAdd(time1.GetTval(), Time_Span.GetTval(), ans);
return Time_Clock(ans);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Clock& Time_Clock::operator+=
// Description :
// Return type : inline const
// Argument : Time_Span &Time_Span
//////////////////////////////////////////////////////////////
inline const Time_Clock& Time_Clock::operator+=(const Time_Span &Time_Span)
{
_my_time.tv_usec += Time_Span._my_time.tv_usec;
_my_time.tv_sec += Time_Span._my_time.tv_sec;
NormalizeTime(_my_time);
return *this;
}
//////////////////////////////////////////////////////////////
// Function name : operator+
// Description :
// Return type : inline Time_Clock
// Argument : const Time_Clock &tm
// Argument : const Time_Span &ts
//////////////////////////////////////////////////////////////
inline Time_Clock operator+(const Time_Clock &tm, const Time_Span &ts)
{
Time_Clock work(tm);
work += ts;
return work;
}
//////////////////////////////////////////////////////////////
// Function name : operator-
// Description :
// Return type : inline Time_Clock
// Argument : const Time_Clock &tm
// Argument : const Time_Span &ts
//////////////////////////////////////////////////////////////
inline Time_Clock operator-(const Time_Clock &tm, const Time_Span &ts)
{
return TimeDifference(tm, ts);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Clock& Time_Clock::operator-=
// Description :
// Return type : inline const
// Argument : Time_Span &Time_Span
//////////////////////////////////////////////////////////////
inline const Time_Clock& Time_Clock::operator-=(const Time_Span &Time_Span)
{
_my_time.tv_usec -= Time_Span._my_time.tv_usec;
_my_time.tv_sec -= Time_Span._my_time.tv_sec;
NormalizeTime(_my_time);
return *this;
}
//////////////////////////////////////////////////////////////
// Function name : operator-
// Description :
// Return type : inline Time_Span
// Argument : const Time_Clock &tm1
// Argument : const Time_Clock &tm2
//////////////////////////////////////////////////////////////
inline Time_Span operator-(const Time_Clock &tm1, const Time_Clock &tm2)
{
return TimeDifference(tm1, tm2);
}
//////////////////////////////////////////////////////////////
// Function name : char * GetTimeStr
// Description :
// Return type : inline const
// Argument : const Time_Clock & intime
//////////////////////////////////////////////////////////////
inline std::string GetTimeStr(const Time_Clock & intime)
{
static std::string ts;
static Time_Clock prev_time;
if (prev_time != intime || ts.empty())
{
ts = intime.Format("%Y-%m-%d %H:%M:%S");
prev_time = intime;
}
return ts;
}
//////////////////////////////////////////////////////////////
// Function name : GetTimeStr
// Description :
// Return type : inline std::string
// Argument : void
//////////////////////////////////////////////////////////////
inline std::string GetTimeStr()
{
return GetTimeStr(Time_Clock::GetCurrentTime());
}
//////////////////////////////////////////////////////////////
// Function name : SetFromTimeStr
// Description :
// Return type : inline bool
// Argument : const char * str
// Argument : Time_Clock & outtime
//////////////////////////////////////////////////////////////
inline bool SetFromTimeStr(const char * str, Time_Clock & outtime)
{
int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int min = 0;
int sec = 0;
if (sscanf(str, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec) != 6)
return false;
outtime.Set(year, month, day, hour, min, sec);
return true;
}
#endif //__TIME_GENERAL_H__

View File

@@ -1,158 +1,158 @@
#ifndef __TIME_OUT_H__
#define __TIME_OUT_H__
///////////////////////////////////////
//
// think of this class as a time based alarm..
//
// would be nice to have a template implementation of this class .. could avoud some storage and some math ..
//
// I would do this but not sure how to represent the duration in the template ??
//
/////////////////////////////////////////////////////////////////////////////////////////////
class Time_Out
{
public:
Time_Out()
{
}
Time_Out(const Time_Span & dur) : _alarm_time(Time_Clock::GetCurrentTime() + dur) , _duration(dur)
{
}
/*
Time_Out(const Time_Clock & tm, const Time_Span & dur) : _alarm_time(tm + dur) , _duration(dur)
{
}
*/
void ResetAll(const Time_Clock &tm, const Time_Span &sp);
void ReStart();
void ResetTime(const Time_Clock & tm);
void SetTimeOutSec(int sec);
bool Expired(const Time_Clock &tm, bool reset = false);
bool Expired(bool reset = false);
Time_Span Remaining(const Time_Clock & tm) const;
Time_Span Remaining() const;
void ForceToExpired()
{
_alarm_time.ToCurrentTime();
}
bool operator() (bool reset= false)
{
return Expired(reset);
}
bool operator() (const Time_Clock &tm, bool reset = false)
{
return Expired(tm, reset);
}
Time_Clock GetAlarm(void)
{
return _alarm_time;
}
Time_Span Duration() const { return _duration; };
void NextInStep(Time_Clock &curtime)
{
_alarm_time += _duration;
if(_alarm_time <=curtime) // if we fall way behind.. just ratchet it up ...
_alarm_time = curtime+_duration;
}
private:
Time_Clock _alarm_time;
Time_Span _duration;
};
//////////////////////////////////////////////////////////////
// Function name : Time_Out::ReStart
// Description :
// Return type : void
// Argument : const Time_Clock &tm
// Argument : const Time_Span &sp
//////////////////////////////////////////////////////////////
inline void Time_Out::ResetAll(const Time_Clock &tm, const Time_Span &sp)
{
_duration = sp;
_alarm_time = tm + _duration;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::ReStart
// Description :
// Return type : void
// Argument : const Time_Clock &tm
//////////////////////////////////////////////////////////////
inline void Time_Out::SetTimeOutSec(int sec)
{
_duration.Set(0, 0, 0, sec, 0);
ReStart();
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::ReStart
// Description :
// Return type : void
// Argument : void
//////////////////////////////////////////////////////////////
inline void Time_Out::ReStart()
{
_alarm_time = Time_Clock::GetCurrentTime() + _duration;
}
//////////////////////////////////////////////////////////////
// Function name : ResetTime
// Description :
// Return type : void
// Argument : const Time_Clock & tm
//////////////////////////////////////////////////////////////
inline void Time_Out::ResetTime(const Time_Clock & tm)
{
_alarm_time = tm + _duration;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Expired
// Description :
// Return type : bool
// Argument : const Time_Clock &tm
//////////////////////////////////////////////////////////////
inline bool Time_Out::Expired(const Time_Clock &tm, bool reset)
{
bool answer = (_alarm_time <= tm) ;
if (answer && reset)
ResetTime(tm);
return answer;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Expired
// Description :
// Return type : bool
// Argument : void
//////////////////////////////////////////////////////////////
inline bool Time_Out::Expired(bool reset)
{
return Expired(Time_Clock::GetCurrentTime(), reset);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Remaining
// Description :
// Return type : Time_Span
// Argument : const Time_Clock & tm
//////////////////////////////////////////////////////////////
inline Time_Span Time_Out::Remaining(const Time_Clock & tm) const
{
return _alarm_time - tm;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Remaining
// Description :
// Return type : Time_Span
// Argument : void
//////////////////////////////////////////////////////////////
inline Time_Span Time_Out::Remaining() const
{
return Remaining(Time_Clock::GetCurrentTime());
}
#endif //__TIME_OUT_H__
#ifndef __TIME_OUT_H__
#define __TIME_OUT_H__
///////////////////////////////////////
//
// think of this class as a time based alarm..
//
// would be nice to have a template implementation of this class .. could avoud some storage and some math ..
//
// I would do this but not sure how to represent the duration in the template ??
//
/////////////////////////////////////////////////////////////////////////////////////////////
class Time_Out
{
public:
Time_Out()
{
}
Time_Out(const Time_Span & dur) : _alarm_time(Time_Clock::GetCurrentTime() + dur) , _duration(dur)
{
}
/*
Time_Out(const Time_Clock & tm, const Time_Span & dur) : _alarm_time(tm + dur) , _duration(dur)
{
}
*/
void ResetAll(const Time_Clock &tm, const Time_Span &sp);
void ReStart();
void ResetTime(const Time_Clock & tm);
void SetTimeOutSec(int sec);
bool Expired(const Time_Clock &tm, bool reset = false);
bool Expired(bool reset = false);
Time_Span Remaining(const Time_Clock & tm) const;
Time_Span Remaining() const;
void ForceToExpired()
{
_alarm_time.ToCurrentTime();
}
bool operator() (bool reset= false)
{
return Expired(reset);
}
bool operator() (const Time_Clock &tm, bool reset = false)
{
return Expired(tm, reset);
}
Time_Clock GetAlarm(void)
{
return _alarm_time;
}
Time_Span Duration() const { return _duration; };
void NextInStep(Time_Clock &curtime)
{
_alarm_time += _duration;
if(_alarm_time <=curtime) // if we fall way behind.. just ratchet it up ...
_alarm_time = curtime+_duration;
}
private:
Time_Clock _alarm_time;
Time_Span _duration;
};
//////////////////////////////////////////////////////////////
// Function name : Time_Out::ReStart
// Description :
// Return type : void
// Argument : const Time_Clock &tm
// Argument : const Time_Span &sp
//////////////////////////////////////////////////////////////
inline void Time_Out::ResetAll(const Time_Clock &tm, const Time_Span &sp)
{
_duration = sp;
_alarm_time = tm + _duration;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::ReStart
// Description :
// Return type : void
// Argument : const Time_Clock &tm
//////////////////////////////////////////////////////////////
inline void Time_Out::SetTimeOutSec(int sec)
{
_duration.Set(0, 0, 0, sec, 0);
ReStart();
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::ReStart
// Description :
// Return type : void
// Argument : void
//////////////////////////////////////////////////////////////
inline void Time_Out::ReStart()
{
_alarm_time = Time_Clock::GetCurrentTime() + _duration;
}
//////////////////////////////////////////////////////////////
// Function name : ResetTime
// Description :
// Return type : void
// Argument : const Time_Clock & tm
//////////////////////////////////////////////////////////////
inline void Time_Out::ResetTime(const Time_Clock & tm)
{
_alarm_time = tm + _duration;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Expired
// Description :
// Return type : bool
// Argument : const Time_Clock &tm
//////////////////////////////////////////////////////////////
inline bool Time_Out::Expired(const Time_Clock &tm, bool reset)
{
bool answer = (_alarm_time <= tm) ;
if (answer && reset)
ResetTime(tm);
return answer;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Expired
// Description :
// Return type : bool
// Argument : void
//////////////////////////////////////////////////////////////
inline bool Time_Out::Expired(bool reset)
{
return Expired(Time_Clock::GetCurrentTime(), reset);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Remaining
// Description :
// Return type : Time_Span
// Argument : const Time_Clock & tm
//////////////////////////////////////////////////////////////
inline Time_Span Time_Out::Remaining(const Time_Clock & tm) const
{
return _alarm_time - tm;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Remaining
// Description :
// Return type : Time_Span
// Argument : void
//////////////////////////////////////////////////////////////
inline Time_Span Time_Out::Remaining() const
{
return Remaining(Time_Clock::GetCurrentTime());
}
#endif //__TIME_OUT_H__

View File

@@ -1,387 +1,387 @@
#ifndef __TIME_SPAN_H__
#define __TIME_SPAN_H__
//////////////////////////////////////////////////////
// Class : Time_Span
//
// Description:
//////////////////////////////////////////////////////
class Time_Span
{
public:
// Constructors
Time_Span()
{
}
Time_Span(struct timeval time)
{
_my_time = time;NormalizeTime(_my_time);
}
Time_Span(time_t time);
Time_Span(long lDays, int nHours, int nMins, int nSecs, int usecs);
Time_Span(long seconds, int usecs ) ;
Time_Span(const Time_Span& Time_SpanSrc);
Time_Span(const Time_Clock& Time_SpanSrc);
///////////////////
const Time_Span& operator=(const Time_Span& Time_SpanSrc);
// Attributes
// extract parts
long GetDays() const; // total # of days
long GetTotalHours() const;
int GetHours() const;
long GetTotalMinutes() const;
int GetMinutes() const;
long GetTotalSeconds() const;
int GetSeconds() const;
long GetTotalMSeconds() const;
long GetTotal100Seconds() const;
long GetMSeconds() const;
// Operations
// time math
const Time_Span& operator+=(Time_Span &Time_Span);
const Time_Span& operator-=(Time_Span &Time_Span);
bool operator==(Time_Span &Time_Span) const;
bool operator!=(Time_Span &Time_Span) const;
bool operator<(Time_Span &Time_Span) const;
bool operator>(Time_Span &Time_Span) const;
bool operator<=(Time_Span &Time_Span) const;
bool operator>=(Time_Span &Time_Span) const;
const timeval & GetTval() const
{
return _my_time;
}
void Set(long lDays, int nHours, int nMins, int nSecs, int usecs);
std::string Format(char *pFormat) const;
private:
struct timeval _my_time;
friend class Time_Clock;
};
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(long seconds, int usecs)
{
_my_time.tv_sec = seconds;
_my_time.tv_usec = usecs;
NormalizeTime(_my_time);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(time_t time)
{
_my_time.tv_usec = 0;
_my_time.tv_sec = (long)time;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(long lDays, int nHours, int nMins, int nSecs, int usecs)
{
_my_time.tv_sec = nSecs + 60 * (nMins + 60 * (nHours + 24 * lDays));
_my_time.tv_usec = usecs;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Set
// Description :
//////////////////////////////////////////////////////////////
inline void Time_Span::Set(long lDays, int nHours, int nMins, int nSecs, int usecs)
{
_my_time.tv_sec = nSecs + 60 * (nMins + 60 * (nHours + 24 * lDays));
_my_time.tv_usec = usecs;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(const Time_Span& Time_SpanSrc)
{
_my_time = Time_SpanSrc._my_time;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(const Time_Clock& Time_SpanSrc)
{
_my_time = Time_SpanSrc._my_time;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span& Time_Span::operator=
// Description :
//////////////////////////////////////////////////////////////
inline const Time_Span& Time_Span::operator=(const Time_Span& Time_SpanSrc)
{
if (&Time_SpanSrc == this)
return * this;
_my_time = Time_SpanSrc._my_time; return *this;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetDays
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetDays() const
{
return _my_time.tv_sec / (24*3600L);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalHours
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetTotalHours() const
{
return _my_time.tv_sec / 3600;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetHours
// Description :
//////////////////////////////////////////////////////////////
inline int Time_Span::GetHours() const
{
return (int)(GetTotalHours() - GetDays()*24);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalMinutes
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetTotalMinutes() const
{
return _my_time.tv_sec / 60;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetMinutes
// Description :
//////////////////////////////////////////////////////////////
inline int Time_Span::GetMinutes() const
{
return (int)(GetTotalMinutes() - GetTotalHours()*60);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalSeconds
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetTotalSeconds() const
{
return _my_time.tv_sec;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalMSeconds
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetTotalMSeconds() const
{
return (_my_time.tv_sec * 1000) + (_my_time.tv_usec / 1000);
}
inline long Time_Span::GetTotal100Seconds() const
{
return (_my_time.tv_sec * 100) + (_my_time.tv_usec / 10000);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalMSeconds
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetMSeconds() const
{
return (_my_time.tv_usec / 1000);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetSeconds
// Description :
//////////////////////////////////////////////////////////////
inline int Time_Span::GetSeconds() const
{
return (int)(GetTotalSeconds() - GetTotalMinutes()*60);
}
//////////////////////////////////////////////////////////////
// Function name : TimeDifference
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span TimeDifference(const Time_Span &Time_Span1, const Time_Span &Time_Span2)
{
timeval ans;
TimeDif(Time_Span2.GetTval(), Time_Span1.GetTval(), ans);
return Time_Span(ans);
}
//////////////////////////////////////////////////////////////
// Function name : TimeAddition
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span TimeAddition(const Time_Span &Time_Span1, const Time_Span &Time_Span2)
{
timeval ans;
TimeAdd(Time_Span2.GetTval(), Time_Span1.GetTval(), ans);
return Time_Span(ans);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span& Time_Span::operator+=
// Description :
//////////////////////////////////////////////////////////////
inline const Time_Span& Time_Span::operator+=(Time_Span &Time_Span)
{
_my_time.tv_usec += Time_Span._my_time.tv_usec;
_my_time.tv_sec += Time_Span._my_time.tv_sec;
NormalizeTime(_my_time);
return *this;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span& Time_Span::operator-=
// Description :
//////////////////////////////////////////////////////////////
inline const Time_Span& Time_Span::operator-=(Time_Span &Time_Span)
{
_my_time.tv_usec -= Time_Span._my_time.tv_usec;
_my_time.tv_sec -= Time_Span._my_time.tv_sec;
NormalizeTime(_my_time);
return *this;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator==
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator==(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec == Time_Span._my_time.tv_usec));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator!=
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator!=(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec != Time_Span._my_time.tv_sec) || (_my_time.tv_usec != Time_Span._my_time.tv_usec));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator<
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator<(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec < Time_Span._my_time.tv_sec) ||
((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec < Time_Span._my_time.tv_usec)));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator>
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator>(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec > Time_Span._my_time.tv_sec) ||
((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec > Time_Span._my_time.tv_usec)));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator<=
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator<=(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec < Time_Span._my_time.tv_sec) ||
((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec <= Time_Span._my_time.tv_usec)));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator>=
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator>=(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec > Time_Span._my_time.tv_sec) ||
((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec >= Time_Span._my_time.tv_usec)));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Format
// Description :
//////////////////////////////////////////////////////////////
inline std::string Time_Span::Format(char * pFormat) const
// formatting Time_Spans is a little trickier than formatting
// * we are only interested in relative time formats, ie. it is illegal
// to format anything dealing with absolute time (i.e. years, months,
// day of week, day of year, timezones, ...)
// * the only valid formats:
// %D - # of days -- NEW !!!
// %H - hour in 24 hour format
// %M - minute (0-59)
// %S - seconds (0-59)
// %% - percent sign
// %N - nanosecs
{
char szBuffer[maxTimeBufferSize];
char ch;
char * pch = szBuffer;
while ((ch = *pFormat++) != '\0') {
assert(pch < &szBuffer[maxTimeBufferSize]);
if (ch == '%') {
switch (ch = *pFormat++) {
default:
assert(false); // probably a bad format character
case '%':
*pch++ = ch;
break;
case 'D':
pch += sprintf(pch, "%ld", GetDays());
break;
case 'H':
pch += sprintf(pch, "%02d", GetHours());
break;
case 'M':
pch += sprintf(pch, "%02d", GetMinutes());
break;
case 'S':
pch += sprintf(pch, "%02d", GetSeconds());
break;
case 'N':
pch += sprintf(pch, "%03d", _my_time.tv_usec / 1000);
break;
}
} else {
*pch++ = ch;
}
}
*pch = '\0';
return std::string(szBuffer);
}
#endif //__TIME_SPAN_H__
#ifndef __TIME_SPAN_H__
#define __TIME_SPAN_H__
//////////////////////////////////////////////////////
// Class : Time_Span
//
// Description:
//////////////////////////////////////////////////////
class Time_Span
{
public:
// Constructors
Time_Span()
{
}
Time_Span(struct timeval time)
{
_my_time = time;NormalizeTime(_my_time);
}
Time_Span(time_t time);
Time_Span(long lDays, int nHours, int nMins, int nSecs, int usecs);
Time_Span(long seconds, int usecs ) ;
Time_Span(const Time_Span& Time_SpanSrc);
Time_Span(const Time_Clock& Time_SpanSrc);
///////////////////
const Time_Span& operator=(const Time_Span& Time_SpanSrc);
// Attributes
// extract parts
long GetDays() const; // total # of days
long GetTotalHours() const;
int GetHours() const;
long GetTotalMinutes() const;
int GetMinutes() const;
long GetTotalSeconds() const;
int GetSeconds() const;
long GetTotalMSeconds() const;
long GetTotal100Seconds() const;
long GetMSeconds() const;
// Operations
// time math
const Time_Span& operator+=(Time_Span &Time_Span);
const Time_Span& operator-=(Time_Span &Time_Span);
bool operator==(Time_Span &Time_Span) const;
bool operator!=(Time_Span &Time_Span) const;
bool operator<(Time_Span &Time_Span) const;
bool operator>(Time_Span &Time_Span) const;
bool operator<=(Time_Span &Time_Span) const;
bool operator>=(Time_Span &Time_Span) const;
const timeval & GetTval() const
{
return _my_time;
}
void Set(long lDays, int nHours, int nMins, int nSecs, int usecs);
std::string Format(char *pFormat) const;
private:
struct timeval _my_time;
friend class Time_Clock;
};
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(long seconds, int usecs)
{
_my_time.tv_sec = seconds;
_my_time.tv_usec = usecs;
NormalizeTime(_my_time);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(time_t time)
{
_my_time.tv_usec = 0;
_my_time.tv_sec = (long)time;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(long lDays, int nHours, int nMins, int nSecs, int usecs)
{
_my_time.tv_sec = nSecs + 60 * (nMins + 60 * (nHours + 24 * lDays));
_my_time.tv_usec = usecs;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Set
// Description :
//////////////////////////////////////////////////////////////
inline void Time_Span::Set(long lDays, int nHours, int nMins, int nSecs, int usecs)
{
_my_time.tv_sec = nSecs + 60 * (nMins + 60 * (nHours + 24 * lDays));
_my_time.tv_usec = usecs;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(const Time_Span& Time_SpanSrc)
{
_my_time = Time_SpanSrc._my_time;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Time_Span
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span::Time_Span(const Time_Clock& Time_SpanSrc)
{
_my_time = Time_SpanSrc._my_time;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span& Time_Span::operator=
// Description :
//////////////////////////////////////////////////////////////
inline const Time_Span& Time_Span::operator=(const Time_Span& Time_SpanSrc)
{
if (&Time_SpanSrc == this)
return * this;
_my_time = Time_SpanSrc._my_time; return *this;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetDays
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetDays() const
{
return _my_time.tv_sec / (24*3600L);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalHours
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetTotalHours() const
{
return _my_time.tv_sec / 3600;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetHours
// Description :
//////////////////////////////////////////////////////////////
inline int Time_Span::GetHours() const
{
return (int)(GetTotalHours() - GetDays()*24);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalMinutes
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetTotalMinutes() const
{
return _my_time.tv_sec / 60;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetMinutes
// Description :
//////////////////////////////////////////////////////////////
inline int Time_Span::GetMinutes() const
{
return (int)(GetTotalMinutes() - GetTotalHours()*60);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalSeconds
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetTotalSeconds() const
{
return _my_time.tv_sec;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalMSeconds
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetTotalMSeconds() const
{
return (_my_time.tv_sec * 1000) + (_my_time.tv_usec / 1000);
}
inline long Time_Span::GetTotal100Seconds() const
{
return (_my_time.tv_sec * 100) + (_my_time.tv_usec / 10000);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetTotalMSeconds
// Description :
//////////////////////////////////////////////////////////////
inline long Time_Span::GetMSeconds() const
{
return (_my_time.tv_usec / 1000);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::GetSeconds
// Description :
//////////////////////////////////////////////////////////////
inline int Time_Span::GetSeconds() const
{
return (int)(GetTotalSeconds() - GetTotalMinutes()*60);
}
//////////////////////////////////////////////////////////////
// Function name : TimeDifference
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span TimeDifference(const Time_Span &Time_Span1, const Time_Span &Time_Span2)
{
timeval ans;
TimeDif(Time_Span2.GetTval(), Time_Span1.GetTval(), ans);
return Time_Span(ans);
}
//////////////////////////////////////////////////////////////
// Function name : TimeAddition
// Description :
//////////////////////////////////////////////////////////////
inline Time_Span TimeAddition(const Time_Span &Time_Span1, const Time_Span &Time_Span2)
{
timeval ans;
TimeAdd(Time_Span2.GetTval(), Time_Span1.GetTval(), ans);
return Time_Span(ans);
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span& Time_Span::operator+=
// Description :
//////////////////////////////////////////////////////////////
inline const Time_Span& Time_Span::operator+=(Time_Span &Time_Span)
{
_my_time.tv_usec += Time_Span._my_time.tv_usec;
_my_time.tv_sec += Time_Span._my_time.tv_sec;
NormalizeTime(_my_time);
return *this;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span& Time_Span::operator-=
// Description :
//////////////////////////////////////////////////////////////
inline const Time_Span& Time_Span::operator-=(Time_Span &Time_Span)
{
_my_time.tv_usec -= Time_Span._my_time.tv_usec;
_my_time.tv_sec -= Time_Span._my_time.tv_sec;
NormalizeTime(_my_time);
return *this;
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator==
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator==(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec == Time_Span._my_time.tv_usec));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator!=
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator!=(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec != Time_Span._my_time.tv_sec) || (_my_time.tv_usec != Time_Span._my_time.tv_usec));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator<
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator<(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec < Time_Span._my_time.tv_sec) ||
((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec < Time_Span._my_time.tv_usec)));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator>
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator>(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec > Time_Span._my_time.tv_sec) ||
((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec > Time_Span._my_time.tv_usec)));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator<=
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator<=(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec < Time_Span._my_time.tv_sec) ||
((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec <= Time_Span._my_time.tv_usec)));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::operator>=
// Description :
//////////////////////////////////////////////////////////////
inline bool Time_Span::operator>=(Time_Span &Time_Span) const
{
return ((_my_time.tv_sec > Time_Span._my_time.tv_sec) ||
((_my_time.tv_sec == Time_Span._my_time.tv_sec) && (_my_time.tv_usec >= Time_Span._my_time.tv_usec)));
}
//////////////////////////////////////////////////////////////
// Function name : Time_Span::Format
// Description :
//////////////////////////////////////////////////////////////
inline std::string Time_Span::Format(char * pFormat) const
// formatting Time_Spans is a little trickier than formatting
// * we are only interested in relative time formats, ie. it is illegal
// to format anything dealing with absolute time (i.e. years, months,
// day of week, day of year, timezones, ...)
// * the only valid formats:
// %D - # of days -- NEW !!!
// %H - hour in 24 hour format
// %M - minute (0-59)
// %S - seconds (0-59)
// %% - percent sign
// %N - nanosecs
{
char szBuffer[maxTimeBufferSize];
char ch;
char * pch = szBuffer;
while ((ch = *pFormat++) != '\0') {
assert(pch < &szBuffer[maxTimeBufferSize]);
if (ch == '%') {
switch (ch = *pFormat++) {
default:
assert(false); // probably a bad format character
case '%':
*pch++ = ch;
break;
case 'D':
pch += sprintf(pch, "%ld", GetDays());
break;
case 'H':
pch += sprintf(pch, "%02d", GetHours());
break;
case 'M':
pch += sprintf(pch, "%02d", GetMinutes());
break;
case 'S':
pch += sprintf(pch, "%02d", GetSeconds());
break;
case 'N':
pch += sprintf(pch, "%03d", _my_time.tv_usec / 1000);
break;
}
} else {
*pch++ = ch;
}
}
*pch = '\0';
return std::string(szBuffer);
}
#endif //__TIME_SPAN_H__