Initial revision

This commit is contained in:
lordjaxom
2004-12-30 22:43:55 +00:00
commit 302fa2e672
96 changed files with 21399 additions and 0 deletions

95
tools/file.c Normal file
View File

@@ -0,0 +1,95 @@
#include "tools/file.h"
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
cTBFile::cTBFile(void) {
}
cTBFile::~cTBFile() {
Close();
}
bool cTBFile::Open(const cTBString &Filename, int Mode, mode_t Attribs) {
int filed;
if (IsOpen()) Close();
if ((filed = ::open(Filename, Mode, Attribs)) == -1)
return false;
if (!cTBSource::Open(filed))
return false;
m_Filename = Filename;
m_Anonymous = false;
return true;
}
bool cTBFile::Open(uint Fileno) {
if (IsOpen()) Close();
if (!cTBSource::Open(Fileno))
return false;
m_Filename.Format("<&%d>", Fileno);
m_Anonymous = true;
return true;
}
bool cTBFile::Close(void) {
bool ret = true;
if (!IsOpen())
ERRNUL(EBADF);
if (::close(*this) == -1)
ret = false;
if (!cTBSource::Close())
ret = false;
m_Filename.Clear();
return ret;
}
bool cTBFile::Unlink(void) const {
if (m_Filename.IsNull())
ERRNUL(ENOENT);
if (!IsOpen())
ERRNUL(EBADF);
if (m_Anonymous)
ERRNUL(EINVAL);
return cTBFile::Unlink(m_Filename);
}
bool cTBFile::Unlink(const cTBString &Filename) {
return (::unlink(Filename) != -1);
}
ssize_t cTBFile::Size(void) const {
struct stat buf;
if (!IsOpen())
ERRSYS(EBADF);
if (fstat(*this, &buf) == -1)
return -1;
return buf.st_size;
}
ssize_t cTBFile::Size(const cTBString &Filename) {
struct stat buf;
if (stat(Filename, &buf) == -1)
return -1;
return buf.st_size;
}

100
tools/file.h Normal file
View File

@@ -0,0 +1,100 @@
#ifndef TOOLBOX_FILE_H
#define TOOLBOX_FILE_H
#include "tools/tools.h"
#include "tools/source.h"
#include "tools/string.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* cTBFile provides a cTBSource-derived interface for input and output on UNIX
files. */
class cTBFile: public cTBSource {
private:
bool m_Anonymous;
cTBString m_Filename;
/* Unhide and forbid baseclass method */
virtual bool Open(int Fd, bool IsUnixFd = false) { return false; }
public:
cTBFile(void);
virtual ~cTBFile();
/* enum eFileType represents the modes a file can be opened with. The full
open mode is one of the first three, maybe or'ed with one of the others.
*/
enum eFileType {
ReadOnly = O_RDONLY,
WriteOnly = O_WRONLY,
ReadWrite = O_RDWR,
Create = O_CREAT,
Exclude = O_EXCL,
Truncate = O_TRUNC,
Append = O_APPEND
};
/* See cTBSource::SysRead()
Reimplemented for UNIX files. */
virtual ssize_t SysRead(void *Buffer, size_t Length) const;
/* See cTBSource::SysWrite()
Reimplemented for UNIX files. */
virtual ssize_t SysWrite(const void *Buffer, size_t Length) const;
/* Open() opens the file referred to by Filename according to the given
Mode. If the file is created, it receives the attributes given by
Attribs, defaulting to rw-------. Returns true on success and false on
error, setting errno appropriately. */
virtual bool Open(const cTBString &Filename, int Mode,
mode_t Attribs = S_IRUSR + S_IWUSR);
/* Open() associates this file object with Fileno. Fileno must refer to a
previously opened file descriptor, which will be set non-blocking by
this call. If successful, true is returned, false otherwise and errno
is set appropriately. */
virtual bool Open(uint Fileno);
/* Close() closes the associated file descriptor and releases all
structures. Returns true on success and false otherwise, setting errno
appropriately. The object is in the closed state afterwards, even if
an error occured. */
virtual bool Close(void);
/* Unlink() unlinks (deletes) the associated file from the underlying
filesystem. Returns true on success and false otherwise, setting errno
appropriately. The file must be opened by filename to use this. */
virtual bool Unlink(void) const;
/* Unlink() unlinks (deletes) the file referred to by Filename from the
underlying filesystem. Returns true on success and false otherwise,
setting errno appropriately. */
static bool Unlink(const cTBString &Filename);
/* Size() returns the current size of the associated file. Returns the
exact size of the file in bytes. Returns -1 on error, setting errno to
an appropriate value. */
virtual ssize_t Size(void) const;
/* Size() returns the current size of the file referred to by Filename.
Symbolic links are followed (the size of the link-target is returned).
Returns the exact size of the file in bytes. Returns -1 on error,
setting errno to an appropriate value. */
static ssize_t Size(const cTBString &Filename);
};
inline ssize_t cTBFile::SysRead(void *Buffer, size_t Length) const {
return ::read(*this, Buffer, Length);
}
inline ssize_t cTBFile::SysWrite(const void *Buffer, size_t Length) const {
return ::write(*this, Buffer, Length);
}
#endif // TOOLBOX_FILE_H

52
tools/select.c Normal file
View File

@@ -0,0 +1,52 @@
#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;
time_t st, et;
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);
st = time_ms();
ms = TimeoutMs;
while (ms > 0 && (res = ::select(m_MaxFiled + 1, &m_Rfds, &m_Wfds, NULL,
&tv)) == -1 && errno == EINTR) {
et = time_ms();
ms -= et - st;
tv.tv_usec = (ms % 1000) * 1000;
tv.tv_sec = ms / 1000;
st = et;
}
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;
}

75
tools/select.h Normal file
View File

@@ -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

90
tools/shared.c Normal file
View File

@@ -0,0 +1,90 @@
#include "tools/shared.h"
#include <errno.h>
#include <stddef.h>
#include <string.h>
cSharedData *cSharedData::Construct (size_t Length) {
size_t reallength = sizeof(cSharedData) + Length;
cSharedData *ret = (cSharedData*)new char[reallength];
ret->m_Length = Length;
ret->m_NumRefs = 0;
return ret;
}
cTBShared::cTBShared(void) {
m_Buffer = NULL;
}
cTBShared::cTBShared (const cTBShared &src) {
m_Buffer = src.m_Buffer;
if (m_Buffer)
++*m_Buffer;
}
cTBShared::~cTBShared () {
if (m_Buffer)
Release();
}
void cTBShared::Clear () {
if (m_Buffer)
Release();
m_Buffer = 0;
}
void cTBShared::Set (const cTBShared &src) {
if (m_Buffer)
Release();
m_Buffer = src.m_Buffer;
if (m_Buffer)
++*m_Buffer;
}
void cTBShared::Release () {
CHECK_PTR(m_Buffer);
if (--*m_Buffer == 0)
delete[] (char*)m_Buffer;
m_Buffer = 0;
}
void cTBShared::Release(uint newsize) {
CHECK_PTR(m_Buffer);
Allocate(newsize, true);
}
void cTBShared::Exclusive () {
CHECK_PTR(m_Buffer);
if (m_Buffer->Refs() == 1)
return;
cSharedData *copy = cSharedData::Construct(m_Buffer->Size());
memcpy(*copy, *m_Buffer, m_Buffer->Size());
Release();
m_Buffer = copy;
++*m_Buffer;
}
void cTBShared::Allocate (size_t len, bool keep /* = false */) {
if (m_Buffer && (m_Buffer->Refs() == 1) && (m_Buffer->Size() == len))
return;
cSharedData *newBuffer = cSharedData::Construct(len);
if (m_Buffer) {
if (keep)
memcpy(*newBuffer, *m_Buffer, len < m_Buffer->Size() ? len : m_Buffer->Size());
Release();
}
m_Buffer = newBuffer;
++*m_Buffer;
}

65
tools/shared.h Normal file
View File

@@ -0,0 +1,65 @@
#ifndef TOOLBOX_SHARED_H
#define TOOLBOX_SHARED_H
#include "tools/tools.h"
struct cSharedData {
private:
uint m_Length;
uint m_NumRefs;
public:
static cSharedData *Construct (size_t Length);
operator char * () { return this ? (char*)(this+1) : 0; }
uint operator++ () { return ++m_NumRefs; }
uint operator-- () { return --m_NumRefs; }
size_t Size() const { return m_Length; }
uint Refs () const { return m_NumRefs; }
};
class cTBShared {
private:
cSharedData *m_Buffer;
protected:
void Release();
void Exclusive();
void Allocate(size_t len, bool keep = false);
char *Buffer() const { return m_Buffer ? (char*)*m_Buffer : (char*)0; }
public:
cTBShared (void);
cTBShared (const cTBShared &src);
virtual ~cTBShared ();
virtual void Clear ();
virtual void Set (const cTBShared &src);
virtual char *Buffer (uint size);
virtual void Release (uint newsize);
cTBShared &operator= (const cTBShared &src) { Set(src); return *this; }
operator const void * () const { return m_Buffer ? (const void*)*m_Buffer : (const void*)0; }
operator void * () const { return m_Buffer ? (void*)*m_Buffer : (void*)0; }
operator const char * () const { return m_Buffer ? (const char*)*m_Buffer : (const char*)0; }
size_t Size() const { return m_Buffer ? m_Buffer->Size() : 0; }
size_t Length() const { return m_Buffer ? m_Buffer->Size() : 0; }
// friend cSource &operator>> (cSource &dest, cTBShared &str);
};
inline char *cTBShared::Buffer(uint size) {
if ((!m_Buffer) || (m_Buffer->Refs() > 1) || (size > m_Buffer->Size()))
Allocate(size, true);
return Buffer();
}
#endif // TOOLBOX_SHARED_H

135
tools/socket.c Normal file
View File

@@ -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 cTBString &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);
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 char *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);
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;
}

108
tools/socket.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef TOOLBOX_SOCKET_H
#define TOOLBOX_SOCKET_H
#include "tools/tools.h"
#include "tools/source.h"
#include "tools/string.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* 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 cTBString &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 char *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. */
cTBString 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. */
cTBString 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

195
tools/source.c Normal file
View File

@@ -0,0 +1,195 @@
#include "tools/source.h"
#include "tools/select.h"
#include "common.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;
time_t st;
int ms, offs;
st = time_ms();
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 -= time_ms() - st;
if (ms <= 0) {
errno = ETIMEDOUT;
return false;
}
}
return true;
}
ssize_t cTBSource::ReadUntil(void *Buffer, size_t Length, const char *Seq,
uint TimeoutMs) {
char *offs;
time_t st;
int seqlen, ms;
size_t olen;
cTBSelect sel;
seqlen = strlen(Seq);
if ((offs = (char*)memmem(m_LineBuffer, m_LineBuffer.Length(), Seq, seqlen))){
olen = offs - m_LineBuffer;
if (olen >= Length) {
errno = ENOBUFS;
return -1;
}
memcpy(Buffer, m_LineBuffer, olen);
m_LineBuffer = m_LineBuffer.Mid(olen + seqlen);
Dprintf("ReadUntil: Served from Linebuffer: %d, |%.*s|\n", olen, olen - 1,
(char*)Buffer);
return olen;
}
st = time_ms();
ms = TimeoutMs;
while (m_LineBuffer.Length() < BUFSIZ) {
int b;
sel.Clear();
sel.Add(m_Filed, false);
if (sel.Select(ms) == -1)
return -1;
if (sel.CanRead(m_Filed)) {
offs = m_LineBuffer.Buffer(BUFSIZ);
if ((b = Read(offs + m_LineBuffer.Length(), BUFSIZ
- m_LineBuffer.Length())) == -1)
return -1;
m_LineBuffer.Release(m_LineBuffer.Length() + b);
if ((offs = (char*)memmem(m_LineBuffer, m_LineBuffer.Length(), Seq,
seqlen))) {
olen = offs - m_LineBuffer;
if (olen >= Length) {
errno = ENOBUFS;
return -1;
}
memcpy(Buffer, m_LineBuffer, olen);
m_LineBuffer = m_LineBuffer.Mid(olen + seqlen, m_LineBuffer.Length()
- olen - seqlen);
Dprintf("ReadUntil: Served after Read: %d, |%.*s|\n", olen, olen-1,
(char*)Buffer);
return olen;
}
}
ms -= time_ms() - st;
if (ms <= 0) {
errno = ETIMEDOUT;
return -1;
}
}
errno = ENOBUFS;
return -1;
/*
cTBSelect sel;
time_t st, et;
int ms, seqlen, offs;
seqlen = strlen(Seq);
st = time_ms();
ms = TimeoutMs;
offs = 0;
while (Length > 0) {
int b;
sel.Clear();
sel.Add(m_Filed, false);
if (sel.Select(ms) == -1)
return -1;
if (sel.CanRead(m_Filed)) {
if ((b = Read((char*)Buffer + offs, Length)) == -1)
return -1;
offs += b;
Length -= b;
if (memmem(Buffer, offs, Seq, seqlen) != NULL)
return offs;
}
et = time_ms();
ms -= et - st;
if (ms <= 0) {
errno = ETIMEDOUT;
return -1;
}
}
errno = ENOBUFS;
return -1;
*/
}

107
tools/source.h Normal file
View File

@@ -0,0 +1,107 @@
#ifndef TOOLBOX_SOURCE_H
#define TOOLBOX_SOURCE_H
#include "tools/tools.h"
#include "tools/string.h"
#include <sys/types.h>
/* 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;
cTBString 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);
/* 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

454
tools/string.c Normal file
View File

@@ -0,0 +1,454 @@
#include "tools/string.h"
#ifdef TOOLBOX_REGEX
# include "tools/regex.h"
#endif
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <errno.h>
const cTBString cTBString::Null;
cTBString::cTBString():
cTBShared(),
m_StringLen(0) {
}
cTBString::cTBString(const cTBString &src):
cTBShared(src),
m_StringLen(src.m_StringLen) {
}
cTBString::cTBString(const char *src) {
Set(src);
}
cTBString::cTBString(const uchar *src) {
Set(src);
}
cTBString::cTBString(char src) {
Set(src);
}
cTBString::~cTBString () {
}
void cTBString::Release(uint newsize) {
m_StringLen = newsize;
cTBShared::Release(m_StringLen + 1);
Buffer()[m_StringLen] = 0;
}
void cTBString::Clear() {
cTBShared::Clear();
m_StringLen = 0;
}
void cTBString::Set(const cTBString &String) {
cTBShared::Set(String);
m_StringLen = String.m_StringLen;
}
void cTBString::Set (const char *String) {
m_StringLen = strlen(String);
Allocate(m_StringLen + 1);
memcpy(Buffer(), String, m_StringLen);
Buffer()[m_StringLen] = 0;
}
void cTBString::Set (const uchar *String) {
Set((const char*)String);
}
void cTBString::Set (char Character) {
m_StringLen = 1;
Allocate(m_StringLen + 1);
Buffer()[0] = Character;
Buffer()[1] = 0;
}
void cTBString::Fill(char Character, int Length) {
if (Length != -1) {
m_StringLen = Length;
Allocate(m_StringLen + 1);
}
memset(Buffer(), Character, m_StringLen);
Buffer()[m_StringLen] = 0;
}
void cTBString::Append(const cTBString &src) {
Allocate(m_StringLen + src.m_StringLen + 1, true);
memcpy(Buffer() + m_StringLen, src.Buffer(), src.m_StringLen);
m_StringLen += src.m_StringLen;
Buffer()[m_StringLen] = 0;
}
void cTBString::Append(const char *src) {
uint len = strlen(src);
Allocate(m_StringLen + len + 1, true);
memcpy(Buffer() + m_StringLen, src, len);
m_StringLen += len;
Buffer()[m_StringLen] = 0;
}
void cTBString::Append(char src) {
Allocate(m_StringLen + 2, true);
Buffer()[m_StringLen] = src;
++m_StringLen;
Buffer()[m_StringLen] = 0;
}
void cTBString::Prepend(const cTBString &src) {
Allocate(m_StringLen + src.m_StringLen + 1, true);
memmove(Buffer() + src.m_StringLen, Buffer(), m_StringLen);
memcpy(Buffer(), src.Buffer(), src.m_StringLen);
m_StringLen += src.m_StringLen;
Buffer()[m_StringLen] = 0;
}
void cTBString::Prepend(const char *src) {
uint len = strlen(src);
Allocate(m_StringLen + len + 1, true);
memmove(Buffer() + len, Buffer(), m_StringLen);
memcpy(Buffer(), src, len);
m_StringLen += len;
Buffer()[m_StringLen] = 0;
}
void cTBString::Prepend(char src) {
Allocate(m_StringLen + 2, true);
memmove(Buffer() + 1, Buffer(), m_StringLen);
Buffer()[0] = src;
Buffer()[++m_StringLen] = 0;
}
void cTBString::Insert(uint Index, const cTBString &String) {
Allocate(m_StringLen + String.m_StringLen + 1, true);
memmove(Buffer() + Index + String.m_StringLen, Buffer() + Index, m_StringLen - Index);
memcpy(Buffer() + Index, String.Buffer(), String.m_StringLen);
m_StringLen += String.m_StringLen;
Buffer()[m_StringLen] = 0;
}
void cTBString::Insert(uint Index, const char *String) {
uint len = strlen(String);
Allocate(m_StringLen + len + 1, true);
memmove(Buffer() + Index + len, Buffer() + Index, m_StringLen - Index);
memcpy(Buffer() + Index, String, len);
m_StringLen += len;
Buffer()[m_StringLen] = 0;
}
void cTBString::Insert(uint Index, char Character) {
Allocate(m_StringLen + 2, true);
memmove(Buffer() + Index + 1, Buffer() + Index, m_StringLen - Index);
Buffer()[Index] = Character;
Buffer()[++m_StringLen] = 0;
}
RETURNS(cTBString, cTBString::Left(uint count) const, ret)
if (count > m_StringLen)
count = m_StringLen;
ret.Allocate(count + 1);
memcpy(ret.Buffer(), Buffer(), count);
ret.Buffer()[count] = 0;
ret.m_StringLen = count;
RETURN(ret)
RETURNS(cTBString, cTBString::Right(uint count) const, ret)
if (count > m_StringLen)
count = m_StringLen;
ret.Allocate(count + 1);
memcpy(ret.Buffer(), Buffer() + m_StringLen - count, count);
ret.Buffer()[count] = 0;
ret.m_StringLen = count;
RETURN(ret)
RETURNS(cTBString, cTBString::Mid(int idx, int count) const, ret)
if (idx < 0)
idx = m_StringLen + idx;
if ((count < 0) || (count > (int)m_StringLen - idx))
count = m_StringLen - idx;
ret.Allocate(count + 1);
memcpy(ret.Buffer(), Buffer() + idx, count);
ret.Buffer()[count] = 0;
ret.m_StringLen = count;
RETURN(ret)
int cTBString::Find (const cTBString &String, uint Offset) const {
if (Offset >= m_StringLen)
return -1;
char *pos = strstr(Buffer() + Offset, String.Buffer());
if (pos) return (pos - Buffer());
else return -1;
}
int cTBString::Find (const char *String, uint Offset) const {
if (Offset >= m_StringLen)
return -1;
char *pos = strstr(Buffer() + Offset, String);
if (pos) return (pos - Buffer());
else return -1;
}
int cTBString::Find (char Character, uint Offset) const {
if (Offset >= m_StringLen)
return -1;
char *pos = strchr(Buffer() + Offset, Character);
if (pos) return (pos - Buffer());
else return -1;
}
#ifdef TOOLBOX_REGEX
bool cTBString::Find (cTBRegEx &Regex, uint Offset) const {
return Regex.Match(Buffer(), Offset);
}
#endif
void cTBString::Format (const char *fmt, ...) {
int n, size = 128;
va_list ap;
char *buf = Buffer(size);
while (1) {
va_start(ap, fmt);
n = vsnprintf(buf, size, fmt, ap);
va_end(ap);
if ((n > -1) && (n < size))
break;
if (n > -1)
size = n + 1;
else
size *= 2;
buf = Buffer(size);
}
Release(n);
}
void cTBString::Format(const cTBString &fmt, ...) {
int n, size = 128;
va_list ap;
char *buf = Buffer(size);
while (1) {
va_start(ap, &fmt);
n = vsnprintf(buf, size, fmt, ap);
va_end(ap);
if ((n > -1) && (n < size))
break;
if (n > -1)
size = n + 1;
else
size *= 2;
buf = Buffer(size);
}
Release(n);
}
template<cTBString::TOFUNC F>
cTBString cTBString::ToAnything(void) const {
const char *src;
char *dest;
cTBString ret;
src = Buffer();
dest = ret.Buffer(m_StringLen + 1);
for (; src < Buffer() + m_StringLen; ++src, ++dest)
*dest = F(*src);
*dest = '\0';
ret.Release(m_StringLen);
return ret;
}
template<cTBString::ISFUNC F>
bool cTBString::IsAnything(void) const {
const char *ptr = Buffer();
for (; ptr < Buffer() + m_StringLen; ++ptr)
if (!F(*ptr)) return false;
return true;
}
short cTBString::ToShort(bool *Ok) const {
long ret;
char *endptr;
bool res = false;
ret = strtol(Buffer(), &endptr, 0);
if (!IsEmpty() && *endptr == '\0' && ret >= SHRT_MIN && ret <= SHRT_MAX)
res = true;
if (Ok) *Ok = res;
return (short)ret;
}
ushort cTBString::ToUShort(bool *Ok) const {
ulong ret;
char *endptr;
bool res = false;
ret = strtoul(Buffer(), &endptr, 0);
if (!IsEmpty() && *endptr == '\0' && ret <= USHRT_MAX)
res = true;
if (Ok) *Ok = res;
return (ushort)ret;
}
int cTBString::ToInt(bool *Ok) const {
long ret;
char *endptr;
bool res = false;
ret = strtol(Buffer(), &endptr, 0);
if (!IsEmpty() && *endptr == '\0' && ret >= INT_MIN && ret <= INT_MAX)
res = true;
if (Ok) *Ok = res;
return (int)ret;
}
uint cTBString::ToUInt(bool *Ok) const {
ulong ret;
char *endptr;
bool res = false;
ret = strtoul(Buffer(), &endptr, 0);
if (!IsEmpty() && *endptr == '\0' && ret <= UINT_MAX)
res = true;
if (Ok) *Ok = res;
return (uint)ret;
}
long cTBString::ToLong(bool *Ok) const {
long ret;
char *endptr;
bool res = false;
errno = 0;
ret = strtol(Buffer(), &endptr, 0);
if (!IsEmpty() && *endptr == '\0' && errno != ERANGE)
res = true;
if (Ok) *Ok = res;
return (long)ret;
}
ulong cTBString::ToULong(bool *Ok) const {
ulong ret;
char *endptr;
bool res = false;
errno = 0;
ret = strtoul(Buffer(), &endptr, 0);
if (!IsEmpty() && *endptr == '\0' && errno != ERANGE)
res = true;
if (Ok) *Ok = res;
return (ulong)ret;
}
float cTBString::ToFloat(bool *Ok) const {
double ret;
char *endptr;
bool res = false;
ret = strtod(Buffer(), &endptr);
if (!IsEmpty() && *endptr == '\0' && errno != ERANGE)
res = true;
if (Ok) *Ok = res;
return (float)ret;
}
double cTBString::ToDouble(bool *Ok) const {
double ret;
char *endptr;
bool res = false;
errno = 0;
ret = strtol(Buffer(), &endptr, 0);
if (!IsEmpty() && *endptr == '\0' && errno != ERANGE)
res = true;
if (Ok) *Ok = res;
return (double)ret;
}
RETURNS(cTBString, cTBString::Number(short Num), ret)
ret.Format("%hd", Num);
RETURN(ret)
RETURNS(cTBString, cTBString::Number(ushort Num), ret)
ret.Format("%hu", Num);
RETURN(ret)
RETURNS(cTBString, cTBString::Number(int Num), ret)
ret.Format("%d", Num);
RETURN(ret)
RETURNS(cTBString, cTBString::Number(uint Num), ret)
ret.Format("%u", Num);
RETURN(ret)
RETURNS(cTBString, cTBString::Number(long Num), ret)
ret.Format("%ld", Num);
RETURN(ret)
RETURNS(cTBString, cTBString::Number(ulong Num), ret)
ret.Format("%lu", Num);
RETURN(ret)
RETURNS(cTBString, cTBString::Number(float Num), ret)
ret.Format("%f", Num);
RETURN(ret)
RETURNS(cTBString, cTBString::Number(double Num), ret)
ret.Format("%f", Num);
RETURN(ret)

353
tools/string.h Normal file
View File

@@ -0,0 +1,353 @@
#ifndef TOOLBOX_STRING_H
#define TOOLBOX_STRING_H
#include "tools/tools.h"
#include "tools/shared.h"
//#include "tools/source.h"
#include <ctype.h>
#include <stddef.h>
#include <string.h>
#ifdef TOOLBOX_REGEX
class cTBRegEx;
#endif
class cTBString: public cTBShared {
private:
uint m_StringLen;
/* Unhide and forbid baseclass method */
virtual void Set (const cTBShared &src) {}
public:
cTBString ();
cTBString (const cTBString &src);
cTBString (const uchar *src);
cTBString (const char *src);
cTBString (char src);
virtual ~cTBString ();
static const cTBString Null;
void Clear ();
void Set (const cTBString &String);
void Set (const uchar *String);
void Set (const char *String);
void Set (char Character);
void Fill (char Character, int Length = -1);
void Release (uint newsize);
cTBString &operator= (const cTBString &src) { Set(src); return *this; }
cTBString &operator= (const char *src) { Set(src); return *this; }
cTBString &operator= (char src) { Set(src); return *this; }
void Append (const cTBString &src);
void Append (const char *src);
void Append (char src);
friend cTBString operator+ (const cTBString &a, const cTBString &b);
friend cTBString operator+ (const cTBString &a, const char *b);
friend cTBString operator+ (const char *a, const cTBString &b);
friend cTBString operator+ (const cTBString &a, char b);
friend cTBString operator+ (char a, const cTBString &b);
friend cTBString &operator+= (cTBString &a, const cTBString &b);
friend cTBString &operator+= (cTBString &a, const char *b);
friend cTBString &operator+= (cTBString &a, char b);
void Prepend (const cTBString &src);
void Prepend (const char *src);
void Prepend (char src);
void Insert (uint Index, const cTBString &src);
void Insert (uint Index, const char *src);
void Insert (uint Index, char src);
char At (uint i) const;
char operator[] (int i) const { return At((uint)i); }
char &At (uint i);
char &operator[] (int i) { return At(i); }
cTBString Left (uint Count) const;
cTBString Right (uint Count) const;
cTBString Mid (int idx, int Count = -1) const;
int Find (const cTBString &String, uint Offset = 0) const;
int Find (const char *String, uint Offset = 0) const;
int Find (char Character, uint Offset = 0) const;
#ifdef TOOLBOX_REGEX
bool Find (cTBRegEx &Regex, uint Offset = 0) const;
#endif
void Format (const char *fmt, ...)
#if defined(__GNUC__)
__attribute__ ((format (printf, 2, 3)))
#endif
;
void Format (const cTBString &fmt, ...);
typedef int(*TOFUNC)(int);
template<TOFUNC F> cTBString ToAnything(void) const;
cTBString ToUpper (void) const { return ToAnything<toupper>(); }
cTBString ToLower (void) const { return ToAnything<tolower>(); }
typedef int(*ISFUNC)(int);
template<ISFUNC F> bool IsAnything(void) const;
bool IsAlnum(void) const { return IsAnything<isalnum>(); }
bool IsAlpha(void) const { return IsAnything<isalpha>(); }
bool IsAscii(void) const { return IsAnything<isascii>(); }
bool IsCntrl(void) const { return IsAnything<iscntrl>(); }
bool IsDigit(void) const { return IsAnything<isdigit>(); }
bool IsGraph(void) const { return IsAnything<isgraph>(); }
bool IsLower(void) const { return IsAnything<islower>(); }
bool IsPrint(void) const { return IsAnything<isprint>(); }
bool IsPunct(void) const { return IsAnything<ispunct>(); }
bool IsSpace(void) const { return IsAnything<isspace>(); }
bool IsUpper(void) const { return IsAnything<isupper>(); }
bool IsXdigit(void) const { return IsAnything<isxdigit>(); }
#if defined(_GNU_SOURCE)
bool IsBlank(void) const { return IsAnything<isblank>(); }
#endif
uint Length (void) const { return m_StringLen; }
bool IsEmpty (void) const { return m_StringLen == 0; }
bool IsNull (void) const { return Buffer() == 0; }
short ToShort(bool *Ok = NULL) const;
ushort ToUShort(bool *Ok = NULL) const;
int ToInt(bool *Ok = NULL) const;
uint ToUInt(bool *Ok = NULL) const;
long ToLong(bool *Ok = NULL) const;
ulong ToULong(bool *Ok = NULL) const;
float ToFloat(bool *Ok = NULL) const;
double ToDouble(bool *Ok = NULL) const;
static cTBString Number(short Num);
static cTBString Number(ushort Num);
static cTBString Number(int Num);
static cTBString Number(uint Num);
static cTBString Number(long Num);
static cTBString Number(ulong Num);
static cTBString Number(float Num);
static cTBString Number(double Num);
friend bool operator== (const cTBString &str1, const cTBString &str2);
friend bool operator== (const cTBString &str1, const char *str2);
friend bool operator== (const char *str1, const cTBString &str2);
friend bool operator!= (const cTBString &str1, const cTBString &str2);
friend bool operator!= (const cTBString &str1, const char *str2);
friend bool operator!= (const char *str1, const cTBString &str2);
friend bool operator< (const cTBString &str1, const cTBString &str2);
friend bool operator< (const cTBString &str1, const char *str2);
friend bool operator< (const char *str1, const cTBString &str2);
friend bool operator> (const cTBString &str1, const cTBString &str2);
friend bool operator> (const cTBString &str1, const char *str2);
friend bool operator> (const char *str1, const cTBString &str2);
friend bool operator<= (const cTBString &str1, const cTBString &str2);
friend bool operator<= (const cTBString &str1, const char *str2);
friend bool operator<= (const char *str1, const cTBString &str2);
friend bool operator>= (const cTBString &str1, const cTBString &str2);
friend bool operator>= (const cTBString &str1, const char *str2);
friend bool operator>= (const char *str1, const cTBString &str2);
};
inline char cTBString::At(uint idx) const {
ASSERT(idx >= m_StringLen);
return Buffer() ? Buffer()[idx] : 0;
}
inline char &cTBString::At(uint idx) {
static char null = 0;
ASSERT(idx >= m_StringLen);
if (Buffer()) {
Exclusive();
return Buffer()[idx];
} else
return (null = 0);
}
inline
RETURNS(cTBString, operator+(const cTBString &a, const cTBString &b), ret(a))
ret.Append(b);
RETURN(ret)
inline
RETURNS(cTBString, operator+ (const cTBString &a, const char *b), ret(a))
ret.Append(b);
RETURN(ret)
inline
RETURNS(cTBString, operator+ (const char *a, const cTBString &b), ret(a))
ret.Append(b);
RETURN(ret)
inline
RETURNS(cTBString, operator+ (const cTBString &a, char b), ret(a))
ret.Append(b);
RETURN(ret)
inline
RETURNS(cTBString, operator+ (char a, const cTBString &b), ret(a))
ret.Append(b);
RETURN(ret)
inline cTBString &operator+= (cTBString &a, const cTBString &b) {
a.Append(b);
return a;
}
inline cTBString &operator+= (cTBString &a, const char *b) {
a.Append(b);
return a;
}
inline cTBString &operator+= (cTBString &a, char b) {
a.Append(b);
return a;
}
inline bool operator== (const cTBString &str1, const cTBString &str2) {
if (str1.Length() != str2.Length())
return false;
return memcmp(str1.Buffer(), str2.Buffer(), str1.Length()) == 0;
}
inline bool operator== (const cTBString &str1, const char *str2) {
uint len = strlen(str2);
if (str1.Length() != len)
return false;
return memcmp(str1.Buffer(), str2, len) == 0;
}
inline bool operator== (const char *str1, const cTBString &str2) {
uint len = strlen(str1);
if (len != str2.Length())
return false;
return memcmp(str1, str2.Buffer(), len) == 0;
}
inline bool operator!= (const cTBString &str1, const cTBString &str2) {
if (str1.Length() != str2.Length())
return true;
return memcmp(str1.Buffer(), str2.Buffer(), str1.Length()) != 0;
}
inline bool operator!= (const cTBString &str1, const char *str2) {
uint len = strlen(str2);
if (str1.Length() != len)
return true;
return memcmp(str1.Buffer(), str2, len) != 0;
}
inline bool operator!= (const char *str1, const cTBString &str2) {
uint len = strlen(str1);
if (len != str2.Length())
return true;
return memcmp(str1, str2.Buffer(), len) != 0;
}
inline bool operator< (const cTBString &str1, const cTBString &str2) {
int ret = memcmp(str1.Buffer(), str2.Buffer(), str1.Length() < str2.Length() ? str1.Length() : str2.Length());
if ((ret < 0) || ((ret == 0) && (str1.Length() < str2.Length())))
return true;
return false;
}
inline bool operator< (const cTBString &str1, const char *str2) {
uint len = strlen(str2);
int ret = memcmp(str1.Buffer(), str2, str1.Length() < len ? str1.Length() : len);
if ((ret < 0) || ((ret == 0) && (str1.Length() < len)))
return true;
return false;
}
inline bool operator< (const char *str1, const cTBString &str2) {
uint len = strlen(str1);
int ret = memcmp(str1, str2.Buffer(), len < str2.Length() ? len : str2.Length());
if ((ret < 0) || ((ret == 0) && (len < str2.Length())))
return true;
return false;
}
inline bool operator> (const cTBString &str1, const cTBString &str2) {
int ret = memcmp(str1.Buffer(), str2.Buffer(), str1.Length() < str2.Length() ? str1.Length() : str2.Length());
if ((ret > 0) || ((ret == 0) && (str1.Length() < str2.Length())))
return true;
return false;
}
inline bool operator> (const cTBString &str1, const char *str2) {
uint len = strlen(str2);
int ret = memcmp(str1.Buffer(), str2, str1.Length() < len ? str1.Length() : len);
if ((ret > 0) || ((ret == 0) && (str1.Length() < len)))
return true;
return false;
}
inline bool operator> (const char *str1, const cTBString &str2) {
uint len = strlen(str1);
int ret = memcmp(str1, str2.Buffer(), len < str2.Length() ? len : str2.Length());
if ((ret > 0) || ((ret == 0) && (len < str2.Length())))
return true;
return false;
}
inline bool operator<= (const cTBString &str1, const cTBString &str2) {
int ret = memcmp(str1.Buffer(), str2.Buffer(), str1.Length() < str2.Length() ? str1.Length() : str2.Length());
if ((ret < 0) || ((ret == 0) && (str1.Length() <= str2.Length())))
return true;
return false;
}
inline bool operator<= (const cTBString &str1, const char *str2) {
uint len = strlen(str2);
int ret = memcmp(str1.Buffer(), str2, str1.Length() < len ? str1.Length() : len);
if ((ret < 0) || ((ret == 0) && (str1.Length() <= len)))
return true;
return false;
}
inline bool operator<= (const char *str1, const cTBString &str2) {
uint len = strlen(str1);
int ret = memcmp(str1, str2.Buffer(), len < str2.Length() ? len : str2.Length());
if ((ret < 0) || ((ret == 0) && (len <= str2.Length())))
return true;
return false;
}
inline bool operator>= (const cTBString &str1, const cTBString &str2) {
int ret = memcmp(str1.Buffer(), str2.Buffer(), str1.Length() < str2.Length() ? str1.Length() : str2.Length());
if ((ret > 0) || ((ret == 0) && (str1.Length() >= str2.Length())))
return true;
return false;
}
inline bool operator>= (const cTBString &str1, const char *str2) {
uint len = strlen(str2);
int ret = memcmp(str1.Buffer(), str2, str1.Length() < len ? str1.Length() : len);
if ((ret > 0) || ((ret == 0) && (str1.Length() >= len)))
return true;
return false;
}
inline bool operator>= (const char *str1, const cTBString &str2) {
uint len = strlen(str1);
int ret = memcmp(str1, str2.Buffer(), len < str2.Length() ? len : str2.Length());
if ((ret > 0) || ((ret == 0) && (len >= str2.Length())))
return true;
return false;
}
#endif // TOOLBOX_STRING_H

12
tools/tools.c Normal file
View File

@@ -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;
}

67
tools/tools.h Normal file
View File

@@ -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