Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvgzip.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * Gzip encoder/decoder based on zlib.
00006  */
00007 #include "wvgzip.h"
00008 #include <zlib.h>
00009 #include <assert.h>
00010 
00011 #define ZBUFSIZE 10240
00012 
00013 /***** GzipEncoder *****/
00014 
00015 WvGzipEncoder::WvGzipEncoder(Mode _mode) :
00016     tmpbuf(ZBUFSIZE), mode(_mode)
00017 {
00018     init();
00019 }
00020 
00021 
00022 WvGzipEncoder::~WvGzipEncoder()
00023 {
00024     close();
00025 }
00026 
00027 
00028 void WvGzipEncoder::init()
00029 {
00030     zstr = new z_stream;
00031     memset(zstr, 0, sizeof(*zstr));
00032     zstr->zalloc = Z_NULL;
00033     zstr->zfree = Z_NULL;
00034     zstr->opaque = NULL;
00035     zstr->msg = NULL;
00036     
00037     int retval;
00038     if (mode == Deflate)
00039         retval = deflateInit(zstr, Z_DEFAULT_COMPRESSION);
00040     else
00041         retval = inflateInit(zstr);
00042     
00043     if (retval != Z_OK)
00044     {
00045         seterror("error %s initializing gzip %s: %s", retval,
00046             mode == Deflate ? "compressor" : "decompressor",
00047             zstr->msg ? zstr->msg : "unknown");
00048         return;
00049     }
00050     zstr->next_in = zstr->next_out = NULL;
00051     zstr->avail_in = zstr->avail_out = 0;
00052 }
00053 
00054 void WvGzipEncoder::close()
00055 {
00056     if (mode == Deflate)
00057         deflateEnd(zstr);
00058     else
00059         inflateEnd(zstr);
00060 
00061     delete zstr;
00062 
00063 }
00064 
00065 bool WvGzipEncoder::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
00066 {
00067     bool success;
00068     for (;;)
00069     {
00070         prepare(& inbuf);
00071         bool alldata = inbuf.used() == 0;
00072         success = process(outbuf, flush && alldata, false);
00073         if (zstr->avail_in != 0)
00074         {
00075             // unget unused data
00076             inbuf.unget(zstr->avail_in);
00077             zstr->avail_in = 0;
00078         }
00079         if (! success)
00080             return false;
00081         if (alldata)
00082             return true;
00083     }
00084 }
00085 
00086 
00087 bool WvGzipEncoder::_finish(WvBuf &outbuf)
00088 {
00089     prepare(NULL);
00090     return process(outbuf, false, true);
00091 }
00092 
00093 
00094 bool WvGzipEncoder::_reset()
00095 {
00096     close();
00097     init();
00098     return true;
00099 }
00100 
00101 
00102 void WvGzipEncoder::prepare(WvBuf *inbuf)
00103 {
00104     assert(zstr->avail_in == 0);
00105     if (inbuf && inbuf->used() != 0)
00106     {
00107         size_t avail = inbuf->optgettable();
00108         zstr->avail_in = avail;
00109         zstr->next_in = const_cast<Bytef*>(
00110             (const Bytef*)inbuf->get(avail));
00111     }
00112     else
00113     {
00114         zstr->avail_in = 0;
00115         zstr->next_in = (Bytef*)""; // so it's not NULL
00116     }
00117 }
00118 
00119 
00120 bool WvGzipEncoder::process(WvBuf &outbuf, bool flush, bool finish)
00121 {
00122     int flushmode = finish ? Z_FINISH :
00123         flush ? Z_SYNC_FLUSH : Z_NO_FLUSH;
00124     int retval;
00125     do
00126     {
00127         // process the next chunk
00128         tmpbuf.zap();
00129         zstr->avail_out = tmpbuf.free();
00130         zstr->next_out = tmpbuf.alloc(tmpbuf.free());
00131         if (mode == Deflate)
00132             retval = deflate(zstr, flushmode);
00133         else
00134             retval = inflate(zstr, flushmode);
00135         tmpbuf.unalloc(zstr->avail_out);
00136 
00137         // consume pending output
00138         outbuf.merge(tmpbuf);
00139     } while (retval == Z_OK);
00140 
00141     if (retval == Z_STREAM_END)
00142         setfinished();
00143     else if (retval != Z_OK && retval != Z_BUF_ERROR)
00144     {
00145         seterror("error %s during gzip %s: %s", retval,
00146             mode == Deflate ? "compression" : "decompression",
00147             zstr->msg ? zstr->msg : "unknown");
00148         return false;
00149     }
00150     return true;
00151 }
00152 

Generated on Sat Mar 13 14:55:42 2004 for WvStreams by doxygen 1.3.6-20040222