📄 wyregfile.cpp
字号:
/* Copyright is licensed under GNU LGPL. by I.J.Wang 2003 documentation is in file wyregfile.3wy*/#define WYLIB_SOURCE#include "wyregfile.h"#include "wy_atdestroy.h"#include <unistd.h>#include <sys/types.h>#include <cstring>#include <memory> // for new#include <typeinfo>const char WyRegFile::class_name[]="WyRegFile";Wy__FtBits WyRegFile::cftbits(void) WY__NOTHROW__{ static const Wy__FtBits fb( Wy__FtBits(S_IFREG) ); return(fb);};off_t wyc_lseek(int fd, off_t offset, int whence){ return ::lseek(fd,offset,whence);};int wyc_ftruncate(int fd, off_t length){ return ::ftruncate(fd,length);};int wyc_mkstemp(char *temp){ return ::mkstemp(temp);};WyRet WyRegFile::wy_pread(Wy__TypeFD fd, void *buf, size_t count, size_t& n_read, off_t pos){ n_read=0; #ifdef __GLIBC__ // man. says unspecified results, guess specific for glib if(count>size_t(std::numeric_limits<ssize_t>::max())) { WY_RETURN(Wym_EFBIG); }#endif WY__CANCEL_POINT; ssize_t v=::pread(fd,buf,count,pos); if(v>=0) { n_read=v; if(size_t(v)>count) { WY_THROW( WyRet(Wym_EIO) ); } WY__CANCEL_POINT; return(Ok); } else { WY__CANCEL_POINT; WY_RETURN(errno); } // UNREACHABLE};WyRet WyRegFile::wy_max_pread(Wy__TypeFD fd, void *buf, size_t count, size_t& n_read, off_t pos){ n_read=0; size_t btr( count ); off_t rpos( pos ); char *bptr( static_cast<char*>(buf) ); while(btr>0) { WY__CANCEL_POINT; ssize_t n( ::pread(fd,bptr,btr,rpos) ); if(n<=0) { if(n==0) { break; // EOF } else { WY__CANCEL_POINT; WY_RETURN(errno); } } n_read+=n; #ifndef NDEBUG if(size_t(n)>btr) { WY_TERMINATE(""); } #endif rpos+=n; bptr+=n; btr-=n; } WY__CANCEL_POINT; return(Ok);};WyRet WyRegFile::wy_pwrite(Wy__TypeFD fd, const void *buf, size_t count, size_t &n_written,off_t pos){ n_written=0; WY__CANCEL_POINT; ssize_t v=::pwrite(fd,buf,count,pos); if(v>=0) { n_written=v; if(size_t(v)>count) { WY_THROW( WyRet(Wym_EIO) ); } WY__CANCEL_POINT; return(Ok); } else { WY__CANCEL_POINT; WY_RETURN(errno); } // UNREACHABLE};//-----------------------------------------------------------------------------WyRegFile::WyRegFile() try : WyByteFlow(cftbits()), _pos(DefaultPos) {}catch(const WyByteFlow::Reply& e) { WY_THROW( Reply(e) );}catch(const WyRet& e) { WY_THROW( WyRet(e) );};WyRegFile::WyRegFile(WyFileHandle fh)try : WyByteFlow(fh,cftbits()), _pos(DefaultPos) {}catch(const WyByteFlow::Reply& e) { WY_THROW( Reply(e) );}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_THROW( WyRet(e) );};WyRegFile::WyRegFile(const WySysFile& regf)try : WyByteFlow(regf,cftbits()), _pos(DefaultPos) { const WyRegFile* p=dynamic_cast<const WyRegFile*>(®f); if(p!=0) { // Argument object may actually associate to a regular file, but whose r/w // position is considered random. We could probably just see if it is // WyRegFile. _pos=p->_pos; }}catch(const WyByteFlow::Reply& e) { WY_THROW( Reply(e) );}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_THROW( WyRet(e) );};WyRegFile::WyRegFile(const char* pathname,int f)try : WyByteFlow(pathname,f,cftbits()), _pos(DefaultPos) {}catch(const WyByteFlow::Reply& e) { WY_THROW( Reply(e) );}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_THROW( WyRet(e) );};WyRegFile::WyRegFile(const WyStr& pathname,int f)try : WyByteFlow(pathname,f,cftbits()), _pos(DefaultPos) {}catch(const WyByteFlow::Reply& e) { WY_THROW( Reply(e) );}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_THROW( WyRet(e) );};WyRegFile::WyRegFile(const WyRegFile ®f)try : WyByteFlow(regf,cftbits()), _pos(regf._pos) {}catch(const WyByteFlow::Reply& e) { WY_THROW( Reply(e) );}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_THROW( WyRet(e) );};WyRegFile::WyRegFile(WyRegFile& regf, Wy::ByMove_t) WY__TSPC() : WyByteFlow(regf,Wy::ByMove), _pos(regf._pos){};WyRet WyRegFile::reset(void){ _pos=DefaultPos; const WyRet r(WyByteFlow::reset()); if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WyRegFile::reset(WyFileHandle fh){ const WyRet r( WyByteFlow::reset(fh) ); if(r!=Ok) { WY_RETURN(r); } _pos=DefaultPos; return(Ok);};WyRet WyRegFile::reset(const WySysFile& regf){ const WyRet r( WyByteFlow::reset(regf) ); if(r!=Ok) { WY_RETURN(r); } const WyRegFile* ptr(dynamic_cast<const WyRegFile*>(®f)); if(ptr==0) { _pos=DefaultPos; } else { _pos=ptr->pos(); } return(Ok);};WyRet WyRegFile::reset(const char* pathname,int f){ const WyRet r( WyByteFlow::reset(pathname,f) ); if(r!=Ok) { WY_RETURN(r); } _pos=DefaultPos; return(Ok);};WyRet WyRegFile::reset(const WyStr& pathname,int f){ const WyRet r( WyByteFlow::reset(pathname,f) ); if(r!=Ok) { WY_RETURN(r); } _pos=DefaultPos; return(Ok);};WyRet WyRegFile::_swap(WySysFile& regf) WY__TSPC(){ const WyRet r( WyByteFlow::_swap(regf) ); if(r!=Ok) { WY_RETURN(r); } Wy__Base::vswap(_pos,dynamic_cast<WyRegFile&>(regf)._pos); return(Ok);};WyRegFile* WyRegFile::_alloc(WyRet& r) consttry { if(WY__EQU_TYPEID(*this,WyRegFile)==false) { r=Wym_ENOSYS; WY_HERE(r); // _alloc not overridden return(NULL); } WyRegFile* p=new(std::nothrow) WyRegFile(); if(p==NULL) { r=Wym_ENOMEM; WY_HERE(r); } else { r=Ok; } return(p);}catch(const Reply& e) { r=e; WY_HERE(r); return(NULL);}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_THROW( WyRet(e) );};WyRet WyRegFile::read(void *buf, size_t count, size_t& n_read){ WyRet r; try { r= WyRegFile::wy_pread(this->wy_fd(),buf,count,n_read,_pos); } catch(...) { _pos+=n_read; throw; } _pos+=n_read; if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WyRegFile::read(WyStr& buf, size_t count, size_t& n_read){ n_read=0; const size_t org_size=buf.size(); const size_t mr_size=org_size+count; if(mr_size<org_size) { WY_RETURN(Wym_EFBIG); // value overflow } WyRet r( buf._reserve(mr_size) ); // expand capacity for the read if(r!=Ok) { WY_RETURN(r); } try { r=WyRegFile::wy_pread(this->wy_fd(),&buf[org_size],count,n_read,_pos); } catch(...) { _pos+=n_read; buf._setsize(org_size+n_read); throw; }; _pos+=n_read; buf._setsize(org_size+n_read); if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WyRegFile::_read_till(void *buf, size_t count, size_t &n_read, char c){ n_read=0; // Read count bytes into buf // WyRet r; size_t b_rd; // Read count bytes (full) r=wy_pread(this->wy_fd(),buf,count,b_rd,_pos); if(r!=Ok) { WY_RETURN(r); // buf may have modified } if(b_rd==0) { return(Ok); // EOF } // Scan for char c (argument) and set r/w position // char *sptr=static_cast<char *>(std::memchr(buf,c,b_rd)); if(sptr==NULL) { // the char not found, output all the data read n_read=b_rd; _pos+=b_rd; return(Ok); } ++sptr; // set n_read to byte until the char (including) and update _pos _pos+= n_read=sptr-static_cast<char* const>(buf); return(Ok);};WyRet WyRegFile::_read_till(WyStr& buf, size_t count, size_t& n_read,char c){ n_read=0; const size_t org_size=buf.size(); const size_t mr_size=org_size+count; if(mr_size<org_size) { WY_RETURN(Wym_EFBIG); // value overflow } WyRet r; if((r=buf._reserve(mr_size))!=Ok) { // expand capacity for the read WY_RETURN(r); } try { r=WyRegFile::_read_till(&buf[org_size],count,n_read,c); } catch(...) { buf._setsize(org_size+n_read); // data in buf is unspecified while stack // unwound. Implement conveys the // n_read setup of underlying function throw; }; buf._setsize(org_size+n_read); if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WyRegFile::write(const void *buf, size_t count, size_t& n_written){ const WyRet r( WyRegFile::wy_pwrite(this->wy_fd(),buf,count,n_written,_pos) ); if(r!=Ok) { WY_RETURN(r); } _pos+=n_written; return(Ok);};WyRet WyRegFile::write(WyCSeg buf, size_t& n_written){ const WyRet r=WyRegFile::wy_pwrite(this->wy_fd(),buf.begin(),buf.size(),n_written,_pos); if(r!=Ok) { WY_RETURN(r); } _pos+=n_written; return(Ok);};WyRet WyRegFile::write(const WyStr& buf, size_t& n_written){ const WyRet r=WyRegFile::wy_pwrite(this->wy_fd(),buf.data(),buf.size(),n_written,_pos); if(r!=Ok) { WY_RETURN(r); } _pos+=n_written; return(Ok);};/*WyRet WyRegFile::drain(void){ const int v=wyc_fdatasync(wy_fd()); if(v==-1) { WY_RETURN(errno); } return(Ok);};*/off_t WyRegFile::pos(void) const{ return _pos; };void WyRegFile::set_pos(off_t ofst) { if(this->is_default()) { return; } _pos=ofst; };WyRet WyRegFile::seek_end(void){ const off_t v=wyc_lseek(this->wy_fd(),0,SEEK_END); if(v==(off_t)-1) { WY_RETURN(errno); } _pos=v; return(Ok);};WyRet WyRegFile::resize(off_t length){ const int v( wyc_ftruncate(this->wy_fd(),length) ); if(v==-1) { WY_RETURN(errno); } return(Ok);};WyRet WyRegFile::fsync(void){ const WyRet r( WyByteFlow::_fsync() ); if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WyRegFile::fdatasync(void){ const WyRet r( WyByteFlow::_fdatasync() ); if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WyRegFile::create(WyRegFile& regf,const char* pathname,int f,mode_t m){ const int v( wyc_open(pathname,f|O_CREAT,m) ); if(v==-1) { WY_RETURN(errno); } Wy_AtDestroy<int,const Wy__TypeFD&> rrad_v(WySysFile::wy_close,v); const WyRet r( regf.reset( WyFileHandle(v) ) ); if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WyRegFile::create(WyRegFile& regf,const WyStr& pathname,int f,mode_t m){ const int v( wyc_open(pathname.c_str(),f|O_CREAT,m) ); if(v==-1) { WY_RETURN(errno); } Wy_AtDestroy<int,const Wy__TypeFD&> rrad_v(WySysFile::wy_close,v); const WyRet r( regf.reset( WyFileHandle(v) ) ); if(r!=Ok) { WY_RETURN(r); } return(Ok);};WyRet WyRegFile::create_tmpfile(WyRegFile& regf,WyStr& temp_name)try { WyRet r; WyStr nbuf(temp_name); const size_t nsiz=nbuf.size(); // append six 'X'es if((r=nbuf.resize(nsiz+sizeof(char[6]),char('X')))!=Ok) { if(r==Wym_EFBIG) { r=Wym_ENAMETOOLONG; } WY_RETURN(r); } nbuf.c_str(); // c_str to ensure a trailing zero char* nptr( &nbuf[0] ); // point to the same buffer const int v=wyc_mkstemp(nptr); if(v==-1) { WY_RETURN(errno); } if((r=regf.reset( WyFileHandle(v) ))!=Ok) { WY_RETURN(r); } nbuf.swap(temp_name); return(Ok);}catch(const WyStr::Reply& e) { WY_RETURN(e);}catch(const WyRet& e) { WY_NDEBUG_MSG(e); WY_RETURN(e);};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -