From 2f22a35e843a24f0ad5f31644133d64648fe4efc Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Mon, 12 Aug 2019 18:25:52 +0200 Subject: Add deep-copy function to compressor interface Signed-off-by: David Oberhollenzer --- include/compress.h | 4 ++++ lib/comp/gzip.c | 31 +++++++++++++++++++++++++++++++ lib/comp/lz4.c | 14 ++++++++++++++ lib/comp/lzo.c | 17 +++++++++++++++++ lib/comp/xz.c | 14 ++++++++++++++ lib/comp/zstd.c | 24 ++++++++++++++++++++++++ 6 files changed, 104 insertions(+) diff --git a/include/compress.h b/include/compress.h index 7c90b2c..1dfba12 100644 --- a/include/compress.h +++ b/include/compress.h @@ -44,6 +44,10 @@ struct compressor_t { ssize_t (*do_block)(compressor_t *cmp, const uint8_t *in, size_t size, uint8_t *out, size_t outsize); + /* create another compressor just like this one, i.e. + with the exact same settings */ + compressor_t *(*create_copy)(compressor_t *cmp); + void (*destroy)(compressor_t *stream); }; diff --git a/lib/comp/gzip.c b/lib/comp/gzip.c index 1068520..1fdc051 100644 --- a/lib/comp/gzip.c +++ b/lib/comp/gzip.c @@ -308,6 +308,36 @@ fail_value: return -1; } +static compressor_t *gzip_create_copy(compressor_t *cmp) +{ + gzip_compressor_t *gzip = malloc(sizeof(*gzip)); + int ret; + + if (gzip == NULL) { + perror("creating additional gzip compressor"); + return NULL; + } + + memcpy(gzip, cmp, sizeof(*gzip)); + memset(&gzip->strm, 0, sizeof(gzip->strm)); + + if (gzip->compress) { + ret = deflateInit2(&gzip->strm, gzip->opt.level, Z_DEFLATED, + gzip->opt.window, 8, Z_DEFAULT_STRATEGY); + } else { + ret = inflateInit(&gzip->strm); + } + + if (ret != Z_OK) { + fputs("internal error creating additional zlib stream\n", + stderr); + free(gzip); + return NULL; + } + + return (compressor_t *)gzip; +} + compressor_t *create_gzip_compressor(bool compress, size_t block_size, char *options) { @@ -340,6 +370,7 @@ compressor_t *create_gzip_compressor(bool compress, size_t block_size, base->destroy = gzip_destroy; base->write_options = gzip_write_options; base->read_options = gzip_read_options; + base->create_copy = gzip_create_copy; if (compress) { ret = deflateInit2(&gzip->strm, level, Z_DEFLATED, window, 8, diff --git a/lib/comp/lz4.c b/lib/comp/lz4.c index ffa84dc..abb6c5c 100644 --- a/lib/comp/lz4.c +++ b/lib/comp/lz4.c @@ -97,6 +97,19 @@ static ssize_t lz4_uncomp_block(compressor_t *base, const uint8_t *in, return ret; } +static compressor_t *lz4_create_copy(compressor_t *cmp) +{ + lz4_compressor_t *lz4 = malloc(sizeof(*lz4)); + + if (lz4 == NULL) { + perror("creating additional lz4 compressor"); + return NULL; + } + + memcpy(lz4, cmp, sizeof(*lz4)); + return (compressor_t *)lz4; +} + static void lz4_destroy(compressor_t *base) { free(base); @@ -131,6 +144,7 @@ compressor_t *create_lz4_compressor(bool compress, size_t block_size, base->do_block = compress ? lz4_comp_block : lz4_uncomp_block; base->write_options = lz4_write_options; base->read_options = lz4_read_options; + base->create_copy = lz4_create_copy; return base; } diff --git a/lib/comp/lzo.c b/lib/comp/lzo.c index 98cc200..66c2f59 100644 --- a/lib/comp/lzo.c +++ b/lib/comp/lzo.c @@ -177,6 +177,22 @@ static ssize_t lzo_uncomp_block(compressor_t *base, const uint8_t *in, return len; } +static compressor_t *lzo_create_copy(compressor_t *cmp) +{ + lzo_compressor_t *other = (lzo_compressor_t *)cmp; + lzo_compressor_t *lzo; + + lzo = calloc(1, sizeof(*lzo) + lzo_algs[other->algorithm].bufsize); + + if (lzo == NULL) { + perror("creating additional lzo compressor"); + return NULL; + } + + memcpy(lzo, other, sizeof(*lzo)); + return (compressor_t *)lzo; +} + static void lzo_destroy(compressor_t *base) { free(base); @@ -281,6 +297,7 @@ compressor_t *create_lzo_compressor(bool compress, size_t block_size, base->do_block = compress ? lzo_comp_block : lzo_uncomp_block; base->write_options = lzo_write_options; base->read_options = lzo_read_options; + base->create_copy = lzo_create_copy; return base; } diff --git a/lib/comp/xz.c b/lib/comp/xz.c index 3e63050..d38aab6 100644 --- a/lib/comp/xz.c +++ b/lib/comp/xz.c @@ -195,6 +195,19 @@ static ssize_t xz_uncomp_block(compressor_t *base, const uint8_t *in, return -1; } +static compressor_t *xz_create_copy(compressor_t *cmp) +{ + xz_compressor_t *xz = malloc(sizeof(*xz)); + + if (xz == NULL) { + perror("creating additional xz compressor"); + return NULL; + } + + memcpy(xz, cmp, sizeof(*xz)); + return (compressor_t *)xz; +} + static void xz_destroy(compressor_t *base) { free(base); @@ -318,6 +331,7 @@ compressor_t *create_xz_compressor(bool compress, size_t block_size, base->do_block = compress ? xz_comp_block : xz_uncomp_block; base->write_options = xz_write_options; base->read_options = xz_read_options; + base->create_copy = xz_create_copy; return base; } diff --git a/lib/comp/zstd.c b/lib/comp/zstd.c index 252e1bf..e206338 100644 --- a/lib/comp/zstd.c +++ b/lib/comp/zstd.c @@ -88,6 +88,29 @@ static ssize_t zstd_uncomp_block(compressor_t *base, const uint8_t *in, return ret; } +static compressor_t *zstd_create_copy(compressor_t *cmp) +{ + zstd_compressor_t *zstd = malloc(sizeof(*zstd)); + + if (zstd == NULL) { + perror("creating additional zstd compressor"); + return NULL; + } + + memcpy(zstd, cmp, sizeof(*zstd)); + + zstd->zctx = ZSTD_createCCtx(); + + if (zstd->zctx == NULL) { + fputs("error creating addtional zstd compression context\n", + stderr); + free(zstd); + return NULL; + } + + return (compressor_t *)zstd; +} + static void zstd_destroy(compressor_t *base) { zstd_compressor_t *zstd = (zstd_compressor_t *)base; @@ -141,6 +164,7 @@ compressor_t *create_zstd_compressor(bool compress, size_t block_size, base->do_block = compress ? zstd_comp_block : zstd_uncomp_block; base->write_options = zstd_write_options; base->read_options = zstd_read_options; + base->create_copy = zstd_create_copy; return base; fail_level: fprintf(stderr, "zstd compression level must be a number in the range " -- cgit v1.2.3