diff options
author | pixel <pixel> | 2008-05-13 06:59:10 +0000 |
---|---|---|
committer | pixel <pixel> | 2008-05-13 06:59:10 +0000 |
commit | 8a1b1e91f6892cc51f7d18750a993c5fbcb321ca (patch) | |
tree | 15ed16593e1c9b3020546f6d706d2ad586df610a /lib/Handle.cc | |
parent | 00202d6c759746dd7ff768934521fc1ede20f144 (diff) |
Adding basic inflate / deflate support.
Diffstat (limited to 'lib/Handle.cc')
-rw-r--r-- | lib/Handle.cc | 118 |
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; +} |