⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 piobase.cxx

📁 PTypes (C++ Portable Types Library) is a simple alternative to the STL that includes multithreading
💻 CXX
字号:
/* * *  C++ Portable Types Library (PTypes) *  Version 1.7.5   Released 9-Mar-2003 * *  Copyright (c) 2001, 2002, 2003 Hovik Melikyan * *  http://www.melikyan.com/ptypes/ *  http://ptypes.sourceforge.net/ * */#include <errno.h>#ifdef WIN32#  include <windows.h>#else#  include <signal.h>#  include <unistd.h>#endif#include "pstreams.h"#include "pasync.h"     // for pexchange()PTYPES_BEGIN/*Known UNIX error codes:EPERM         1          Not ownerENOENT        2          No such file or directoryESRCH         3          No such processEINTR         4          Interrupted system callEIO           5          I/O errorENXIO         6          No such device or addressE2BIG         7          Argument list too longENOEXEC       8          Exec format errorEBADF         9          Bad file numberECHILD       10          No spawned processesEAGAIN       11          No more processes; not enough memory; maximum nesting level reachedENOMEM       12          Not enough memoryEACCES       13          Permission deniedEFAULT       14          Bad addressENOTBLK      15          Block device requiredEBUSY        16          Mount device busyEEXIST       17          File existsEXDEV        18          Cross-device linkENODEV       19          No such deviceENOTDIR      20          Not a directoryEISDIR       21          Is a directoryEINVAL       22          Invalid argumentENFILE       23          File table overflowEMFILE       24          Too many open filesENOTTY       25          Not a teletypeETXTBSY      26          Text file busyEFBIG        27          File too largeENOSPC       28          No space left on deviceESPIPE       29          Illegal seekEROFS        30          Read-only file systemEMLINK       31          Too many linksEPIPE        32          Broken pipeEDOM         33          Math argumentERANGE       34          Result too largeEUCLEAN      35          File system needs cleaningEDEADLK      36          Resource deadlock would occurEDEADLOCK    36          Resource deadlock would occur*/#ifndef WIN32static class _io_init{public:    _io_init();} _init;_io_init::_io_init(){    // We don't like broken pipes. PTypes will throw an exception instead.    signal(SIGPIPE, SIG_IGN);}#endifint unixerrno() {#ifdef WIN32    switch(GetLastError())     {    case ERROR_FILE_NOT_FOUND:    case ERROR_PATH_NOT_FOUND:      return ENOENT;    case ERROR_TOO_MANY_OPEN_FILES: return EMFILE;    case ERROR_ACCESS_DENIED:    case ERROR_SHARING_VIOLATION:   return EACCES;    case ERROR_INVALID_HANDLE:      return EBADF;    case ERROR_NOT_ENOUGH_MEMORY:    case ERROR_OUTOFMEMORY:         return ENOMEM;    case ERROR_INVALID_DRIVE:       return ENODEV;    case ERROR_WRITE_PROTECT:       return EROFS;    case ERROR_FILE_EXISTS:         return EEXIST;    case ERROR_BROKEN_PIPE:         return EPIPE;    case ERROR_DISK_FULL:           return ENOSPC;    case ERROR_SEEK_ON_DEVICE:      return ESPIPE;    default: return EIO;    }#else    return errno;#endif}//// This function gives error messages for most frequently raising // IO errors. If the function returns NULL a generic message// can be given, e.g. "I/O error". See also iobase::get_errormsg()//const char* unixerrmsg(int code){    switch(code)     {    case EBADF:  return "Invalid file descriptor";    case ESPIPE: return "Can not seek on this device";    case ENOENT: return "No such file or directory";    case EMFILE: return "Too many open files";    case EACCES: return "Access denied";    case ENOMEM: return "Not enough memory";    case ENODEV: return "No such device";    case EROFS:  return "Read-only file system";    case EEXIST: return "File already exists";    case ENOSPC: return "Disk full";    case EPIPE:  return "Broken pipe";    default: return nil;    }}estream::estream(iobase* ierrstm, int icode, const char* imsg)    : exceptobj(imsg), code(icode), errstm(ierrstm) {}estream::estream(iobase* ierrstm, int icode, const string& imsg)    : exceptobj(imsg), code(icode), errstm(ierrstm) {}estream::~estream() {}int defbufsize = 8192;int stmbalance = 0;iobase::iobase(int ibufsize)    : component(), active(false), cancelled(false), eof(true),       handle(invhandle), abspos(0), bufsize(0), bufdata(nil), bufpos(0), bufend(0),      stmerrno(0), deferrormsg(), status(IO_CREATED), onstatus(nil) {    if (ibufsize < 0)        bufsize = defbufsize;    else        bufsize = ibufsize;}iobase::~iobase() {}void iobase::bufalloc() {    if (bufdata != nil)	fatal(CRIT_FIRST + 13, "(ptypes internal) invalid buffer allocation");    bufdata = (char*)memalloc(bufsize);}void iobase::buffree() {    bufclear();    memfree(bufdata);    bufdata = 0;}void iobase::chstat(int newstat) {    status = newstat;    if (onstatus != nil)        (*onstatus)(this, newstat);}void iobase::error(int code, const char* defmsg) {    eof = true;    stmerrno = code;    deferrormsg = defmsg;    throw new estream(this, code, get_errormsg());}void iobase::errstminactive() {    error(EIO, "Stream inactive");}void iobase::errbufrequired(){    fatal(CRIT_FIRST + 11, "Internal: buffer required");}void iobase::open() {    cancel();    chstat(IO_OPENING);    abspos = 0;    cancelled = false;    eof = false;    stmerrno = 0;    clear(deferrormsg);    active = true;    stmbalance++;    bufalloc();    doopen();    chstat(IO_OPENED);}void iobase::close() {    if (!active)        return;    stmbalance--;    try     {        if (bufsize > 0 && !cancelled)            flush();        doclose();    }    catch(estream* e)     {        delete e;    }    buffree();    active = false;    eof = true;    chstat(IO_CLOSED);}void iobase::cancel() {    cancelled = true;    close();}int iobase::seek(int newpos, ioseekmode mode) {    if (!active)        errstminactive();    flush();    int ret = doseek(newpos, mode);    if (ret < 0)        error(ESPIPE, "Seek failed");    bufclear();    eof = false;    abspos = ret;    return ret;}void iobase::flush() {}int iobase::doseek(int newpos, ioseekmode mode){    if (handle == invhandle)    {        error(ESPIPE, "Can't seek on this device");        return -1;    }#ifdef WIN32    static int wmode[3] = {FILE_BEGIN, FILE_CURRENT, FILE_END};    return SetFilePointer(HANDLE(handle), newpos, nil, wmode[mode]);#else    static int umode[3] = {SEEK_SET, SEEK_CUR, SEEK_END};    return lseek(handle, newpos, umode[mode]);#endif}void iobase::doclose(){#ifdef WIN32    CloseHandle(HANDLE(pexchange(&handle, invhandle)));#else    ::close(pexchange(&handle, invhandle));#endif}void iobase::set_active(bool newval) {    if (newval != active)        if (newval)            open();        else            close();}void iobase::set_bufsize(int newval) {    if (active)        fatal(CRIT_FIRST + 12, "Cannot change buffer size while stream is active");    if (newval < 0)        bufsize = defbufsize;    else        bufsize = newval;}string iobase::get_errstmname() {    return get_streamname();}const char* iobase::uerrmsg(int code){    return unixerrmsg(code);}int iobase::uerrno(){    return unixerrno();}string iobase::get_errormsg() {    string s = uerrmsg(stmerrno);    if (isempty(s))        s = deferrormsg;    if (pos('[', s) >= 0 && *(pconst(s) + length(s) - 1) == ']')        return s;    string e = get_errstmname();    if (isempty(e))        return s;    return s + " [" + e + ']';}PTYPES_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -