summaryrefslogtreecommitdiff
path: root/lib/Handle.cc
diff options
context:
space:
mode:
authorpixel <pixel>2008-05-13 06:59:10 +0000
committerpixel <pixel>2008-05-13 06:59:10 +0000
commit8a1b1e91f6892cc51f7d18750a993c5fbcb321ca (patch)
tree15ed16593e1c9b3020546f6d706d2ad586df610a /lib/Handle.cc
parent00202d6c759746dd7ff768934521fc1ede20f144 (diff)
Adding basic inflate / deflate support.
Diffstat (limited to 'lib/Handle.cc')
-rw-r--r--lib/Handle.cc118
1 files changed, 117 insertions, 1 deletions
diff --git a/lib/Handle.cc b/lib/Handle.cc
index 7313d92..479c055 100644
--- a/lib/Handle.cc
+++ b/lib/Handle.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* $Id: Handle.cc,v 1.81 2008-01-21 17:19:07 pixel Exp $ */
+/* $Id: Handle.cc,v 1.82 2008-05-13 06:59:10 pixel Exp $ */
#include <stdio.h>
#include <string.h>
@@ -700,3 +700,119 @@ int Handle::nclose() throw (GeneralException) {
int Handle::GetNbHandles() {
return nb_handles;
}
+
+#define CHUNK 10240
+//
+// shamelessly ripped from http://www.zlib.net/zpipe.c
+//
+int Handle::zlib_inflate(Handle * in, Handle * out) throw (GeneralException) {
+ int ret;
+ z_stream s;
+ unsigned char b_in[CHUNK];
+ unsigned char b_out[CHUNK];
+ unsigned int have, total_out;
+
+ s.zalloc = (alloc_func) 0;
+ s.zfree = (free_func) 0;
+ s.opaque = (voidpf) 0;
+ s.next_in = Z_NULL;
+ s.next_out = Z_NULL;
+ s.avail_in = 0;
+ s.avail_out = 0;
+
+ have = total_out = 0;
+
+ ret = inflateInit(&s);
+ if (ret != Z_OK ) {
+ throw GeneralException("zlib: deflateInit() failed: " + String(ret));
+ }
+
+ do {
+ s.avail_in = in->read(b_in, CHUNK);
+
+ if (s.avail_in == 0)
+ break;
+
+ s.next_in = b_in;
+
+ do {
+ s.avail_out = CHUNK;
+ s.next_out = b_out;
+ ret = inflate(&s, Z_NO_FLUSH);
+ if (ret == Z_STREAM_ERROR) {
+ throw GeneralException("inflate returned Z_STREAM_ERROR: " + String(s.msg));
+ }
+ switch (ret) {
+ case Z_NEED_DICT:
+ ret = Z_DATA_ERROR;
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ inflateEnd(&s);
+ throw GeneralException("inflate returned an erroneous state: " + String(ret) + " - " + String(s.msg));
+ }
+ have = CHUNK - s.avail_out;
+ if (out->write(b_out, have) != have) {
+ throw GeneralException("Output file not writable.");
+ }
+ total_out += have;
+ } while (s.avail_out == 0);
+ } while (ret != Z_STREAM_END);
+
+ inflateEnd(&s);
+
+ return total_out;
+}
+
+int Handle::zlib_deflate(Handle * in, Handle * out) throw (GeneralException) {
+ int ret, flush;
+ z_stream s;
+ unsigned char b_in[CHUNK];
+ unsigned char b_out[CHUNK];
+ unsigned int have, total_out;
+
+ s.zalloc = (alloc_func) 0;
+ s.zfree = (free_func) 0;
+ s.opaque = (voidpf) 0;
+ s.next_in = Z_NULL;
+ s.next_out = Z_NULL;
+ s.avail_in = 0;
+ s.avail_out = 0;
+
+ have = total_out = 0;
+
+ ret = deflateInit(&s, 9);
+ if (ret != Z_OK ) {
+ throw GeneralException("zlib: deflateInit() failed: " + String(ret));
+ }
+
+ do {
+ s.avail_in = in->read(b_in, CHUNK);
+
+ flush = s.avail_in == 0 ? Z_FINISH : Z_NO_FLUSH;
+ s.next_in = b_in;
+
+ do {
+ s.avail_out = CHUNK;
+ s.next_out = b_out;
+ ret = deflate(&s, flush);
+ if (ret == Z_STREAM_ERROR) {
+ throw GeneralException("inflate returned Z_STREAM_ERROR: " + String(s.msg));
+ }
+ have = CHUNK - s.avail_out;
+ if (out->write(b_out, have) != have) {
+ deflateEnd(&s);
+ throw GeneralException("couldn't write properly to output.");
+ }
+
+ total_out += have;
+ } while (s.avail_out == 0);
+
+ if (s.avail_in != 0) {
+ throw GeneralException("All input not used.");
+ }
+ } while (flush != Z_FINISH);
+
+ deflateEnd(&s);
+
+ return total_out;
+}