diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-06-11 17:59:21 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-06-11 19:29:25 +0200 |
commit | c7eae87870da755586446fecb4eb30063c1d641c (patch) | |
tree | 3b8d1a7846bbe356fc1a3700b57582265760bbca /lib/io/src/xfrm | |
parent | 366ccf20745b23f1eb8554cbe17e6972271de002 (diff) |
libio: move istream buffer logic into interall callbacks
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/io/src/xfrm')
-rw-r--r-- | lib/io/src/xfrm/istream.c | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/lib/io/src/xfrm/istream.c b/lib/io/src/xfrm/istream.c index bad3e22..c9bc41a 100644 --- a/lib/io/src/xfrm/istream.c +++ b/lib/io/src/xfrm/istream.c @@ -12,27 +12,28 @@ typedef struct istream_xfrm_t { istream_t *wrapped; xfrm_stream_t *xfrm; + size_t buffer_offset; + size_t buffer_used; sqfs_u8 uncompressed[BUFSZ]; } istream_xfrm_t; -static int xfrm_precache(istream_t *base) +static int precache(istream_t *base) { istream_xfrm_t *xfrm = (istream_xfrm_t *)base; int ret; - assert(base->buffer >= xfrm->uncompressed); - assert(base->buffer <= (xfrm->uncompressed + BUFSZ)); - assert(base->buffer_used <= BUFSZ); - assert((size_t)(base->buffer - xfrm->uncompressed) <= - (BUFSZ - base->buffer_used)); - - if (base->buffer_used > 0) - memmove(xfrm->uncompressed, base->buffer, base->buffer_used); + if (xfrm->buffer_offset > 0 && + xfrm->buffer_offset < xfrm->buffer_used) { + memmove(xfrm->uncompressed, + xfrm->uncompressed + xfrm->buffer_offset, + xfrm->buffer_used - xfrm->buffer_offset); + } - base->buffer = xfrm->uncompressed; + xfrm->buffer_used -= xfrm->buffer_offset; + xfrm->buffer_offset = 0; for (;;) { - sqfs_u32 in_off = 0, out_off = base->buffer_used; + sqfs_u32 in_off = 0, out_off = xfrm->buffer_used; int mode = XFRM_STREAM_FLUSH_NONE; const sqfs_u8 *ptr; size_t avail; @@ -41,10 +42,8 @@ static int xfrm_precache(istream_t *base) sizeof(xfrm->uncompressed)); if (ret < 0) return ret; - if (ret > 0) { + if (ret > 0) mode = XFRM_STREAM_FLUSH_FULL; - avail = 0; - } ret = xfrm->xfrm->process_data(xfrm->xfrm, ptr, avail, @@ -58,7 +57,7 @@ static int xfrm_precache(istream_t *base) return -1; } - base->buffer_used = out_off; + xfrm->buffer_used = out_off; istream_advance_buffer(xfrm->wrapped, in_off); if (ret == XFRM_STREAM_BUFFER_FULL || out_off >= BUFSZ) @@ -71,6 +70,37 @@ static int xfrm_precache(istream_t *base) return 0; } +static int xfrm_get_buffered_data(istream_t *strm, const sqfs_u8 **out, + size_t *size, size_t want) +{ + istream_xfrm_t *xfrm = (istream_xfrm_t *)strm; + + if (want > BUFSZ) + want = BUFSZ; + + if (xfrm->buffer_used == 0 || + (xfrm->buffer_used - xfrm->buffer_offset) < want) { + int ret = precache(strm); + if (ret) + return ret; + } + + *out = xfrm->uncompressed + xfrm->buffer_offset; + *size = xfrm->buffer_used - xfrm->buffer_offset; + return (*size == 0) ? 1 : 0; +} + +static void xfrm_advance_buffer(istream_t *strm, size_t count) +{ + istream_xfrm_t *xfrm = (istream_xfrm_t *)strm; + + assert(count <= xfrm->buffer_used); + + xfrm->buffer_offset += count; + + assert(xfrm->buffer_offset <= xfrm->buffer_used); +} + static const char *xfrm_get_filename(istream_t *strm) { istream_xfrm_t *xfrm = (istream_xfrm_t *)strm; @@ -100,9 +130,9 @@ istream_t *istream_xfrm_create(istream_t *strm, xfrm_stream_t *xfrm) stream->wrapped = sqfs_grab(strm); stream->xfrm = sqfs_grab(xfrm); - base->precache = xfrm_precache; + base->get_buffered_data = xfrm_get_buffered_data; + base->advance_buffer = xfrm_advance_buffer; base->get_filename = xfrm_get_filename; - base->buffer = stream->uncompressed; return base; fail: fprintf(stderr, "%s: error initializing decompressor stream.\n", |