File-Raw-Gzip

 view release on metacpan or  search on metacpan

gz.c  view on Meta::CPAN

/*
 * 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 )