22#include "compressor.h"
26#define DFLT_WINDOWS_BIT (-MAX_WBITS)
27#define GZIP_WINDOWS_BIT ((MAX_WBITS)+16)
28#define GZIP_CHUNK_SIZE 16384
33#define Z_STREAM_ERROR (-2)
34#define Z_BUF_ERROR (-5)
35#define DFLT_WINDOWS_BIT 0
36#define GZIP_WINDOWS_BIT 0
37#define GZIP_CHUNK_SIZE 0
40#define MIN(a,b) (a > b ? b : a)
41#define MAX(a,b) (a > b ? a : b)
43using namespace NSROOT;
45Compressor::Compressor(
const char *input,
size_t len,
bool gzip,
int level )
46: m_status(Z_STREAM_ERROR)
49, m_chunk_size(GZIP_CHUNK_SIZE)
50, m_type_in(MEM_BUFFER)
62 m_output =
new char[m_chunk_size];
63 _opaque =
new z_stream;
64 m_status = _init(_opaque, m_output, m_chunk_size,
65 (gzip ? GZIP_WINDOWS_BIT : DFLT_WINDOWS_BIT),
67 m_stop = (m_status != Z_OK);
71Compressor::Compressor(STREAM_READER reader,
void *handle,
bool gzip,
int level )
72: m_status(Z_STREAM_ERROR)
75, m_chunk_size(GZIP_CHUNK_SIZE)
76, m_type_in(FCB_READER)
80, m_rstream_hdl(handle)
88 m_rstream_buf =
new char[m_chunk_size];
89 m_output =
new char[m_chunk_size];
90 _opaque =
new z_stream;
91 m_status = _init(_opaque, m_output, m_chunk_size,
92 (gzip ? GZIP_WINDOWS_BIT : DFLT_WINDOWS_BIT),
94 m_stop = (m_status != Z_OK);
98Compressor::~Compressor()
101 z_stream *strm =
static_cast<z_stream*
>(_opaque);
111 delete [] m_rstream_buf;
112 m_rstream_buf =
nullptr;
118 return (m_status == Z_STREAM_END);
123 return (m_status == Z_BUF_ERROR);
147 size_t sz = MIN(m_output_len, len);
148 memcpy(buf, m_output + m_output_pos, sz);
155 else if (m_status != Z_STREAM_END)
157 z_stream *strm =
static_cast<z_stream*
>(_opaque);
160 if (!strm->avail_out)
162 strm->next_out = (
unsigned char*)m_output;
163 strm->avail_out = m_chunk_size;
167 m_status = deflate(strm, m_flush);
173 m_output_len = m_chunk_size - m_output_pos - strm->avail_out;
195 *data = m_output + m_output_pos;
197 m_output_pos += m_output_len;
201 else if (m_status != Z_STREAM_END)
203 z_stream *strm =
static_cast<z_stream*
>(_opaque);
206 if (!strm->avail_out)
208 strm->next_out = (
unsigned char*)m_output;
209 strm->avail_out = m_chunk_size;
213 m_status = deflate(strm, m_flush);
219 m_output_len = m_chunk_size - m_output_pos - strm->avail_out;
232int Compressor::_init(
void *zp,
void *out,
size_t len,
int wbits,
int level)
235 z_stream *strm =
static_cast<z_stream*
>(zp);
237 strm->zalloc = Z_NULL;
238 strm->zfree = Z_NULL;
239 strm->opaque = Z_NULL;
241 strm->next_in = Z_NULL;
242 strm->avail_out = len;
243 strm->next_out = (
unsigned char*)out;
244 return deflateInit2(strm, MAX(-1, MIN(level, 9)), Z_DEFLATED, wbits, 8, Z_DEFAULT_STRATEGY);
246 return Z_STREAM_ERROR;
250size_t Compressor::NextChunk()
254 if (m_flush != Z_FINISH)
256 z_stream *strm =
static_cast<z_stream*
>(_opaque);
261 sz = MIN(m_chunk_size, m_input_len);
266 strm->next_in = (
unsigned char*)m_input;
267 strm->avail_in = (unsigned)sz;
272 m_flush = (m_input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
277 int ret = (*m_rstream)(m_rstream_hdl, (
void*)m_rstream_buf, m_chunk_size);
282 m_flush = (ret > 0 ? Z_NO_FLUSH : Z_FINISH);
286 strm->next_in = (
unsigned char*)m_rstream_buf;
287 strm->avail_in = (unsigned)sz;
298Decompressor::Decompressor(
const char *input,
size_t len,
bool gzip)
299: m_status(Z_STREAM_ERROR)
301, m_chunk_size(GZIP_CHUNK_SIZE)
302, m_type_in(MEM_BUFFER)
314 m_output =
new char[m_chunk_size];
315 _opaque =
new z_stream;
316 m_status = _init(_opaque, m_output, m_chunk_size,
317 (gzip ? GZIP_WINDOWS_BIT : DFLT_WINDOWS_BIT));
318 m_stop = (m_status != Z_OK);
322Decompressor::Decompressor(STREAM_READER reader,
void *handle,
bool gzip)
323: m_status(Z_STREAM_ERROR)
325, m_chunk_size(GZIP_CHUNK_SIZE)
326, m_type_in(FCB_READER)
330, m_rstream_hdl(handle)
338 m_rstream_buf =
new char[m_chunk_size];
339 m_output =
new char[m_chunk_size];
340 _opaque =
new z_stream;
341 m_status = _init(_opaque, m_output, m_chunk_size,
342 (gzip ? GZIP_WINDOWS_BIT : DFLT_WINDOWS_BIT));
343 m_stop = (m_status != Z_OK);
347Decompressor::~Decompressor()
350 z_stream *strm =
static_cast<z_stream*
>(_opaque);
360 delete [] m_rstream_buf;
361 m_rstream_buf =
nullptr;
367 return (m_status == Z_STREAM_END);
372 return (m_status == Z_BUF_ERROR);
396 size_t sz = MIN(m_output_len, len);
397 memcpy(buf, m_output + m_output_pos, sz);
404 else if (m_status != Z_STREAM_END)
406 z_stream *strm =
static_cast<z_stream*
>(_opaque);
409 if (!strm->avail_out)
411 strm->next_out = (
unsigned char*)m_output;
412 strm->avail_out = m_chunk_size;
416 m_status = inflate(strm, Z_NO_FLUSH);
422 m_output_len = m_chunk_size - m_output_pos - strm->avail_out;
444 *data = m_output + m_output_pos;
446 m_output_pos += m_output_len;
450 else if (m_status != Z_STREAM_END)
452 z_stream *strm =
static_cast<z_stream*
>(_opaque);
455 if (!strm->avail_out)
457 strm->next_out = (
unsigned char*)m_output;
458 strm->avail_out = m_chunk_size;
462 m_status = inflate(strm, Z_NO_FLUSH);
468 m_output_len = m_chunk_size - m_output_pos - strm->avail_out;
481int Decompressor::_init(
void *zp,
void *out,
size_t len,
int wbits)
484 z_stream *strm =
static_cast<z_stream*
>(zp);
486 strm->zalloc = Z_NULL;
487 strm->zfree = Z_NULL;
488 strm->opaque = Z_NULL;
490 strm->next_in = Z_NULL;
491 strm->avail_out = len;
492 strm->next_out = (
unsigned char*)out;
493 return inflateInit2(strm, wbits);
495 return Z_STREAM_ERROR;
499size_t Decompressor::NextChunk()
503 z_stream *strm =
static_cast<z_stream*
>(_opaque);
508 sz = MIN(m_chunk_size, m_input_len);
513 strm->next_in = (
unsigned char*)m_input;
514 strm->avail_in = (unsigned)sz;
522 int ret = (*m_rstream)(m_rstream_hdl, (
void*)m_rstream_buf, m_chunk_size);
528 strm->next_in = (
unsigned char*)m_rstream_buf;
529 strm->avail_in = (unsigned)sz;
bool IsCompleted()
Output stream is completed.
bool HasStreamError()
Data error occurred from stream.
bool HasBufferError()
Data cannot be read from input.
size_t ReadOutput(char *buf, size_t len)
Copy data from output stream to the given pointer until size limit.
size_t FetchOutput(const char **data)
Fetch next chunk of data from output stream. No copy of data is performed and result can be used as i...
bool HasBufferError()
Data cannot be read from input.
size_t ReadOutput(char *buf, size_t len)
Copy data from output stream to the given pointer until size limit.
bool IsCompleted()
Output stream is completed.
bool HasStreamError()
Data error occurred from stream.
size_t FetchOutput(const char **data)
Fetch next chunk of data from output stream. No copy of data is performed and result can be used as i...