summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorzwer <zwer@1f4bef6d-8e0a-0410-8695-e467da8aaccf>2006-01-24 13:13:39 +0000
committerzwer <zwer@1f4bef6d-8e0a-0410-8695-e467da8aaccf>2006-01-24 13:13:39 +0000
commit0d14897dfb0fe4310ccb2bb51a5960a03d5a5bc6 (patch)
tree7b65667843ea5db07766d23688f045d20140361c /tools
parente1dadf2dbdd2bcf65517310498ded03c821e463e (diff)
downloadvdr-plugin-ffnetdev-0d14897dfb0fe4310ccb2bb51a5960a03d5a5bc6.tar.gz
vdr-plugin-ffnetdev-0d14897dfb0fe4310ccb2bb51a5960a03d5a5bc6.tar.bz2
Im Projektarchiv verschoben
git-svn-id: svn://svn.berlios.de/ffnetdev/trunk@5 1f4bef6d-8e0a-0410-8695-e467da8aaccf
Diffstat (limited to 'tools')
-rw-r--r--tools/select.c49
-rw-r--r--tools/select.h75
-rw-r--r--tools/socket.c135
-rw-r--r--tools/socket.h108
-rw-r--r--tools/source.c169
-rw-r--r--tools/source.h109
-rw-r--r--tools/tools.c12
-rw-r--r--tools/tools.h67
8 files changed, 724 insertions, 0 deletions
diff --git a/tools/select.c b/tools/select.c
new file mode 100644
index 0000000..0ab5f9b
--- /dev/null
+++ b/tools/select.c
@@ -0,0 +1,49 @@
+#include "tools/select.h"
+
+#include <vdr/tools.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+
+cTBSelect::cTBSelect(void) {
+ Clear();
+}
+
+cTBSelect::~cTBSelect() {
+}
+
+int cTBSelect::Select(uint TimeoutMs) {
+ struct timeval tv;
+ ssize_t res;
+ int ms;
+
+ tv.tv_usec = (TimeoutMs % 1000) * 1000;
+ tv.tv_sec = TimeoutMs / 1000;
+
+ if (TimeoutMs == 0)
+ return ::select(m_MaxFiled + 1, &m_Rfds, &m_Wfds, NULL, &tv);
+
+ cTimeMs starttime;
+ ms = TimeoutMs;
+ while (ms > 0 && (res = ::select(m_MaxFiled + 1, &m_Rfds, &m_Wfds, NULL,
+ &tv)) == -1 && errno == EINTR) {
+ ms = TimeoutMs - starttime.Elapsed();
+ tv.tv_usec = (ms % 1000) * 1000;
+ tv.tv_sec = ms / 1000;
+ }
+ if (ms <= 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ return res;
+}
+
+int cTBSelect::Select(void) {
+ ssize_t res;
+ while ((res = ::select(m_MaxFiled + 1, &m_Rfds, &m_Wfds, NULL, NULL)) == -1
+ && errno == EINTR)
+ ;
+ return res;
+}
diff --git a/tools/select.h b/tools/select.h
new file mode 100644
index 0000000..7e873e2
--- /dev/null
+++ b/tools/select.h
@@ -0,0 +1,75 @@
+#ifndef TOOLBOX_SELECT_H
+#define TOOLBOX_SELECT_H
+
+#include "tools/tools.h"
+
+#include <sys/types.h>
+
+/* cTBSelect provides an interface for polling UNIX-like file descriptors. */
+
+class cTBSelect {
+private:
+ int m_MaxFiled;
+
+ fd_set m_Rfds;
+ fd_set m_Wfds;
+
+public:
+ cTBSelect(void);
+ virtual ~cTBSelect();
+
+ /* Clear() resets the object for use in a new Select() call. All file
+ descriptors and their previous states are invalidated. */
+ virtual void Clear(void);
+
+ /* Add() adds a file descriptor to be polled in the next Select() call.
+ That call polls if the file is readable if Output is set to false,
+ writeable otherwise. */
+ virtual bool Add(int Filed, bool Output = false);
+
+ /* Select() polls all descriptors added by Add() and returns as soon as
+ one of those changes state (gets readable/writeable), or after
+ TimeoutMs milliseconds, whichever happens first. It returns the number
+ of filedescriptors that have changed state. On error, -1 is returned
+ and errno is set appropriately. */
+ virtual int Select(uint TimeoutMs);
+
+ /* Select() polls all descriptors added by Add() and returns as soon as
+ one of those changes state (gets readable/writeable). It returns the
+ number of filedescriptors that have changed state. On error, -1 is
+ returned and errno is set appropriately. */
+ virtual int Select(void);
+
+ /* CanRead() returns true if the descriptor has changed to readable during
+ the last Select() call. Otherwise false is returned. */
+ virtual bool CanRead(int FileNo) const;
+
+ /* CanWrite() returns true if the descriptor has changed to writeable
+ during the last Select() call. Otherwise false is returned. */
+ virtual bool CanWrite(int FileNo) const;
+};
+
+inline void cTBSelect::Clear(void) {
+ FD_ZERO(&m_Rfds);
+ FD_ZERO(&m_Wfds);
+ m_MaxFiled = -1;
+}
+
+inline bool cTBSelect::Add(int Filed, bool Output /* = false */) {
+ if (Filed < 0) return false;
+ FD_SET(Filed, Output ? &m_Wfds : &m_Rfds);
+ if (Filed > m_MaxFiled) m_MaxFiled = Filed;
+ return true;
+}
+
+inline bool cTBSelect::CanRead(int FileNo) const {
+ if (FileNo < 0) return false;
+ return FD_ISSET(FileNo, &m_Rfds);
+}
+
+inline bool cTBSelect::CanWrite(int FileNo) const {
+ if (FileNo < 0) return false;
+ return FD_ISSET(FileNo, &m_Wfds);
+}
+
+#endif // TOOLBOX_SELECT_H
diff --git a/tools/socket.c b/tools/socket.c
new file mode 100644
index 0000000..3e3be65
--- /dev/null
+++ b/tools/socket.c
@@ -0,0 +1,135 @@
+#include "tools/socket.h"
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+cTBSocket::cTBSocket(int Type) {
+ memset(&m_LocalAddr, 0, sizeof(m_LocalAddr));
+ memset(&m_RemoteAddr, 0, sizeof(m_RemoteAddr));
+ m_Type = Type;
+}
+
+cTBSocket::~cTBSocket() {
+ if (IsOpen()) Close();
+}
+
+bool cTBSocket::Connect(const std::string &Host, unsigned int Port) {
+ socklen_t len;
+ int socket;
+
+ if (IsOpen()) Close();
+
+ if ((socket = ::socket(PF_INET, m_Type, IPPROTO_IP)) == -1)
+ return false;
+
+ m_LocalAddr.sin_family = AF_INET;
+ m_LocalAddr.sin_port = 0;
+ m_LocalAddr.sin_addr.s_addr = INADDR_ANY;
+ if (::bind(socket, (struct sockaddr*)&m_LocalAddr, sizeof(m_LocalAddr))
+ == -1)
+ return false;
+
+ m_RemoteAddr.sin_family = AF_INET;
+ m_RemoteAddr.sin_port = htons(Port);
+ m_RemoteAddr.sin_addr.s_addr = inet_addr(Host.c_str());
+ if (::connect(socket, (struct sockaddr*)&m_RemoteAddr,
+ sizeof(m_RemoteAddr)) == -1)
+ return false;
+
+ len = sizeof(struct sockaddr_in);
+ if (::getpeername(socket, (struct sockaddr*)&m_RemoteAddr, &len) == -1)
+ return false;
+
+ len = sizeof(struct sockaddr_in);
+ if (::getsockname(socket, (struct sockaddr*)&m_LocalAddr, &len) == -1)
+ return false;
+
+ return cTBSource::Open(socket);
+}
+
+bool cTBSocket::Listen(const std::string &Ip, unsigned int Port, int BackLog) {
+ int val;
+ socklen_t len;
+ int socket;
+
+ if (IsOpen()) Close();
+
+ if ((socket = ::socket(PF_INET, m_Type, IPPROTO_IP)) == -1)
+ return false;
+
+ val = 1;
+ if (::setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1)
+ return false;
+
+ m_LocalAddr.sin_family = AF_INET;
+ m_LocalAddr.sin_port = htons(Port);
+ m_LocalAddr.sin_addr.s_addr = inet_addr(Ip.c_str());
+ if (::bind(socket, (struct sockaddr*)&m_LocalAddr, sizeof(m_LocalAddr))
+ == -1)
+ return false;
+
+ len = sizeof(struct sockaddr_in);
+ if (::getsockname(socket, (struct sockaddr*)&m_LocalAddr, &len) == -1)
+ return false;
+
+ if (m_Type == SOCK_STREAM && ::listen(socket, BackLog) == -1)
+ return false;
+
+ if (!cTBSource::Open(socket))
+ return false;
+
+ return true;
+}
+
+bool cTBSocket::Accept(const cTBSocket &Listener) {
+ socklen_t addrlen;
+ int socket;
+
+ if (IsOpen()) Close();
+
+ addrlen = sizeof(struct sockaddr_in);
+ if ((socket = ::accept(Listener, (struct sockaddr*)&m_RemoteAddr,
+ &addrlen)) == -1)
+ return false;
+
+ addrlen = sizeof(struct sockaddr_in);
+ if (::getsockname(socket, (struct sockaddr*)&m_LocalAddr, &addrlen) == -1)
+ return false;
+
+ if (!cTBSource::Open(socket))
+ return false;
+
+ return true;
+}
+
+RETURNS(cTBSocket, cTBSocket::Accept(void) const, ret)
+ ret.Accept(*this);
+RETURN(ret)
+
+bool cTBSocket::Close(void) {
+ bool ret = true;
+
+ if (!IsOpen())
+ ERRNUL(EBADF);
+
+ if (::close(*this) == -1)
+ ret = false;
+
+ if (!cTBSource::Close())
+ ret = false;
+
+ memset(&m_LocalAddr, 0, sizeof(m_LocalAddr));
+ memset(&m_RemoteAddr, 0, sizeof(m_RemoteAddr));
+
+ return ret;
+}
+
+bool cTBSocket::Shutdown(int how) {
+ if (!IsOpen())
+ ERRNUL(EBADF);
+
+ return ::shutdown(*this, how) != -1;
+}
diff --git a/tools/socket.h b/tools/socket.h
new file mode 100644
index 0000000..d1a7d62
--- /dev/null
+++ b/tools/socket.h
@@ -0,0 +1,108 @@
+#ifndef TOOLBOX_SOCKET_H
+#define TOOLBOX_SOCKET_H
+
+#include "tools/tools.h"
+#include "tools/source.h"
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string>
+
+/* cTBSocket provides a cTBSource-derived interface for input and output on
+ TCP/IPv4-sockets. */
+
+class cTBSocket: public cTBSource {
+private:
+ struct sockaddr_in m_LocalAddr;
+ struct sockaddr_in m_RemoteAddr;
+
+ int m_Type;
+
+public:
+ cTBSocket(int Type = SOCK_STREAM);
+ virtual ~cTBSocket();
+
+ /* See cTBSource::SysRead()
+ Reimplemented for TCP/IPv4 sockets. */
+ virtual ssize_t SysRead(void *Buffer, size_t Length) const;
+
+ /* See cTBSource::SysWrite()
+ Reimplemented for TCP/IPv4 sockets. */
+ virtual ssize_t SysWrite(const void *Buffer, size_t Length) const;
+
+ /* Connect() tries to connect an available local socket to the port given
+ by Port of the target host given by Host in numbers-and-dots notation
+ (i.e. "212.43.45.21"). Returns true if the connection attempt was
+ successful and false otherwise, setting errno appropriately. */
+ virtual bool Connect(const std::string &Host, uint Port);
+
+ /* Shutdown() shuts down one or both ends of a socket. If called with How
+ set to SHUT_RD, further reads on this socket will be denied. If called
+ with SHUT_WR, all writes are denied. Called with SHUT_RDWR, all firther
+ action on this socket will be denied. Returns true on success and false
+ otherwise, setting errno appropriately. */
+ virtual bool Shutdown(int How);
+
+ /* Close() closes the associated socket and releases all structures.
+ Returns true on success and false otherwise, setting errno
+ appropriately. The object is in the closed state afterwards, regardless
+ of any errors. */
+ virtual bool Close(void);
+
+ /* Listen() listens on the local port Port for incoming connections. The
+ BackLog parameter defines the maximum length the queue of pending
+ connections may grow to. Returns true if the object is listening on
+ the specified port and false otherwise, setting errno appropriately. */
+ virtual bool Listen(const std::string &Ip, uint Port, int BackLog);
+
+ /* Accept() returns a newly created cTBSocket, which is connected to the
+ first connection request on the queue of pending connections of a
+ listening socket. If no connection request was pending, or if any other
+ error occured, the resulting cTBSocket is closed. */
+ virtual cTBSocket Accept(void) const;
+
+ /* Accept() extracts the first connection request on the queue of pending
+ connections of the listening socket Listener and connects it to this
+ object. Returns true on success and false otherwise, setting errno to
+ an appropriate value. */
+ virtual bool Accept(const cTBSocket &Listener);
+
+ /* LocalPort() returns the port number this socket is connected to locally.
+ The result is undefined for a non-open socket. */
+ int LocalPort(void) const { return ntohs(m_LocalAddr.sin_port); }
+
+ /* RemotePort() returns the port number this socket is connected to on the
+ remote side. The result is undefined for a non-open socket. */
+ int RemotePort(void) const { return ntohs(m_RemoteAddr.sin_port); }
+
+ /* LocalIp() returns the internet address in numbers-and-dots notation of
+ the interface this socket is connected to locally. This can be
+ "0.0.0.0" for a listening socket listening to all interfaces. If the
+ socket is in its closed state, the result is undefined. */
+ std::string LocalIp(void) const { return inet_ntoa(m_LocalAddr.sin_addr); }
+
+ /* RemoteIp() returns the internet address in numbers-and-dots notation of
+ the interface this socket is connected to on the remote side. If the
+ socket is in its closed state, the result is undefined. */
+ std::string RemoteIp(void) const { return inet_ntoa(m_RemoteAddr.sin_addr); }
+
+ in_addr_t LocalIpAddr(void) const { return m_LocalAddr.sin_addr.s_addr; }
+ in_addr_t RemoteIpAddr(void) const { return m_RemoteAddr.sin_addr.s_addr; }
+
+ int Type(void) const { return m_Type; }
+};
+
+inline ssize_t cTBSocket::SysRead(void *Buffer, size_t Length) const {
+ if (m_Type == SOCK_DGRAM) {
+ socklen_t len = sizeof(m_RemoteAddr);
+ return ::recvfrom(*this, Buffer, Length, 0, (sockaddr*)&m_RemoteAddr, &len);
+ } else
+ return ::recv(*this, Buffer, Length, 0);
+}
+
+inline ssize_t cTBSocket::SysWrite(const void *Buffer, size_t Length) const {
+ return ::send(*this, Buffer, Length, 0);
+}
+
+#endif // TOOLBOX_SOCKET_H
diff --git a/tools/source.c b/tools/source.c
new file mode 100644
index 0000000..f8751b6
--- /dev/null
+++ b/tools/source.c
@@ -0,0 +1,169 @@
+#include "tools/source.h"
+#include "tools/select.h"
+
+#include <vdr/tools.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+cTBSource::cTBSource(void) {
+ m_BytesRead = 0;
+ m_BytesWritten = 0;
+ m_Filed = -1;
+}
+
+bool cTBSource::Open(int Filed, bool IsUnixFd) {
+ if (IsOpen())
+ Close();
+
+ m_Filed = Filed;
+ if (IsUnixFd && ::fcntl(m_Filed, F_SETFL, O_NONBLOCK) == -1)
+ return false;
+
+ return true;
+}
+
+cTBSource::~cTBSource() {
+}
+
+bool cTBSource::Close(void) {
+ if (!IsOpen()) {
+ errno = EBADF;
+ return false;
+ }
+
+ m_Filed = -1;
+ return true;
+}
+
+ssize_t cTBSource::Read(void *Buffer, size_t Length) {
+ ssize_t res;
+ while ((res = SysRead(Buffer, Length)) < 0 && errno == EINTR)
+ errno = 0;
+ if (res > 0) m_BytesRead += res;
+ return res;
+}
+
+ssize_t cTBSource::Write(const void *Buffer, size_t Length) {
+ ssize_t res;
+ while ((res = SysWrite(Buffer, Length)) < 0 && errno == EINTR)
+ errno = 0;
+ if (res > 0) m_BytesWritten += res;
+ return res;
+}
+
+bool cTBSource::TimedWrite(const void *Buffer, size_t Length, uint TimeoutMs) {
+ cTBSelect sel;
+ int ms, offs;
+
+ cTimeMs starttime;
+ ms = TimeoutMs;
+ offs = 0;
+ while (Length > 0) {
+ int b;
+
+ sel.Clear();
+ sel.Add(m_Filed, true);
+ if (sel.Select(ms) == -1)
+ return false;
+
+ if (sel.CanWrite(m_Filed)) {
+ if ((b = Write((char*)Buffer + offs, Length)) == -1)
+ return false;
+ offs += b;
+ Length -= b;
+ }
+
+ ms = TimeoutMs - starttime.Elapsed();
+ if (ms <= 0) {
+ errno = ETIMEDOUT;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cTBSource::SafeWrite(const void *Buffer, size_t Length) {
+ cTBSelect sel;
+ int offs;
+
+ offs = 0;
+ while (Length > 0) {
+ int b;
+
+ sel.Clear();
+ sel.Add(m_Filed, true);
+ if (sel.Select() == -1)
+ return false;
+
+ if (sel.CanWrite(m_Filed)) {
+ if ((b = Write((char*)Buffer + offs, Length)) == -1)
+ return false;
+ offs += b;
+ Length -= b;
+ }
+
+ }
+ return true;
+}
+
+ssize_t cTBSource::ReadUntil(void *Buffer, size_t Length, const char *Seq,
+ uint TimeoutMs) {
+ int ms;
+ size_t len;
+ cTBSelect sel;
+
+ if ((len = m_LineBuffer.find(Seq)) != (size_t)-1) {
+ if (len > Length) {
+ errno = ENOBUFS;
+ return -1;
+ }
+ memcpy(Buffer, m_LineBuffer.data(), len);
+ m_LineBuffer.erase(0, len + strlen(Seq));
+ //Dprintf("ReadUntil: Served from Linebuffer: %d, |%.*s|\n", len, len - 1,
+ // (char*)Buffer);
+ return len;
+ }
+
+ cTimeMs starttime;
+ ms = TimeoutMs;
+ while (m_LineBuffer.size() < BUFSIZ) {
+ sel.Clear();
+ sel.Add(m_Filed, false);
+
+ if (sel.Select(ms) == -1)
+ return -1;
+
+ if (sel.CanRead(m_Filed)) {
+ int b;
+
+ len = m_LineBuffer.size();
+ m_LineBuffer.resize(BUFSIZ);
+ if ((b = Read((char*)m_LineBuffer.data() + len, BUFSIZ - len)) == -1)
+ return -1;
+ m_LineBuffer.resize(len + b);
+
+ if ((len = m_LineBuffer.find(Seq)) != (size_t)-1) {
+ if (len > Length) {
+ errno = ENOBUFS;
+ return -1;
+ }
+ memcpy(Buffer, m_LineBuffer.data(), len);
+ m_LineBuffer.erase(0, len + strlen(Seq));
+ //Dprintf("ReadUntil: Served from Linebuffer: %d, |%.*s|\n", len, len - 1,
+ // (char*)Buffer);
+ return len;
+ }
+ }
+
+ ms = TimeoutMs - starttime.Elapsed();
+ if (ms <= 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ }
+ errno = ENOBUFS;
+ return -1;
+}
+
diff --git a/tools/source.h b/tools/source.h
new file mode 100644
index 0000000..09c4bf3
--- /dev/null
+++ b/tools/source.h
@@ -0,0 +1,109 @@
+#ifndef TOOLBOX_SOURCE_H
+#define TOOLBOX_SOURCE_H
+
+#include "tools/tools.h"
+
+#include <sys/types.h>
+#include <string>
+
+/* cTBSource provides an abstract interface for input and output. It can
+ be used to have common access to different types of UNIX-files. */
+
+class cTBSource {
+private:
+ int m_Filed;
+
+ size_t m_BytesRead;
+ size_t m_BytesWritten;
+
+ std::string m_LineBuffer;
+
+public:
+ cTBSource(void);
+ virtual ~cTBSource();
+
+ /* SysRead() implements the low-level read on the source. It will store
+ data into the area pointed to by Buffer, which is at least Length
+ bytes in size. It will return the exact number of bytes read (which
+ can be fewer than requested). On error, -1 is returned, and errno
+ is set to an appropriate value. */
+ virtual ssize_t SysRead(void *Buffer, size_t Length) const = 0;
+
+ /* SysWrite() implements the low-level write on the source. It will write
+ at most Length bytes of the data pointed to by Buffer. It will return
+ the exact number of bytes written (which can be fewer than requested).
+ On error, -1 is returned, and errno is set to an appropriate value. */
+ virtual ssize_t SysWrite(const void *Buffer, size_t Length) const = 0;
+
+ /* IsOpen() returns true, if this source refers to a valid descriptor.
+ It is not checked whether this source is really open, so only if
+ opened by the appropriate Methods this function will return the
+ correct value */
+ virtual bool IsOpen(void) const { return m_Filed != -1; }
+
+ /* Open() associates this source with the descriptor Filed, setting it
+ to non-blocking mode if IsUnixFd in true. Returns true on success,
+ and false on error, setting errno to appropriately.
+ If you want to implement sources that can't be represented by UNIX
+ filedescriptors, you can use Filed to store any useful information
+ about the source.
+ This must be called by any derivations in an appropriate Method (like
+ open for files, connect for sockets). */
+ virtual bool Open(int Filed, bool IsUnixFd = true);
+
+ /* Close() resets the source to the uninitialized state (IsOpen() == false)
+ and must be called by any derivations after really closing the source.
+ Returns true on success and false on error, setting errno appropriately.
+ The object is in closed state afterwards, even if an error occured. */
+ virtual bool Close(void);
+
+ /* Read() reads at most Length bytes into the storage pointed to by Buffer,
+ which must be at least Length bytes in size, using the SysRead()-
+ Interface. It retries if an EINTR occurs (i.e. the low-level call was
+ interrupted). It returns the exact number of bytes read (which can be
+ fewer than requested). On error, -1 is returned, and errno is set
+ appropriately. */
+ ssize_t Read(void *Buffer, size_t Length);
+
+ /* Write() writes at most Length bytes from the storage pointed to by
+ Buffer, using the SysWrite()-Interface. It retries if EINTR occurs
+ (i.e. the low-level call was interrupted). It returns the exact number
+ of bytes written (which can be fewer than requested). On error, -1 is
+ returned and errno is set appropriately. */
+ ssize_t Write(const void *Buffer, size_t Length);
+
+ /* TimedWrite() tries to write Length bytes from the storage pointed to by
+ Buffer within the time specified by TimeoutMs, using the Write()-
+ Interface. On success, true is returned. On error, false is returned
+ and errno is set appropriately. TimedRead only works on UNIX file
+ descriptor sources. */
+ bool TimedWrite(const void *Buffer, size_t Length, uint TimeoutMs);
+
+ bool SafeWrite(const void *Buffer, size_t Length);
+
+ /* ReadUntil() tries to read at most Length bytes into the storage pointed
+ to by Buffer, which must be at least Length bytes in size, within the
+ time specified by TimeoutMs, using the Read()-Interface. Reading stops
+ after the character sequence Seq has been read and on end-of-file.
+ Returns the number of bytes read (if that is equal to Length, you have
+ to check if the buffer ends with Seq), or -1 on error, in which case
+ errno is set appropriately. */
+ ssize_t ReadUntil(void *Buffer, size_t Length, const char *Seq,
+ uint TimeoutMs);
+
+ /* BytesRead() returns the exact number of bytes read through the Read()
+ method since Close() has been called on this source (or since its
+ creation). */
+ size_t BytesRead(void) const { return m_BytesRead; }
+
+ /* BytesWritten() returns the exact number of bytes written through the
+ Write() method since Close() has been called on this source (or since
+ its creation). */
+ size_t BytesWritten(void) const { return m_BytesWritten; }
+
+ /* operator int() returns the descriptor (or informative number) associated
+ with this source. */
+ operator int() const { return m_Filed; }
+};
+
+#endif // TOOLBOX_SOURCE_H
diff --git a/tools/tools.c b/tools/tools.c
new file mode 100644
index 0000000..fa813fa
--- /dev/null
+++ b/tools/tools.c
@@ -0,0 +1,12 @@
+#include "tools/tools.h"
+
+#include <sys/time.h>
+#include <time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+void *operator new(size_t nSize, void *p) throw () {
+ return p;
+}
+
diff --git a/tools/tools.h b/tools/tools.h
new file mode 100644
index 0000000..ab00c60
--- /dev/null
+++ b/tools/tools.h
@@ -0,0 +1,67 @@
+#ifndef TOOLBOX_TOOLS_H
+#define TOOLBOX_TOOLS_H
+
+//#include <stdio.h>
+//#include <iostream>
+#include <sys/types.h>
+
+//#define KILOBYTE(x) ((x)*1024)
+//#define MEGABYTE(x) (KILOBYTE(x)*1024)
+
+//typedef unsigned int uint;
+//typedef unsigned long ulong;
+typedef unsigned char uchar;
+//typedef unsigned short ushort;
+
+// Special constructor for CreateElements
+void *operator new(size_t, void*) throw ();
+
+#ifdef TOOLBOX_DEBUG
+# define ASSERT(x) if ((x)) cerr << "Warning: ASSERT failed At " << __FILE__ << ":" << __LINE__ << " ["#x"]" << endl
+# define CHECK_PTR(x) if (!(x)) cerr << "Warning: Pointer is NULL At " << __FILE__ << ":" << __LINE__ << endl;
+# define CHECK_NEXT_ALLOC() _checkNextAlloc()
+# define DPRINT(x...) LOGi(x)
+#else
+# define ASSERT(x)
+# define CHECK_PTR(x)
+# define CHECK_NEXT_ALLOC()
+# define DPRINT(x...)
+#endif
+
+#define ERRNUL(e) {errno=e;return 0;}
+#define ERRSYS(e) {errno=e;return -1;}
+
+/* RETURNS() and RETURN() are macros that can be used if a class object is
+ being returned. They make use of the GNU C-Compiler's named return value
+ feature, if available. In this case, the class object isn't returned and
+ copied, but the result itself is filled.
+
+ RETURNS(ReturnType, FunctionDeclaration, Result)
+ ... function-body working on Result ...
+ RETURN(Result)
+
+ A function like this (cXYZ is a class type):
+
+ cXYZ myfunction(int a, char *b) {
+ cXYZ result;
+ ... something happens with result ...
+ return result;
+ }
+
+ can be written like this:
+
+ RETURNS(cXYZ, myfunction(int a, char *b), result)
+ ... something happens with result ...
+ RETURN(result)
+
+ DISABLED SINCE GCC 3.x
+*/
+//#ifdef __GNUC__
+//# define RETURNS(t,x,r) t x return r {
+//# define RETURN(x) }
+//#else
+# define RETURNS(t,x,r) t x { t r;
+# define RETURN(x) return x; }
+//#endif
+
+#endif // TOOLBOX_TOOLS_H