/** * relative seek **/ ::std::streampos seekoff(::std::streamoff off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) { // absolute seek if ( way == ::std::ios_base::beg ) { return seekpos(off,which); } // seek relative to current position else if ( way == ::std::ios_base::cur ) { if ( which == std::ios_base::in ) { return seekpos(readpos + (gptr()-eback()),which); } else if ( which == std::ios_base::out ) { return seekpos(writepos + (pptr()-pbase()),which); } else { return -1; } } // seek relative to end of file else if ( way == ::std::ios_base::end ) { off_t const endoff = fd->getFileSize(); return seekpos(endoff+off,which); } else { return -1; } }
// seek off_t doSeek(int64_t const p, int const whence) { off_t off = static_cast<off_t>(-1); while ( (off=fd->lseek(p,whence)) == static_cast<off_t>(-1) ) { int const error = errno; switch ( error ) { case EINTR: case EAGAIN: // try again break; default: { libmaus2::exception::LibMausException se; se.getStream() << "PosixInputOutputStreamBuffer::doSeek(): seek() failed: " << strerror(error) << std::endl; se.finish(); throw se; } } } return off; }
size_t doRead(char * buffer, size_t count) { ssize_t r = -1; while ( (r=fd->read(buffer,count)) < 0 ) { int const error = errno; switch ( error ) { case EINTR: case EAGAIN: // try again break; default: { libmaus2::exception::LibMausException se; se.getStream() << "PosixInputOutputStreamBuffer::doRead(): read() failed: " << strerror(error) << std::endl; se.finish(); throw se; } } } return r; }
void init(bool const repos) { // set empty buffer setgchecked(buffer.end(), buffer.end(), buffer.end()); // seek if ( repos ) fd->lseek(symsread,SEEK_SET); }
MemoryInputStreamBuffer( std::string const & rfn, int64_t const rblocksize, uint64_t const rputbackspace = 0 ) : fd(doOpen(rfn)), filesize(fd->getFileSize()), blocksize((rblocksize < 0) ? getDefaultBlockSize() : rblocksize), putbackspace(rputbackspace), buffer(putbackspace + blocksize,false), symsread(0) { init(false); }
// write buffer contents void doSync() { uint64_t n = pptr()-pbase(); pbump(-n); char * p = pbase(); while ( n ) { ssize_t const w = fd->write(p,n); if ( w < 0 ) { int const error = errno; switch ( error ) { case EINTR: case EAGAIN: break; default: { libmaus2::exception::LibMausException se; se.getStream() << "PosixInputOutputStreamBuffer::doSync(): write() failed: " << strerror(error) << std::endl; se.finish(); throw se; } } } else { assert ( w <= static_cast<int64_t>(n) ); n -= w; writepos += w; } } assert ( ! n ); }
int_type underflow() { // if there is still data, then return it if ( gptr() < egptr() ) return static_cast<int_type>(*uptr()); assert ( gptr() == egptr() ); // number of bytes for putback buffer uint64_t const putbackcopy = std::min( static_cast<uint64_t>(gptr() - eback()), putbackspace ); // copy bytes std::copy( gptr()-putbackcopy, gptr(), buffer.begin() + putbackspace - putbackcopy ); // load data uint64_t const uncompressedsize = fd->read( buffer.begin()+putbackspace, buffer.size()-putbackspace ); // set buffer pointers setgchecked( buffer.begin()+putbackspace-putbackcopy, buffer.begin()+putbackspace, buffer.begin()+putbackspace+uncompressedsize); symsread += uncompressedsize; if ( uncompressedsize ) return static_cast<int_type>(*uptr()); else return traits_type::eof(); }