From cdccc69c62579b0c13b35fad0728079652b8f3c9 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Tue, 31 Jan 2023 11:21:30 +0100 Subject: Move library source into src sub-directory Signed-off-by: David Oberhollenzer --- lib/io/src/xfrm/istream.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 lib/io/src/xfrm/istream.c (limited to 'lib/io/src/xfrm/istream.c') diff --git a/lib/io/src/xfrm/istream.c b/lib/io/src/xfrm/istream.c new file mode 100644 index 0000000..4a1ad77 --- /dev/null +++ b/lib/io/src/xfrm/istream.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +typedef struct istream_xfrm_t { + istream_t base; + + istream_t *wrapped; + xfrm_stream_t *xfrm; + + sqfs_u8 uncompressed[BUFSZ]; +} istream_xfrm_t; + +static int xfrm_precache(istream_t *base) +{ + istream_xfrm_t *xfrm = (istream_xfrm_t *)base; + int ret; + + ret = istream_precache(xfrm->wrapped); + if (ret != 0) + return ret; + + for (;;) { + const sqfs_u32 in_sz = xfrm->wrapped->buffer_used; + const sqfs_u32 out_sz = sizeof(xfrm->uncompressed); + sqfs_u32 in_off = 0, out_off = base->buffer_used; + int mode = XFRM_STREAM_FLUSH_NONE; + + if (xfrm->wrapped->eof) + mode = XFRM_STREAM_FLUSH_FULL; + + ret = xfrm->xfrm->process_data(xfrm->xfrm, + xfrm->wrapped->buffer, in_sz, + base->buffer + out_off, + out_sz - out_off, + &in_off, &out_off, mode); + + if (ret == XFRM_STREAM_ERROR) { + fprintf(stderr, "%s: internal error in decompressor.\n", + base->get_filename(base)); + return -1; + } + + base->buffer_used = out_off; + xfrm->wrapped->buffer_offset = in_off; + + if (ret == XFRM_STREAM_BUFFER_FULL || out_off >= out_sz) + break; + + ret = istream_precache(xfrm->wrapped); + if (ret != 0) + return ret; + + if (xfrm->wrapped->eof && xfrm->wrapped->buffer_used == 0) { + if (base->buffer_used == 0) + base->eof = true; + break; + } + } + + return 0; +} + +static const char *xfrm_get_filename(istream_t *strm) +{ + istream_xfrm_t *xfrm = (istream_xfrm_t *)strm; + + return xfrm->wrapped->get_filename(xfrm->wrapped); +} + +static void xfrm_destroy(sqfs_object_t *obj) +{ + istream_xfrm_t *xfrm = (istream_xfrm_t *)obj; + + sqfs_drop(xfrm->xfrm); + sqfs_drop(xfrm->wrapped); + free(xfrm); +} + +istream_t *istream_xfrm_create(istream_t *strm, xfrm_stream_t *xfrm) +{ + istream_xfrm_t *stream = calloc(1, sizeof(*stream)); + istream_t *base = (istream_t *)stream; + + if (stream == NULL) + goto fail; + + sqfs_object_init(stream, xfrm_destroy, NULL); + + stream->wrapped = sqfs_grab(strm); + stream->xfrm = sqfs_grab(xfrm); + + base->precache = xfrm_precache; + base->get_filename = xfrm_get_filename; + base->buffer = stream->uncompressed; + base->eof = false; + return base; +fail: + fprintf(stderr, "%s: error initializing decompressor stream.\n", + strm->get_filename(strm)); + return NULL; +} -- cgit v1.2.3