#ifndef _H_UNIXPLUSPLUS
#define _H_UNIXPLUSPLUS
#include <Security/utilities.h>
#include "timeflow.h"
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <cstdio>
#include <cstdarg>
#include <map>
namespace Security {
namespace UnixPlusPlus {
class FileDesc {
protected:
static const int invalidFd = -1;
void setFd(int fd) { mFd = fd; mAtEnd = false; }
static void checkError(int result) { if (result == -1) UnixError::throwMe(); }
void checkSetFd(int fd) { checkError(fd); mFd = fd; mAtEnd = false; }
public:
FileDesc() : mFd(invalidFd), mAtEnd(false) { }
FileDesc(int fd) : mFd(fd), mAtEnd(false) { }
FileDesc(const char *path, int flag = O_RDONLY, mode_t mode = 0666) : mFd(invalidFd)
{ open(path, flag, mode); }
FileDesc &operator = (int fd) { mFd = fd; mAtEnd = false; return *this; }
FileDesc &operator = (const FileDesc &fd) { mFd = fd.mFd; mAtEnd = fd.mAtEnd; return *this; }
bool isOpen() const { return mFd != invalidFd; }
operator bool() const { return isOpen(); }
int fd() const { return mFd; }
operator int() const { return fd(); }
void clear() { mFd = invalidFd; }
void close();
void open(const char *path, int flag = O_RDONLY, mode_t mode = 0666);
size_t read(void *addr, size_t length);
size_t write(const void *addr, size_t length);
bool atEnd() const { return mAtEnd; }
off_t seek(off_t position, int whence = SEEK_SET);
void *mmap(int prot = PROT_READ, size_t length = 0, int flags = MAP_FILE,
off_t offset = 0, void *addr = NULL);
int fcntl(int cmd, int arg = 0) const;
int fcntl(int cmd, void *arg) const;
int flags() const;
void flags(int flags) const;
void setFlag(int flag, bool on = true) const;
void clearFlag(int flag) const { setFlag(flag, false); }
int ioctl(int cmd, void *arg) const;
template <class Arg> Arg iocget(int cmd) const
{ Arg arg; ioctl(cmd, &arg); return arg; }
template <class Arg> void iocget(int cmd, Arg &arg) const
{ ioctl(cmd, &arg); }
template <class Arg> void iocset(int cmd, const Arg &arg)
{ ioctl(cmd, const_cast<Arg *>(&arg)); }
typedef struct stat UnixStat;
void fstat(UnixStat &st) const;
size_t fileSize() const;
FILE *fdopen(const char *mode = NULL);
private:
int mFd;
protected:
bool mAtEnd; };
} }
#endif //_H_UNIXPLUSPLUS