summaryrefslogtreecommitdiff
path: root/lib/Handle.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Handle.cc')
-rw-r--r--lib/Handle.cc71
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);
+ }
+}