From 551dd3879c288a2b6b6fbaca5c09c04fbe994ff4 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Tue, 13 Dec 2022 09:15:19 +0100 Subject: Split stream compression out of libio Move it to a separate libxfrm library, where it can be independently tested as well. The bulk of the new code is also mainly test cases for the compressors. Signed-off-by: David Oberhollenzer --- lib/io/compress/bzip2.c | 96 ------------------------------- lib/io/compress/gzip.c | 92 ------------------------------ lib/io/compress/ostream_compressor.c | 106 ----------------------------------- lib/io/compress/xz.c | 80 -------------------------- lib/io/compress/zstd.c | 94 ------------------------------- 5 files changed, 468 deletions(-) delete mode 100644 lib/io/compress/bzip2.c delete mode 100644 lib/io/compress/gzip.c delete mode 100644 lib/io/compress/ostream_compressor.c delete mode 100644 lib/io/compress/xz.c delete mode 100644 lib/io/compress/zstd.c (limited to 'lib/io/compress') diff --git a/lib/io/compress/bzip2.c b/lib/io/compress/bzip2.c deleted file mode 100644 index 7f0c09a..0000000 --- a/lib/io/compress/bzip2.c +++ /dev/null @@ -1,96 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * bzip2.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#include - -typedef struct { - ostream_comp_t base; - - bz_stream strm; -} ostream_bzip2_t; - -static int flush_inbuf(ostream_comp_t *base, bool finish) -{ - ostream_bzip2_t *bzip2 = (ostream_bzip2_t *)base; - size_t have; - int ret; - - bzip2->strm.next_in = (char *)base->inbuf; - - if (base->inbuf_used > sizeof(base->inbuf)) - base->inbuf_used = sizeof(base->inbuf); - - if ((sizeof(size_t) > sizeof(unsigned int)) && - (base->inbuf_used > (size_t)UINT_MAX)) { - bzip2->strm.avail_in = UINT_MAX; - } else { - bzip2->strm.avail_in = (unsigned int)base->inbuf_used; - } - - for (;;) { - bzip2->strm.next_out = (char *)base->outbuf; - bzip2->strm.avail_out = sizeof(base->outbuf); - - ret = BZ2_bzCompress(&bzip2->strm, finish ? BZ_FINISH : BZ_RUN); - - if (ret < 0 && ret != BZ_OUTBUFF_FULL) { - fprintf(stderr, "%s: internal error in bzip2 " - "compressor.\n", - base->wrapped->get_filename(base->wrapped)); - return -1; - } - - have = sizeof(base->outbuf) - bzip2->strm.avail_out; - - if (base->wrapped->append(base->wrapped, base->outbuf, have)) - return -1; - - if (ret == BZ_STREAM_END || ret == BZ_OUTBUFF_FULL || - bzip2->strm.avail_in == 0) { - break; - } - } - - if (bzip2->strm.avail_in > 0) { - memmove(base->inbuf, bzip2->strm.next_in, - bzip2->strm.avail_in); - } - - base->inbuf_used = bzip2->strm.avail_in; - return 0; -} - -static void cleanup(ostream_comp_t *base) -{ - ostream_bzip2_t *bzip2 = (ostream_bzip2_t *)base; - - BZ2_bzCompressEnd(&bzip2->strm); -} - -ostream_comp_t *ostream_bzip2_create(const char *filename) -{ - ostream_bzip2_t *bzip2 = calloc(1, sizeof(*bzip2)); - ostream_comp_t *base = (ostream_comp_t *)bzip2; - - if (bzip2 == NULL) { - fprintf(stderr, "%s: creating bzip2 compressor: %s.\n", - filename, strerror(errno)); - return NULL; - } - - if (BZ2_bzCompressInit(&bzip2->strm, 9, 0, 30) != BZ_OK) { - fprintf(stderr, "%s: error initializing bzip2 compressor.\n", - filename); - free(bzip2); - return NULL; - } - - base->flush_inbuf = flush_inbuf; - base->cleanup = cleanup; - return base; -} diff --git a/lib/io/compress/gzip.c b/lib/io/compress/gzip.c deleted file mode 100644 index b73a258..0000000 --- a/lib/io/compress/gzip.c +++ /dev/null @@ -1,92 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * gzip.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#include - -typedef struct { - ostream_comp_t base; - - z_stream strm; -} ostream_gzip_t; - -static int flush_inbuf(ostream_comp_t *base, bool finish) -{ - ostream_gzip_t *gzip = (ostream_gzip_t *)base; - size_t have; - int ret; - - if (base->inbuf_used > sizeof(base->inbuf)) - base->inbuf_used = sizeof(base->inbuf); - - if (sizeof(size_t) > sizeof(uInt)) { - gzip->strm.avail_in = ~((uInt)0); - - if ((size_t)gzip->strm.avail_in > base->inbuf_used) - gzip->strm.avail_in = (uInt)base->inbuf_used; - } else { - gzip->strm.avail_in = (uInt)base->inbuf_used; - } - - gzip->strm.next_in = base->inbuf; - - do { - gzip->strm.avail_out = BUFSZ; - gzip->strm.next_out = base->outbuf; - - ret = deflate(&gzip->strm, finish ? Z_FINISH : Z_NO_FLUSH); - - if (ret == Z_STREAM_ERROR) { - fprintf(stderr, - "%s: internal error in gzip compressor.\n", - base->wrapped->get_filename(base->wrapped)); - return -1; - } - - have = BUFSZ - gzip->strm.avail_out; - - if (base->wrapped->append(base->wrapped, base->outbuf, have)) - return -1; - } while (gzip->strm.avail_out == 0); - - base->inbuf_used = 0; - return 0; -} - -static void cleanup(ostream_comp_t *base) -{ - ostream_gzip_t *gzip = (ostream_gzip_t *)base; - - deflateEnd(&gzip->strm); -} - -ostream_comp_t *ostream_gzip_create(const char *filename) -{ - ostream_gzip_t *gzip = calloc(1, sizeof(*gzip)); - ostream_comp_t *base = (ostream_comp_t *)gzip; - int ret; - - if (gzip == NULL) { - fprintf(stderr, "%s: creating gzip wrapper: %s.\n", - filename, strerror(errno)); - return NULL; - } - - ret = deflateInit2(&gzip->strm, 9, Z_DEFLATED, 16 + 15, 8, - Z_DEFAULT_STRATEGY); - if (ret != Z_OK) { - fprintf(stderr, - "%s: internal error creating gzip compressor.\n", - filename); - free(gzip); - return NULL; - } - - base->flush_inbuf = flush_inbuf; - base->cleanup = cleanup; - return base; -} diff --git a/lib/io/compress/ostream_compressor.c b/lib/io/compress/ostream_compressor.c deleted file mode 100644 index a5f16d5..0000000 --- a/lib/io/compress/ostream_compressor.c +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * ostream_compressor.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -static int comp_append(ostream_t *strm, const void *data, size_t size) -{ - ostream_comp_t *comp = (ostream_comp_t *)strm; - size_t diff; - - while (size > 0) { - if (comp->inbuf_used >= BUFSZ) { - if (comp->flush_inbuf(comp, false)) - return -1; - } - - diff = BUFSZ - comp->inbuf_used; - - if (diff > size) - diff = size; - - memcpy(comp->inbuf + comp->inbuf_used, data, diff); - - comp->inbuf_used += diff; - data = (const char *)data + diff; - size -= diff; - } - - return 0; -} - -static int comp_flush(ostream_t *strm) -{ - ostream_comp_t *comp = (ostream_comp_t *)strm; - - if (comp->inbuf_used > 0) { - if (comp->flush_inbuf(comp, true)) - return -1; - } - - return comp->wrapped->flush(comp->wrapped); -} - -static const char *comp_get_filename(ostream_t *strm) -{ - ostream_comp_t *comp = (ostream_comp_t *)strm; - - return comp->wrapped->get_filename(comp->wrapped); -} - -static void comp_destroy(sqfs_object_t *obj) -{ - ostream_comp_t *comp = (ostream_comp_t *)obj; - - comp->cleanup(comp); - sqfs_drop(comp->wrapped); - free(comp); -} - -ostream_t *ostream_compressor_create(ostream_t *strm, int comp_id) -{ - ostream_comp_t *comp = NULL; - ostream_t *base; - - switch (comp_id) { - case IO_COMPRESSOR_GZIP: -#ifdef WITH_GZIP - comp = ostream_gzip_create(strm->get_filename(strm)); -#endif - break; - case IO_COMPRESSOR_XZ: -#ifdef WITH_XZ - comp = ostream_xz_create(strm->get_filename(strm)); -#endif - break; - case IO_COMPRESSOR_ZSTD: -#if defined(WITH_ZSTD) && defined(HAVE_ZSTD_STREAM) - comp = ostream_zstd_create(strm->get_filename(strm)); -#endif - break; - case IO_COMPRESSOR_BZIP2: -#ifdef WITH_BZIP2 - comp = ostream_bzip2_create(strm->get_filename(strm)); -#endif - break; - default: - break; - } - - if (comp == NULL) - return NULL; - - sqfs_object_init(comp, comp_destroy, NULL); - - comp->wrapped = sqfs_grab(strm); - comp->inbuf_used = 0; - - base = (ostream_t *)comp; - base->append = comp_append; - base->flush = comp_flush; - base->get_filename = comp_get_filename; - return base; -} diff --git a/lib/io/compress/xz.c b/lib/io/compress/xz.c deleted file mode 100644 index 65bda0b..0000000 --- a/lib/io/compress/xz.c +++ /dev/null @@ -1,80 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * xz.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#include - -typedef struct { - ostream_comp_t base; - - lzma_stream strm; -} ostream_xz_t; - -static int flush_inbuf(ostream_comp_t *base, bool finish) -{ - ostream_xz_t *xz = (ostream_xz_t *)base; - lzma_ret ret_xz; - size_t have; - - xz->strm.next_in = base->inbuf; - xz->strm.avail_in = base->inbuf_used; - - do { - xz->strm.next_out = base->outbuf; - xz->strm.avail_out = BUFSZ; - - ret_xz = lzma_code(&xz->strm, finish ? LZMA_FINISH : LZMA_RUN); - - if ((ret_xz != LZMA_OK) && (ret_xz != LZMA_STREAM_END)) { - fprintf(stderr, - "%s: internal error in XZ compressor.\n", - base->wrapped->get_filename(base->wrapped)); - return -1; - } - - have = BUFSZ - xz->strm.avail_out; - - if (base->wrapped->append(base->wrapped, base->outbuf, have)) - return -1; - } while (xz->strm.avail_out == 0); - - base->inbuf_used = 0; - return 0; -} - -static void cleanup(ostream_comp_t *base) -{ - ostream_xz_t *xz = (ostream_xz_t *)base; - - lzma_end(&xz->strm); -} - -ostream_comp_t *ostream_xz_create(const char *filename) -{ - ostream_xz_t *xz = calloc(1, sizeof(*xz)); - ostream_comp_t *base = (ostream_comp_t *)xz; - lzma_ret ret_xz; - - if (xz == NULL) { - fprintf(stderr, "%s: creating xz wrapper: %s.\n", - filename, strerror(errno)); - return NULL; - } - - ret_xz = lzma_easy_encoder(&xz->strm, LZMA_PRESET_DEFAULT, - LZMA_CHECK_CRC64); - if (ret_xz != LZMA_OK) { - fprintf(stderr, "%s: error initializing XZ compressor\n", - filename); - free(xz); - return NULL; - } - - base->flush_inbuf = flush_inbuf; - base->cleanup = cleanup; - return base; -} diff --git a/lib/io/compress/zstd.c b/lib/io/compress/zstd.c deleted file mode 100644 index c0b002e..0000000 --- a/lib/io/compress/zstd.c +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * zstd.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#include - -#ifdef HAVE_ZSTD_STREAM -typedef struct { - ostream_comp_t base; - - ZSTD_CStream *strm; -} ostream_zstd_t; - -static int flush_inbuf(ostream_comp_t *base, bool finish) -{ - ostream_zstd_t *zstd = (ostream_zstd_t *)base; - ZSTD_EndDirective op; - ZSTD_outBuffer out; - ZSTD_inBuffer in; - size_t ret; - - op = finish ? ZSTD_e_end : ZSTD_e_continue; - - do { - memset(&in, 0, sizeof(in)); - memset(&out, 0, sizeof(out)); - - in.src = base->inbuf; - in.size = base->inbuf_used; - - out.dst = base->outbuf; - out.size = BUFSZ; - - ret = ZSTD_compressStream2(zstd->strm, &out, &in, op); - - if (ZSTD_isError(ret)) { - fprintf(stderr, "%s: error in zstd compressor.\n", - base->wrapped->get_filename(base->wrapped)); - return -1; - } - - if (base->wrapped->append(base->wrapped, base->outbuf, - out.pos)) { - return -1; - } - - if (in.pos < in.size) { - base->inbuf_used = in.size - in.pos; - - memmove(base->inbuf, base->inbuf + in.pos, - base->inbuf_used); - } else { - base->inbuf_used = 0; - } - } while (finish && ret != 0); - - return 0; -} - -static void cleanup(ostream_comp_t *base) -{ - ostream_zstd_t *zstd = (ostream_zstd_t *)base; - - ZSTD_freeCStream(zstd->strm); -} - -ostream_comp_t *ostream_zstd_create(const char *filename) -{ - ostream_zstd_t *zstd = calloc(1, sizeof(*zstd)); - ostream_comp_t *base = (ostream_comp_t *)zstd; - - if (zstd == NULL) { - fprintf(stderr, "%s: creating zstd wrapper: %s.\n", - filename, strerror(errno)); - return NULL; - } - - zstd->strm = ZSTD_createCStream(); - if (zstd->strm == NULL) { - fprintf(stderr, "%s: error creating zstd decoder.\n", - filename); - free(zstd); - return NULL; - } - - base->flush_inbuf = flush_inbuf; - base->cleanup = cleanup; - return base; -} -#endif /* HAVE_ZSTD_STREAM */ -- cgit v1.2.3