File-Raw-Gzip
view release on metacpan or search on metacpan
/*
* gz.c - zlib inflate/deflate wrappers driving a malloc-grown output
* buffer. Both functions consume the entire input in one go (one-shot
* codec, no streaming). Output buffer doubles when full; that bounds
* realloc count to log2(out_size).
*/
#include "gz.h"
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#define GZ_DEFAULT_CHUNK (128 * 1024)
#define GZ_DEFAULT_LEVEL 6
#define GZ_DEFAULT_MEM 8
void gz_options_init(gz_options_t *opts) {
opts->level = GZ_DEFAULT_LEVEL;
opts->mode = GZ_MODE_AUTO;
opts->chunk_size = GZ_DEFAULT_CHUNK;
opts->strategy = Z_DEFAULT_STRATEGY;
opts->mem_level = GZ_DEFAULT_MEM;
}
static int wbits_for_mode(gz_mode_t mode, int encoding) {
switch (mode) {
case GZ_MODE_GZIP: return MAX_WBITS | 16; /* 31 */
case GZ_MODE_ZLIB: return MAX_WBITS; /* 15 */
case GZ_MODE_RAW: return -MAX_WBITS; /* -15 */
case GZ_MODE_AUTO: return encoding ? -1 : (MAX_WBITS | 32); /* 47 decode */
}
return -1;
}
static gz_err_t map_z_err(int z) {
switch (z) {
case Z_OK: return GZ_OK;
case Z_STREAM_END: return GZ_OK;
case Z_NEED_DICT: return GZ_ERR_NEED_DICT;
case Z_DATA_ERROR: return GZ_ERR_DATA;
case Z_MEM_ERROR: return GZ_ERR_MEM;
case Z_BUF_ERROR: return GZ_ERR_BUF;
case Z_VERSION_ERROR:return GZ_ERR_VERSION;
default: return GZ_ERR_DATA;
}
}
const char *gz_strerror(gz_err_t err) {
switch (err) {
case GZ_OK: return "ok";
case GZ_ERR_INIT: return "zlib init failed";
case GZ_ERR_DATA: return "corrupt input stream";
case GZ_ERR_NEED_DICT: return "stream requires preset dictionary (unsupported)";
case GZ_ERR_MEM: return "out of memory";
case GZ_ERR_BUF: return "buffer error";
case GZ_ERR_VERSION: return "zlib version mismatch";
case GZ_ERR_OPT: return "invalid option";
case GZ_ERR_TRUNCATED: return "input ended before stream completion";
}
return "unknown error";
}
/* Grow `*buf` so it has at least `*cap >= used + need` bytes. Returns 0
( run in 1.773 second using v1.01-cache-2.11-cpan-140bd7fdf52 )