22 #include "compressor.h" 30 #define Z_STREAM_END 1 31 #define Z_STREAM_ERROR (-2) 32 #define Z_BUF_ERROR (-5) 35 #define GZIP_WINDOWS_BIT 15 + 16 36 #define GZIP_CHUNK_SIZE 16384 37 #define MIN(a,b) (a > b ? b : a) 38 #define MAX(a,b) (a > b ? a : b) 42 Compressor::Compressor(
const char *input,
size_t len,
int level )
43 : m_status(Z_STREAM_ERROR)
46 , m_chunk_size(GZIP_CHUNK_SIZE)
47 , m_type_in(MEM_BUFFER)
59 m_output =
new char[m_chunk_size];
60 _opaque =
new z_stream;
61 m_status = _init(_opaque, m_output, m_chunk_size, level);
62 m_stop = (m_status != Z_OK);
66 Compressor::Compressor(STREAM_READER reader,
void *handle,
int level )
67 : m_status(Z_STREAM_ERROR)
70 , m_chunk_size(GZIP_CHUNK_SIZE)
71 , m_type_in(FCB_READER)
75 , m_rstream_hdl(handle)
83 m_rstream_buf =
new char[m_chunk_size];
84 m_output =
new char[m_chunk_size];
85 _opaque =
new z_stream;
86 m_status = _init(_opaque, m_output, m_chunk_size, level);
87 m_stop = (m_status != Z_OK);
91 Compressor::~Compressor()
94 z_stream *strm =
static_cast<z_stream*
>(_opaque);
97 SAFE_DELETE_ARRAY(m_output);
98 SAFE_DELETE_ARRAY(m_rstream_buf);
102 bool Compressor::IsCompleted()
104 return (m_status == Z_STREAM_END);
107 bool Compressor::HasBufferError()
109 return (m_status == Z_BUF_ERROR);
112 bool Compressor::HasStreamError()
125 size_t Compressor::ReadOutput(
char *buf,
size_t len)
133 size_t sz = MIN(m_output_len, len);
134 memcpy(buf, m_output + m_output_pos, sz);
141 else if (m_status != Z_STREAM_END)
143 z_stream *strm =
static_cast<z_stream*
>(_opaque);
146 if (!strm->avail_out)
148 strm->next_out = (
unsigned char*)m_output;
149 strm->avail_out = m_chunk_size;
153 m_status = deflate(strm, m_flush);
159 m_output_len = m_chunk_size - m_output_pos - strm->avail_out;
172 size_t Compressor::FetchOutput(
const char **data)
181 *data = m_output + m_output_pos;
183 m_output_pos += m_output_len;
187 else if (m_status != Z_STREAM_END)
189 z_stream *strm =
static_cast<z_stream*
>(_opaque);
192 if (!strm->avail_out)
194 strm->next_out = (
unsigned char*)m_output;
195 strm->avail_out = m_chunk_size;
199 m_status = deflate(strm, m_flush);
205 m_output_len = m_chunk_size - m_output_pos - strm->avail_out;
218 int Compressor::_init(
void *zp,
void *out,
size_t len,
int level)
221 z_stream *strm =
static_cast<z_stream*
>(zp);
223 strm->zalloc = Z_NULL;
224 strm->zfree = Z_NULL;
225 strm->opaque = Z_NULL;
227 strm->next_in = Z_NULL;
228 strm->avail_out = len;
229 strm->next_out = (
unsigned char*)out;
230 return deflateInit2(strm, MAX(-1, MIN(level, 9)), Z_DEFLATED, GZIP_WINDOWS_BIT, 8, Z_DEFAULT_STRATEGY);
232 return Z_STREAM_ERROR;
236 size_t Compressor::NextChunk()
240 if (m_flush != Z_FINISH)
242 z_stream *strm =
static_cast<z_stream*
>(_opaque);
247 sz = MIN(m_chunk_size, m_input_len);
252 strm->next_in = (
unsigned char*)m_input;
253 strm->avail_in = (unsigned)sz;
258 m_flush = (m_input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
263 int ret = (*m_rstream)(m_rstream_hdl, (
void*)m_rstream_buf, m_chunk_size);
268 m_flush = (ret > 0 ? Z_NO_FLUSH : Z_FINISH);
272 strm->next_in = (
unsigned char*)m_rstream_buf;
273 strm->avail_in = (unsigned)sz;
284 Decompressor::Decompressor(
const char *input,
size_t len)
285 : m_status(Z_STREAM_ERROR)
287 , m_chunk_size(GZIP_CHUNK_SIZE)
288 , m_type_in(MEM_BUFFER)
300 m_output =
new char[m_chunk_size];
301 _opaque =
new z_stream;
302 m_status = _init(_opaque, m_output, m_chunk_size);
303 m_stop = (m_status != Z_OK);
307 Decompressor::Decompressor(STREAM_READER reader,
void *handle)
308 : m_status(Z_STREAM_ERROR)
310 , m_chunk_size(GZIP_CHUNK_SIZE)
311 , m_type_in(FCB_READER)
315 , m_rstream_hdl(handle)
323 m_rstream_buf =
new char[m_chunk_size];
324 m_output =
new char[m_chunk_size];
325 _opaque =
new z_stream;
326 m_status = _init(_opaque, m_output, m_chunk_size);
327 m_stop = (m_status != Z_OK);
331 Decompressor::~Decompressor()
334 z_stream *strm =
static_cast<z_stream*
>(_opaque);
337 SAFE_DELETE_ARRAY(m_output);
338 SAFE_DELETE_ARRAY(m_rstream_buf);
342 bool Decompressor::IsCompleted()
344 return (m_status == Z_STREAM_END);
347 bool Decompressor::HasBufferError()
349 return (m_status == Z_BUF_ERROR);
352 bool Decompressor::HasStreamError()
365 size_t Decompressor::ReadOutput(
char *buf,
size_t len)
373 size_t sz = MIN(m_output_len, len);
374 memcpy(buf, m_output + m_output_pos, sz);
381 else if (m_status != Z_STREAM_END)
383 z_stream *strm =
static_cast<z_stream*
>(_opaque);
386 if (!strm->avail_out)
388 strm->next_out = (
unsigned char*)m_output;
389 strm->avail_out = m_chunk_size;
393 m_status = inflate(strm, Z_NO_FLUSH);
399 m_output_len = m_chunk_size - m_output_pos - strm->avail_out;
412 size_t Decompressor::FetchOutput(
const char **data)
421 *data = m_output + m_output_pos;
423 m_output_pos += m_output_len;
427 else if (m_status != Z_STREAM_END)
429 z_stream *strm =
static_cast<z_stream*
>(_opaque);
432 if (!strm->avail_out)
434 strm->next_out = (
unsigned char*)m_output;
435 strm->avail_out = m_chunk_size;
439 m_status = inflate(strm, Z_NO_FLUSH);
445 m_output_len = m_chunk_size - m_output_pos - strm->avail_out;
458 int Decompressor::_init(
void *zp,
void *out,
size_t len)
461 z_stream *strm =
static_cast<z_stream*
>(zp);
463 strm->zalloc = Z_NULL;
464 strm->zfree = Z_NULL;
465 strm->opaque = Z_NULL;
467 strm->next_in = Z_NULL;
468 strm->avail_out = len;
469 strm->next_out = (
unsigned char*)out;
470 return inflateInit2(strm, GZIP_WINDOWS_BIT);
472 return Z_STREAM_ERROR;
476 size_t Decompressor::NextChunk()
480 z_stream *strm =
static_cast<z_stream*
>(_opaque);
485 sz = MIN(m_chunk_size, m_input_len);
490 strm->next_in = (
unsigned char*)m_input;
491 strm->avail_in = (unsigned)sz;
499 int ret = (*m_rstream)(m_rstream_hdl, (
void*)m_rstream_buf, m_chunk_size);
505 strm->next_in = (
unsigned char*)m_rstream_buf;
506 strm->avail_in = (unsigned)sz;