Compression.h
/*
* Compression.h
*
* Created on: Aug 26, 2013
* Author: jerome
*/
#ifndef COMPRESSION_H_
#define COMPRESSION_H_
#include <zlib.h>
#include <zconf.h>
#include <iostream>
#include <vector>
#define COMPRESSION_LEVEL Z_DEFAULT_COMPRESSION
#define BUFFER_SIZE 16384
typedef std::vector<unsigned char> StlVecUnChar;
class Compression
{
public:
enum CompressLevel
{
NO_COMPRESSION = Z_NO_COMPRESSION,
BEST_SPEED = Z_BEST_SPEED,
BEST_COMPRESSION = Z_BEST_COMPRESSION,
DEFAULT_COMPRESSION = Z_DEFAULT_COMPRESSION
};
Compression()
: m_zstream(), m_IsCompress(true), m_bufferInCapa(BUFFER_SIZE), m_bufferOutCapa(BUFFER_SIZE), m_compressLevel(DEFAULT_COMPRESSION)
{
}
Compression(bool isCom, CompressLevel level = DEFAULT_COMPRESSION)
: m_zstream(), m_IsCompress(isCom), m_bufferInCapa(BUFFER_SIZE), m_bufferOutCapa(BUFFER_SIZE), m_compressLevel(level)
{
}
virtual ~Compression();
int Init();
int Deflate(const StlVecUnChar &inStr, StlVecUnChar &outStr);
int Inflate(const StlVecUnChar &inStr, StlVecUnChar &outStr);
private:
z_stream m_zstream; // Stream structure used by zlib
bool m_IsCompress; // True: compress. False: decompress
unsigned char m_bufferIn[BUFFER_SIZE]; // Input buffer for zlib
unsigned char m_bufferOut[BUFFER_SIZE];// Output Buffer for zlib
const int m_bufferInCapa; // Input buffer capacity
const int m_bufferOutCapa; // Output buffer capacity
CompressLevel m_compressLevel; // Compress level
};
#endif /* COMPRESSION_H_ */
Compression.cpp
/*
* Compression.cpp
*
* Created on: Aug 26, 2013
* Author: jerome
*/
#include "Compression.h"
#include <cstdio>
#include <cstring>
#include <cassert>
Compression::~Compression() {
// TODO Auto-generated destructor stub
}
int Compression::Init()
{
int ret;
m_zstream.zalloc = NULL;
m_zstream.zfree = NULL;
m_zstream.opaque = NULL;
if(m_IsCompress)
{
ret = deflateInit2_(&m_zstream, m_compressLevel, Z_DEFLATED, MAX_WBITS,
MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY, ZLIB_VERSION, sizeof(z_stream));
}
else
{
ret = inflateInit2_(&m_zstream, MAX_WBITS, ZLIB_VERSION, sizeof(z_stream));
}
return ret;
}
int Compression::Deflate(const StlVecUnChar &inStr, StlVecUnChar &outStr)
{
int ret;
int flush;
size_t lastByte = inStr.size ();
int have = 0;
while (lastByte > 0)
{
if (lastByte > m_bufferInCapa)
{
memcpy (m_bufferIn, &inStr[inStr.size () - lastByte], m_bufferInCapa);
lastByte -= m_bufferInCapa;
m_zstream.avail_in = m_bufferInCapa;
flush = Z_NO_FLUSH;
}
else
{
memcpy (m_bufferIn, &inStr[inStr.size () - lastByte], lastByte);
m_zstream.avail_in = lastByte;
lastByte = 0;
flush = Z_FINISH;
}
m_zstream.next_in = m_bufferIn;
do
{
m_zstream.avail_out = m_bufferOutCapa;
m_zstream.next_out = m_bufferOut;
ret = deflate(&m_zstream, flush);
assert(ret != Z_STREAM_ERROR);
have = m_bufferOutCapa - m_zstream.avail_out;
outStr.insert (outStr.end (), m_bufferOut, m_bufferOut + have);
}while(m_zstream.avail_out == 0);
assert(m_zstream.avail_in == 0);
}
// Finish deflate
(void)deflateEnd(&m_zstream);
return Z_OK;
}
int Compression::Inflate(const StlVecUnChar &inStr, StlVecUnChar &outStr)
{
int ret;
int lastByte = inStr.size();
int have = 0;
while (lastByte > 0)
{
if (lastByte > m_bufferInCapa)
{
memcpy(m_bufferIn, &inStr[inStr.size () - lastByte], m_bufferInCapa);
lastByte -= m_bufferInCapa;
m_zstream.avail_in = m_bufferInCapa;
}
else
{
memcpy(m_bufferIn, &inStr[inStr.size () - lastByte], lastByte);
m_zstream.avail_in = lastByte;
lastByte = 0;
}
m_zstream.next_in = m_bufferIn;
do
{
m_zstream.next_out = m_bufferOut;
m_zstream.avail_out = m_bufferOutCapa;
ret = inflate(&m_zstream, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR);
switch(ret)
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&m_zstream);
return ret;
}
have = m_bufferOutCapa - m_zstream.avail_out;
outStr.insert (outStr.end (), m_bufferOut, m_bufferOut + have);
}while(m_zstream.avail_out == 0);
}
(void)inflateEnd(&m_zstream);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
Download source file.