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 Tue Oct 5 01:09:20 2004 for WvStreams by doxygen 1.3.7