From cb8b1eebd20a4e8d8596de18d3ea22bd2e94ddc5 Mon Sep 17 00:00:00 2001 From: decafcode Date: Fri, 24 Nov 2023 11:16:23 -0500 Subject: [PATCH] feat(573file): add headered LZ file reader --- 573file/lz-file.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ 573file/lz-file.h | 7 ++++ 573file/meson.build | 2 + 3 files changed, 102 insertions(+) create mode 100644 573file/lz-file.c create mode 100644 573file/lz-file.h diff --git a/573file/lz-file.c b/573file/lz-file.c new file mode 100644 index 0000000..a27c9d4 --- /dev/null +++ b/573file/lz-file.c @@ -0,0 +1,93 @@ +#include +#include +#include + +#include "573file/lz.h" + +#include "util/iobuf.h" +#include "util/log.h" + +int lz_file_read(struct const_iobuf *src, void **out_bytes, + size_t *out_nbytes) { + struct iobuf dest; + uint32_t h_orig_size; + uint32_t h_comp_size; + size_t orig_size; + size_t comp_size; + const void *payload; + void *bytes; + int r; + + assert(src != NULL); + assert(out_bytes != NULL); + assert(out_nbytes != NULL); + + bytes = NULL; + *out_bytes = NULL; + *out_nbytes = 0; + + r = iobuf_read_be32(src, &h_orig_size); + + if (r < 0) { + log_error(r); + + goto end; + } + + r = iobuf_read_be32(src, &h_comp_size); + + if (r < 0) { + log_error(r); + + goto end; + } + + comp_size = src->nbytes - src->pos; + + if (comp_size != h_comp_size) { + r = -EBADMSG; + log_write( + "Compressed size mismatch: Header says %#x bytes, actual size is %#lx", + h_comp_size, (unsigned long)comp_size); + + goto end; + } + + payload = src->bytes + src->pos; + memset(&dest, 0, sizeof(dest)); + lz_dec_decompress(payload, comp_size, &dest); + + orig_size = dest.pos; + + if (orig_size != h_orig_size) { + r = -EBADMSG; + log_write( + "Original size mismatch: Header says %#x bytes, actual size is #%lx", + h_orig_size, (unsigned long)orig_size); + + goto end; + } + + bytes = malloc(orig_size); + + if (bytes == NULL) { + r = -EBADMSG; + + goto end; + } + + dest.bytes = bytes; + dest.nbytes = orig_size; + dest.pos = 0; + + lz_dec_decompress(payload, comp_size, &dest); + + *out_bytes = bytes; + *out_nbytes = orig_size; + bytes = NULL; + +end: + free(bytes); + + return r; +} diff --git a/573file/lz-file.h b/573file/lz-file.h new file mode 100644 index 0000000..7ff8751 --- /dev/null +++ b/573file/lz-file.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +#include "util/iobuf.h" + +int lz_file_read(struct const_iobuf *src, void **out_bytes, size_t *out_nbytes); diff --git a/573file/meson.build b/573file/meson.build index 20b6dd0..5ffaa88 100644 --- a/573file/meson.build +++ b/573file/meson.build @@ -7,6 +7,8 @@ _573file_lib = static_library( 'ifs.h', 'lz.c', 'lz.h', + 'lz-file.c', + 'lz-file.h', 'prop-binary-reader.c', 'prop-binary-reader.h', 'prop-type.c',