size_t StandardFile::readData(File::Byte* buffer,size_t bufferSize) { /* Check if file needs to be repositioned: */ if(filePos!=readPos) if(lseek64(fd,readPos,SEEK_SET)<0) throw SeekError(readPos); /* Read more data from source: */ ssize_t readResult; do { readResult=::read(fd,buffer,bufferSize); } while(readResult<0&&(errno==EAGAIN||errno==EWOULDBLOCK||errno==EINTR)); /* Handle the result from the read call: */ if(readResult<0) { /* Unknown error; probably a bad thing: */ throw Error(Misc::printStdErrMsg("IO::StandardFile: Fatal error %d while reading from file",int(errno))); } /* Advance the read pointer: */ readPos+=readResult; filePos=readPos; return size_t(readResult); }
void StandardFile::writeData(const File::Byte* buffer,size_t bufferSize) { /* Check if file needs to be repositioned: */ if(filePos!=writePos) if(lseek64(fd,writePos,SEEK_SET)<0) throw SeekError(writePos); /* Invalidate the read buffer to prevent reading stale data: */ flushReadBuffer(); /* Write all data in the given buffer: */ while(bufferSize>0) { ssize_t writeResult=::write(fd,buffer,bufferSize); if(writeResult>0) { /* Prepare to write more data: */ buffer+=writeResult; bufferSize-=writeResult; /* Advance the write pointer: */ writePos+=writeResult; filePos=writePos; } else if(writeResult<0&&(errno==EAGAIN||errno==EWOULDBLOCK||errno==EINTR)) { /* Do nothing */ } else if(writeResult==0) { /* Sink has reached end-of-file: */ throw WriteError(bufferSize); } else { /* Unknown error; probably a bad thing: */ throw Error(Misc::printStdErrMsg("IO::StandardFile: Fatal error %d while writing to file",int(errno))); } } }
size_t SeekableFilter::readData(File::Byte* buffer,size_t bufferSize) { /* Check if the file position needs to be moved to the read position: */ if(filePos!=readPos) { if(readPos>filePos) { /* Skip forward in buffer chain from the current position: */ currentPos+=(readPos-filePos); /* Skip buffers until the current buffer offset is within the current buffer: */ while(currentPos>Offset(current->size)) { /* Check if there is a next buffer: */ if(current->succ!=0) { /* Go to the next buffer: */ currentPos-=current->size; current=current->succ; } else { /* Check for end-of-file: */ if(source->eof()) throw SeekError(readPos); /* Read more data: */ readFromSource(); } } } else { /* Skip from the beginning of the buffer chain: */ current=head; currentPos=readPos; /* Skip buffers until the current buffer offset is within the current buffer: */ while(currentPos>Offset(current->size)) { /* Go to the next buffer: */ currentPos-=current->size; current=current->succ; } } /* Update the file position: */ filePos=readPos; } /* Check if the file position is at the end of the read data: */ if(filePos==totalReadSize) { /* Check for end-of-file: */ if(source->eof()) return 0; /* Read more data: */ readFromSource(); } /* Read from the current file position: */ if(currentPos==Offset(current->size)) { /* Go to the next buffer: */ current=current->succ; currentPos=0; } size_t copySize=current->size-size_t(currentPos); setReadBuffer(copySize,reinterpret_cast<Byte*>(current+1)+currentPos,false); readPos+=copySize; filePos+=copySize; currentPos+=copySize; return copySize; }