summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Handle.cc21
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/Handle.cc b/lib/Handle.cc
index e8ac1d5..457f2c9 100644
--- a/lib/Handle.cc
+++ b/lib/Handle.cc
@@ -463,6 +463,9 @@ ssize_t Handle::uread(void * buf, size_t count) {
#ifdef DEBUG
printm(M_BARE, String(_("Performing gzread of ")) + count + _(" byte(s) for handle ") + h + "\n");
#endif
+ ssize_t msize = GetSize();
+ if ((msize >= 0) && ((count + itell) >= msize))
+ count = msize - itell;
int err = gzread(zfile, buf, count);
if (err == -1) {
throw GeneralException(String("Error reading zstream: ") + gzerror(zfile, &err));
@@ -503,7 +506,23 @@ bool Handle::CanSeek() const {
off_t Handle::seek(off_t offset, int whence) throw(GeneralException) {
if (z) {
- return itell = gzseek(zfile, offset, whence);
+ ssize_t msize = GetSize();
+ if (msize >= 0) {
+ switch (whence) {
+ case SEEK_CUR:
+ offset += itell;
+ break;
+ case SEEK_END:
+ offset += msize;
+ break;
+ }
+ return itell = gzseek(zfile, offset, SEEK_SET);
+ } else {
+ if (whence == SEEK_END) {
+ throw IOGeneral("zlib can't seek from the end on a stream.");
+ }
+ return itell = gzseek(zfile, offset, whence);
+ }
} else {
throw IOGeneral(_("Handle ") + GetName() + _(" can't seek"));
}