--- /dev/null
+
+/*] Copyright (c) 2009-2011, Charles McGarvey [*****************************
+**] All rights reserved.
+*
+* Distributable under the terms and conditions of the 2-clause BSD license;
+* see the file COPYING for a complete text of the license.
+*
+*****************************************************************************/
+
+#include <iostream>
+#include <stdexcept>
+#include <zlib.h>
+
+#include "compression.hh"
+
+#define ZLIB_BUF_SIZE 262114
+
+
+namespace moof {
+
+
+void inflate(std::istream& in, std::ostream& out)
+{
+ char inbuf[ZLIB_BUF_SIZE];
+ char outbuf[ZLIB_BUF_SIZE];
+
+ z_stream zstream;
+
+ zstream.zalloc = Z_NULL;
+ zstream.zfree = Z_NULL;
+ zstream.opaque = Z_NULL;
+ zstream.avail_in = 0;
+ zstream.next_in = Z_NULL;
+
+ int result = inflateInit2(&zstream, 32 + MAX_WBITS);
+ if (result != Z_OK) throw std::runtime_error("zlib init error");
+
+ do {
+ in.read(inbuf, sizeof(inbuf));
+ zstream.next_in = (Bytef*)inbuf;
+ zstream.avail_in = in.gcount();
+
+ if (zstream.avail_in == 0) break;
+
+ do {
+ zstream.next_out = (Bytef*)outbuf;
+ zstream.avail_out = sizeof(outbuf);
+
+ result = inflate(&zstream, Z_NO_FLUSH);
+ switch (result)
+ {
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ inflateEnd(&zstream);
+ throw std::runtime_error("zlib inflate error");
+ case Z_STREAM_ERROR:
+ throw std::runtime_error("zlib stream error");
+ }
+
+ int inflated = sizeof(outbuf) - zstream.avail_out;
+ out.write(outbuf, inflated);
+ }
+ while (zstream.avail_out == 0);
+ }
+ while(result != Z_STREAM_END);
+
+ inflateEnd(&zstream);
+}
+
+void inflate(const char* in, size_t size, std::ostream& out)
+{
+ char buf[ZLIB_BUF_SIZE];
+
+ z_stream zstream;
+ zstream.zalloc = Z_NULL;
+ zstream.zfree = Z_NULL;
+ zstream.opaque = Z_NULL;
+ zstream.avail_in = size;
+ zstream.next_in = (Bytef*)in;
+
+ int result = inflateInit2(&zstream, 32 + MAX_WBITS);
+ if (result != Z_OK) throw std::runtime_error("zlib init error");
+
+ do {
+ zstream.next_out = (Bytef*)buf;
+ zstream.avail_out = sizeof(buf);
+
+ result = inflate(&zstream, Z_NO_FLUSH);
+ switch (result)
+ {
+ case Z_NEED_DICT:
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ inflateEnd(&zstream);
+ throw std::runtime_error("zlib inflate error");
+ case Z_STREAM_ERROR:
+ throw std::runtime_error("zlib stream error");
+ }
+
+ size_t inflated = sizeof(buf) - zstream.avail_out;
+ out.write(buf, inflated);
+ }
+ while (zstream.avail_out == 0);
+
+ inflateEnd(&zstream);
+}
+
+
+} // namespace moof
+