diff options
Diffstat (limited to 'lib/Handle.cc')
-rw-r--r-- | lib/Handle.cc | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/lib/Handle.cc b/lib/Handle.cc index e3ed198..7bd9e37 100644 --- a/lib/Handle.cc +++ b/lib/Handle.cc @@ -20,6 +20,10 @@ #include "Handle.h" #include "gettext.h" +enum { + DEFLATE, INFLATE; +} + Handle::Handle(const Handle & nh) : itell(0), h(nh.h >= 0 ? dup(nh.h) : nh.h), closed(nh.closed), nonblock(nh.closed), zfile(0), z(0) { #ifdef DEBUG @@ -184,8 +188,27 @@ void Handle::close() throw (GeneralException) { return; } + Flush(); + if (h >= 0) { - if (z) { + if (z >= 10) { + int err; + if (c == DEFLATE) { + err = deflateEnd(&zstrm); + if (err != Z_OK) { + throw (String(_("Error during deflateEnd: ")) + zstrm.msg); + } + } else { + err = inflateEnd(&zstrm); + if (err != Z_OK) { + throw (String(_("Error during inflateEnd: ")) + zstrm.msg); + } + } + err = ::close(h); + if (err) { + throw GeneralException(String(_("Error during (zstream) close: ")) + strerror(errno)); + } + } else if (z) { #ifdef DEBUG std::cerr << "Performing gzclose on handle " << h << std::endl; #endif @@ -248,7 +271,29 @@ void Handle::SetZ(int az) throw (GeneralException) { if (h < 0) { throw GeneralException(_("Can't SetZ a virtual Handle.")); } - if (az) { + if (az >= 10) { +#ifdef DEBUG + std::cerr << "Setting up zstream using inflate/deflate...\n"; +#endif + int err; + zstrm.zalloc = Z_NULL; + zstrm.zfree = Z_NULL; + if (CanWrite()) { + c = DEFLATE; + err = deflateInit(&zstrm, az - 10); + if (err != Z_OK) { + throw GeneralException(String(_("Error in deflateInit: ")) + zstrm.msg); + } + } else { + c = INFLATE; + zstrm.next_in = 0; + zstrm.avail_in = 0; + err = inflateInit(&zstrm); + if (err != Z_OK) { + throw GeneralException(String(_("Error in inflateInit: ")) + zstrm.msg); + } + } + } else if (az) { char format[4]; int index = 0; if (CanRead()) { @@ -270,8 +315,8 @@ void Handle::SetZ(int az) throw (GeneralException) { } ssize_t Handle::uwrite(const void * buf, size_t count) throw (GeneralException) { - if (z) { - itell += count; + if (z >= 10) { + } else if (z) { #ifdef FULLDEBUG std::cerr << "Performing gzwrite of " << count << " byte for handle " << h << std::endl; #endif @@ -288,6 +333,7 @@ ssize_t Handle::uwrite(const void * buf, size_t count) throw (GeneralException) throw GeneralException(String(_("Error in zlib during gzwrite: ")) + m); } } + itell += err; return err; } else { itell += count = ::write(h, buf, count); @@ -296,8 +342,8 @@ ssize_t Handle::uwrite(const void * buf, size_t count) throw (GeneralException) } ssize_t Handle::uread(void * buf, size_t count) { - if (z) { - itell += count; + if (z >= 10) { + } if (z) { #ifdef DEBUG std::cerr << "Performing gzread of " << count << " byte for handle " << h << std::endl; #endif @@ -310,6 +356,7 @@ ssize_t Handle::uread(void * buf, size_t count) { return 0; } } + itell += err; return err; } else { itell += count = ::read(h, buf, count); @@ -398,3 +445,15 @@ void copy(Handle * s, Handle * d, ssize_t size) { d->write(&c, 1); } } + +void Handle::Flush() { + if (h < 0) + return; + if (z >= 10) { + + } else if (z) { + gzflush(z); + } else { + fsync(h); + } +} |