using GLib; using ZLib; class ZLibTest : Object { // 16KB buffer size const int CHUNK = 16*1024; uchar[] buf_in; uchar[] buf_out; construct { buf_in = new uchar[CHUNK]; buf_out = new uchar[CHUNK]; } public int inflate (InputStream source, OutputStream dest) throws Error { uint have; int ret = Status.OK; var strm = InflateStream.full (15 | 32); // no way to check if this failed... // decompress until deflate stream ends or end of file do { strm.avail_in = (int) source.read (buf_in, CHUNK, null); if (strm.avail_in == 0) break; strm.next_in = buf_in; // run inflate() on input until output buffer not full do { strm.avail_out = buf_out.length; strm.next_out = buf_out; ret = strm.inflate (Flush.NONE); assert (ret != Status.STREAM_ERROR); // state not clobbered if (ret == Status.NEED_DICT) ret = Status.DATA_ERROR; // and fall through switch (ret) { case Status.DATA_ERROR: case Status.MEM_ERROR: return ret; } have = CHUNK - strm.avail_out; if (dest.write (buf_out, have, null) != have) return Status.ERRNO; } while (strm.avail_out == 0); // done when inflate () says it's done } while (ret != Status.STREAM_END); return ret == Status.STREAM_END ? Status.OK : Status.DATA_ERROR; } public static int main (string[] argv) { var zlib_test = new ZLibTest (); var infile = File.new_for_path ("test.gz"); var outfile = File.new_for_path ("test.jpg"); InputStream instream; OutputStream outstream; try { instream = infile.read (null); outstream = outfile.create (FileCreateFlags.NONE, null); return zlib_test.inflate (instream, outstream); } catch (Error e) { stderr.printf ("Error: %s\n", e.message); return -1; } } }