diff --git a/lib/zlibwapi.lib b/lib/zlibwapi.lib index 22e6555..df384ed 100644 Binary files a/lib/zlibwapi.lib and b/lib/zlibwapi.lib differ diff --git a/src/zlib_wrapper.cpp b/src/zlib_wrapper.cpp index b085472..249d08a 100644 --- a/src/zlib_wrapper.cpp +++ b/src/zlib_wrapper.cpp @@ -2,98 +2,91 @@ #include "log.h" #include #include +#include +#include +#include +using namespace std; -/// From CSDN -/* Uncompress gzip data */ -static int _gz_decompress_real(Byte *zdata, uLong nzdata, - Byte *data, uLong *ndata) +/// Block size. +#define BLOCKSZ 4096 + +class Decompress { - int err = 0; - z_stream d_stream = {0}; /* decompression stream */ - static char dummy_head[2] = +public: + Decompress() { - 0x8 + 0x7 * 0x10, - (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF, - }; - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - d_stream.next_in = zdata; - d_stream.avail_in = 0; - d_stream.next_out = data; - if(inflateInit2(&d_stream, MAX_WBITS+32) != Z_OK) return -1; + memset(&_z,0,sizeof(_z)); + _status=-1; + } - /// Decompress Input Data by byte. (There must be some faster methods) - while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) { - d_stream.avail_in = d_stream.avail_out = 1; - if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break; - if(err != Z_OK ) + ~Decompress() + { + destroy(); + } + + Decompress(const Decompress& )=delete; + Decompress& operator = (const Decompress&)=delete; + + Decompress(Decompress&& d)=delete; + Decompress& operator = (Decompress&&)=delete; + + void setIn(Bytef* ptr,uInt sz) + { + _z.next_in=ptr; + _z.avail_in=sz; + } + void setOut(Bytef* ptr,uInt sz) + { + _z.next_out=ptr; + _z.avail_out=sz; + } + + int init(int window_size) + { + /// Cannot initialize used stream block + if(_status!=-1) return -101; + + int ret=inflateInit2(&_z,window_size); + if(ret==Z_OK) { - if(err == Z_DATA_ERROR) - { - d_stream.next_in = (Bytef*) dummy_head; - d_stream.avail_in = sizeof(dummy_head); - if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK) - { - /// Clean up. - if(inflateEnd(&d_stream)!=Z_OK) - return -2; - else - return -3; - } - } - else if(err==Z_BUF_ERROR) - { - /// Clean up. - if(inflateEnd(&d_stream)!=Z_OK) - return 1; - else - return 2; - } - else - { - /// Clean up. - if(inflateEnd(&d_stream)!=Z_OK) - return -4; - else - return -5; - } + _status=1; } + return ret; } - err=inflate(&d_stream,Z_FINISH); - if(err==Z_BUF_ERROR) + int run(int flush_parameter) { - /// Clean up. - if(inflateEnd(&d_stream) != Z_OK) - return 11; - else - return 12; + return inflate(&_z,flush_parameter); } - else if(err!=Z_OK&&err!=Z_STREAM_END) + + int destroy() { - /// Clean up. - if(inflateEnd(&d_stream) != Z_OK) - return -15; - else - return -16; + if(_status<0) return -101; + + int ret=inflateEnd(&_z); + if(ret==Z_OK) + { + _status=-2; + } + + return ret; } - uLong total_out=d_stream.total_out; - - /// Clean up. - if(inflateEnd(&d_stream) != Z_OK) return -10; - - *ndata = total_out; - return 0; -} + /// For experiment use. + z_stream& get() + { + return _z; + } +private: + z_stream _z; + int _status; +}; std::string GZDecompress(const std::string& InputStr) { - int ret; int inputSz=InputStr.size(); - char* holder=(char*)malloc(inputSz+32); + unsigned char* holder=(unsigned char*)malloc(inputSz+32); if(!holder) { dprintf("Failed to malloc holder.\n"); @@ -102,46 +95,38 @@ std::string GZDecompress(const std::string& InputStr) memset(holder,0,inputSz+32); memcpy(holder,InputStr.data(),inputSz); - std::shared_ptr sp; + std::shared_ptr sp; sp.reset(holder,free); - int rate=2; + Decompress d; + if(d.init(MAX_WBITS+16)!=Z_OK) + { + dprintf("Failed to init zlib\n"); + return ""; + } + + d.setIn(holder,inputSz); + + unsigned char buffer[BLOCKSZ]; + + string result; + do { - uLong outSz=inputSz*rate+32; - dprintf("Try decompress with BufferLength: %d\n",(int)outSz); - - char* buffer=(char*)malloc(outSz); - if(!buffer) + d.setOut(buffer,BLOCKSZ); + int ret=d.run(Z_NO_FLUSH); + switch(ret) { - dprintf("Failed to malloc buffer with size=%d\n",(int)outSz); + case Z_NEED_DICT: + case Z_DATA_ERROR: + case Z_MEM_ERROR: + dprintf("Failed to decode. ret=%d\n",ret); return ""; } - memset(buffer,0,outSz); - std::shared_ptr xp; - xp.reset(buffer,free); + int realsz=BLOCKSZ-d.get().avail_out; + result.append(string((char*)buffer,realsz)); + } while (d.get().avail_out==0); - if((ret=_gz_decompress_real((Byte*)holder,inputSz,(Byte*)buffer,&outSz))!=0) - { - if(ret>0) - { - dprintf("Decompress Failed. Continue with ret %d\n",ret); - rate++; - } - else - { - dprintf("Decompress Failed: ret=%d\n",ret); - return ""; - } - } - else - { - return std::string(buffer,outSz); - } - - }while(true); - - dprintf("Warning: Program should never reaches here.\n"); - return ""; + return result; } diff --git a/zlibwapi.dll b/zlibwapi.dll index 741ffd8..bf295ef 100644 Binary files a/zlibwapi.dll and b/zlibwapi.dll differ