📄 piobase.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 + -