diff --git a/src/file.cpp b/src/file.cpp index d2918700..b9436c0f 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -69,7 +69,7 @@ void File::unlink(const char *name) **************************************************************************/ FileBase::FileBase() : - _fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL) + _fd(-1), _flags(0), _shflags(0), _mode(0), _name(NULL), _offset(0), _length(0) { memset(&st,0,sizeof(st)); } @@ -104,6 +104,8 @@ void FileBase::sopen() assert(0); #endif } + ::fstat(_fd, &st); + _length = st.st_size; } @@ -117,6 +119,8 @@ bool FileBase::close() _flags = 0; _mode = 0; _name = NULL; + _offset = 0; + _length = 0; return ok; } @@ -164,10 +168,17 @@ void FileBase::seek(off_t off, int whence) { if (!isOpen()) throwIOException("bad seek 1"); - if (whence == SEEK_SET && off < 0) - throwIOException("bad seek 2"); - if (whence == SEEK_END && off > 0) - throwIOException("bad seek 3"); + if (whence == SEEK_SET) { + if (off < 0) + throwIOException("bad seek 2"); + off += _offset; + } + if (whence == SEEK_END) { + if (off > 0) + throwIOException("bad seek 3"); + off += _length; + whence = SEEK_SET; + } if (::lseek(_fd,off,whence) < 0) throwIOException("seek error",errno); } @@ -180,7 +191,19 @@ off_t FileBase::tell() const off_t l = ::lseek(_fd, 0, SEEK_CUR); if (l < 0) throwIOException("tell error",errno); - return l; + return l - _offset; +} + + +void FileBase::set_extent(off_t offset, off_t length) +{ + _offset = offset; + _length = length; +} + +off_t FileBase::st_size() const +{ + return _length; } @@ -205,6 +228,8 @@ void InputFile::sopen(const char *name, int flags, int shflags) _flags = flags; _shflags = shflags; _mode = 0; + _offset = 0; + _length = 0; FileBase::sopen(); if (!isOpen()) { @@ -289,6 +314,8 @@ void OutputFile::sopen(const char *name, int flags, int shflags, int mode) _flags = flags; _shflags = shflags; _mode = mode; + _offset = 0; + _length = 0; FileBase::sopen(); if (!isOpen()) { @@ -316,6 +343,8 @@ bool OutputFile::openStdout(int flags, bool force) _flags = flags; _shflags = -1; _mode = 0; + _offset = 0; + _length = 0; if (flags && acc_set_binmode(fd, 1) == -1) throwIOException(_name, errno); _fd = fd; diff --git a/src/file.h b/src/file.h index 6cef361c..9910dc35 100644 --- a/src/file.h +++ b/src/file.h @@ -59,6 +59,7 @@ public: virtual bool isOpen() const { return _fd >= 0; } int getFd() const { return _fd; } const char *getName() const { return _name; } + virtual off_t st_size() const; // { return _length; } protected: void sopen(); @@ -67,12 +68,15 @@ protected: virtual void write(const void *buf, int len); virtual void seek(off_t off, int whence); virtual off_t tell() const; + virtual void set_extent(off_t offset, off_t length); int _fd; int _flags; int _shflags; int _mode; const char *_name; + off_t _offset; + off_t _length; public: struct stat st; }; diff --git a/src/packer.cpp b/src/packer.cpp index 8e5f9de0..7ca8b1e8 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -46,7 +46,7 @@ Packer::Packer(InputFile *f) : last_patch(NULL), last_patch_len(0), last_patch_off(0) { if (fi != NULL) - file_size = fi->st.st_size; + file_size = fi->st_size(); uip = new UiPacker(this); memset(&ph, 0, sizeof(ph)); }