133 lines
2.4 KiB
C++
133 lines
2.4 KiB
C++
#include "zlib_wrapper.h"
|
|
#include "log.h"
|
|
#include <memory>
|
|
#include <string>
|
|
#include <list>
|
|
#include <queue>
|
|
#include <vector>
|
|
using namespace std;
|
|
|
|
/// Block size.
|
|
#define BLOCKSZ 4096
|
|
|
|
class Decompress
|
|
{
|
|
public:
|
|
Decompress()
|
|
{
|
|
memset(&_z,0,sizeof(_z));
|
|
_status=-1;
|
|
}
|
|
|
|
~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)
|
|
{
|
|
_status=1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int run(int flush_parameter)
|
|
{
|
|
return inflate(&_z,flush_parameter);
|
|
}
|
|
|
|
int destroy()
|
|
{
|
|
if(_status<0) return -101;
|
|
|
|
int ret=inflateEnd(&_z);
|
|
if(ret==Z_OK)
|
|
{
|
|
_status=-2;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/// For experiment use.
|
|
z_stream& get()
|
|
{
|
|
return _z;
|
|
}
|
|
private:
|
|
z_stream _z;
|
|
int _status;
|
|
};
|
|
|
|
std::string GZDecompress(const std::string& InputStr)
|
|
{
|
|
int inputSz=InputStr.size();
|
|
|
|
unsigned char* holder=(unsigned char*)malloc(inputSz+32);
|
|
if(!holder)
|
|
{
|
|
dprintf("Failed to malloc holder.\n");
|
|
return "";
|
|
}
|
|
memset(holder,0,inputSz+32);
|
|
memcpy(holder,InputStr.data(),inputSz);
|
|
|
|
std::shared_ptr<unsigned char> sp;
|
|
sp.reset(holder,free);
|
|
|
|
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
|
|
{
|
|
d.setOut(buffer,BLOCKSZ);
|
|
int ret=d.run(Z_NO_FLUSH);
|
|
switch(ret)
|
|
{
|
|
case Z_NEED_DICT:
|
|
case Z_DATA_ERROR:
|
|
case Z_MEM_ERROR:
|
|
dprintf("Failed to decode. ret=%d\n",ret);
|
|
return "";
|
|
}
|
|
|
|
int realsz=BLOCKSZ-d.get().avail_out;
|
|
result.append(string((char*)buffer,realsz));
|
|
} while (d.get().avail_out==0);
|
|
|
|
return result;
|
|
}
|