From 359d71e90050a8b83f7bc7d2ecd4ff29c477cc22 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 26 Jun 2022 22:51:27 +0200 Subject: Cleanup: rename libfstream to libio, split headers Signed-off-by: David Oberhollenzer --- Makefile.am | 2 +- bin/gensquashfs/Makemodule.am | 2 +- bin/rdsquashfs/Makemodule.am | 2 +- bin/sqfs2tar/Makemodule.am | 2 +- bin/sqfs2tar/options.c | 12 +- bin/sqfs2tar/sqfs2tar.h | 2 + bin/sqfsdiff/Makemodule.am | 2 +- bin/tar2sqfs/Makemodule.am | 2 +- bin/tar2sqfs/options.c | 8 +- bin/tar2sqfs/tar2sqfs.c | 4 +- bin/tar2sqfs/tar2sqfs.h | 2 + include/common.h | 4 +- include/compat.h | 2 +- include/fstream.h | 402 -------------------------- include/fstree.h | 2 +- include/io/file.h | 52 ++++ include/io/istream.h | 128 +++++++++ include/io/ostream.h | 138 +++++++++ include/io/std.h | 39 +++ include/io/xfrm.h | 128 +++++++++ include/tar.h | 3 +- lib/fstream/Makemodule.am | 45 --- lib/fstream/compress/bzip2.c | 96 ------- lib/fstream/compress/gzip.c | 92 ------ lib/fstream/compress/ostream_compressor.c | 108 ------- lib/fstream/compress/xz.c | 80 ------ lib/fstream/compress/zstd.c | 94 ------ lib/fstream/compressor.c | 67 ----- lib/fstream/get_line.c | 118 -------- lib/fstream/internal.h | 77 ----- lib/fstream/istream.c | 91 ------ lib/fstream/ostream.c | 84 ------ lib/fstream/printf.c | 30 -- lib/fstream/uncompress/autodetect.c | 55 ---- lib/fstream/uncompress/bzip2.c | 118 -------- lib/fstream/uncompress/gzip.c | 106 ------- lib/fstream/uncompress/istream_compressor.c | 69 ----- lib/fstream/uncompress/xz.c | 96 ------- lib/fstream/uncompress/zstd.c | 81 ------ lib/fstream/unix/istream.c | 124 -------- lib/fstream/unix/ostream.c | 173 ----------- lib/fstream/win32/istream.c | 138 --------- lib/fstream/win32/ostream.c | 197 ------------- lib/fstree/fstree_from_file.c | 2 +- lib/io/Makemodule.am | 45 +++ lib/io/compress/bzip2.c | 96 +++++++ lib/io/compress/gzip.c | 92 ++++++ lib/io/compress/ostream_compressor.c | 108 +++++++ lib/io/compress/xz.c | 80 ++++++ lib/io/compress/zstd.c | 94 ++++++ lib/io/get_line.c | 118 ++++++++ lib/io/internal.h | 81 ++++++ lib/io/istream.c | 91 ++++++ lib/io/ostream.c | 84 ++++++ lib/io/printf.c | 30 ++ lib/io/uncompress/autodetect.c | 55 ++++ lib/io/uncompress/bzip2.c | 118 ++++++++ lib/io/uncompress/gzip.c | 106 +++++++ lib/io/uncompress/istream_compressor.c | 69 +++++ lib/io/uncompress/xz.c | 96 +++++++ lib/io/uncompress/zstd.c | 81 ++++++ lib/io/unix/istream.c | 124 ++++++++ lib/io/unix/ostream.c | 173 +++++++++++ lib/io/win32/istream.c | 138 +++++++++ lib/io/win32/ostream.c | 197 +++++++++++++ lib/io/xfrm.c | 67 +++++ tests/Makemodule.am | 2 +- tests/libfstream/Makemodule.am | 68 ----- tests/libfstream/get_line.c | 166 ----------- tests/libfstream/get_line.txt | 11 - tests/libfstream/uncompress.c | 431 --------------------------- tests/libfstree/Makemodule.am | 12 +- tests/libio/Makemodule.am | 68 +++++ tests/libio/get_line.c | 166 +++++++++++ tests/libio/get_line.txt | 11 + tests/libio/uncompress.c | 432 ++++++++++++++++++++++++++++ tests/libtar/Makemodule.am | 60 ++-- tests/libtar/tar_big_file.c | 1 + tests/libtar/tar_fuzz.c | 1 + tests/libtar/tar_simple.c | 1 + tests/libtar/tar_sparse.c | 1 + tests/libtar/tar_sparse_gnu.c | 1 + tests/libtar/tar_target_filled.c | 1 + tests/libtar/tar_xattr.c | 1 + tests/libtar/tar_xattr_bin.c | 1 + tests/libutil/Makemodule.am | 2 +- tests/libutil/str_table.c | 2 +- 87 files changed, 3382 insertions(+), 3279 deletions(-) delete mode 100644 include/fstream.h create mode 100644 include/io/file.h create mode 100644 include/io/istream.h create mode 100644 include/io/ostream.h create mode 100644 include/io/std.h create mode 100644 include/io/xfrm.h delete mode 100644 lib/fstream/Makemodule.am delete mode 100644 lib/fstream/compress/bzip2.c delete mode 100644 lib/fstream/compress/gzip.c delete mode 100644 lib/fstream/compress/ostream_compressor.c delete mode 100644 lib/fstream/compress/xz.c delete mode 100644 lib/fstream/compress/zstd.c delete mode 100644 lib/fstream/compressor.c delete mode 100644 lib/fstream/get_line.c delete mode 100644 lib/fstream/internal.h delete mode 100644 lib/fstream/istream.c delete mode 100644 lib/fstream/ostream.c delete mode 100644 lib/fstream/printf.c delete mode 100644 lib/fstream/uncompress/autodetect.c delete mode 100644 lib/fstream/uncompress/bzip2.c delete mode 100644 lib/fstream/uncompress/gzip.c delete mode 100644 lib/fstream/uncompress/istream_compressor.c delete mode 100644 lib/fstream/uncompress/xz.c delete mode 100644 lib/fstream/uncompress/zstd.c delete mode 100644 lib/fstream/unix/istream.c delete mode 100644 lib/fstream/unix/ostream.c delete mode 100644 lib/fstream/win32/istream.c delete mode 100644 lib/fstream/win32/ostream.c create mode 100644 lib/io/Makemodule.am create mode 100644 lib/io/compress/bzip2.c create mode 100644 lib/io/compress/gzip.c create mode 100644 lib/io/compress/ostream_compressor.c create mode 100644 lib/io/compress/xz.c create mode 100644 lib/io/compress/zstd.c create mode 100644 lib/io/get_line.c create mode 100644 lib/io/internal.h create mode 100644 lib/io/istream.c create mode 100644 lib/io/ostream.c create mode 100644 lib/io/printf.c create mode 100644 lib/io/uncompress/autodetect.c create mode 100644 lib/io/uncompress/bzip2.c create mode 100644 lib/io/uncompress/gzip.c create mode 100644 lib/io/uncompress/istream_compressor.c create mode 100644 lib/io/uncompress/xz.c create mode 100644 lib/io/uncompress/zstd.c create mode 100644 lib/io/unix/istream.c create mode 100644 lib/io/unix/ostream.c create mode 100644 lib/io/win32/istream.c create mode 100644 lib/io/win32/ostream.c create mode 100644 lib/io/xfrm.c delete mode 100644 tests/libfstream/Makemodule.am delete mode 100644 tests/libfstream/get_line.c delete mode 100644 tests/libfstream/get_line.txt delete mode 100644 tests/libfstream/uncompress.c create mode 100644 tests/libio/Makemodule.am create mode 100644 tests/libio/get_line.c create mode 100644 tests/libio/get_line.txt create mode 100644 tests/libio/uncompress.c diff --git a/Makefile.am b/Makefile.am index 33efeb7..bbb48f0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,7 +29,7 @@ TESTS = include lib/lz4/Makemodule.am include lib/sqfs/Makemodule.am include lib/util/Makemodule.am -include lib/fstream/Makemodule.am +include lib/io/Makemodule.am if BUILD_TOOLS include lib/fstree/Makemodule.am diff --git a/bin/gensquashfs/Makemodule.am b/bin/gensquashfs/Makemodule.am index 11a3535..03f4f4c 100644 --- a/bin/gensquashfs/Makemodule.am +++ b/bin/gensquashfs/Makemodule.am @@ -1,7 +1,7 @@ gensquashfs_SOURCES = bin/gensquashfs/mkfs.c bin/gensquashfs/mkfs.h gensquashfs_SOURCES += bin/gensquashfs/options.c bin/gensquashfs/selinux.c gensquashfs_SOURCES += bin/gensquashfs/dirscan_xattr.c -gensquashfs_LDADD = libcommon.a libsquashfs.la libfstree.a libfstream.a +gensquashfs_LDADD = libcommon.a libsquashfs.la libfstree.a libio.a gensquashfs_LDADD += libcompat.a $(LZO_LIBS) $(PTHREAD_LIBS) gensquashfs_CPPFLAGS = $(AM_CPPFLAGS) gensquashfs_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) diff --git a/bin/rdsquashfs/Makemodule.am b/bin/rdsquashfs/Makemodule.am index 094771c..974e7bc 100644 --- a/bin/rdsquashfs/Makemodule.am +++ b/bin/rdsquashfs/Makemodule.am @@ -4,7 +4,7 @@ rdsquashfs_SOURCES += bin/rdsquashfs/restore_fstree.c bin/rdsquashfs/describe.c rdsquashfs_SOURCES += bin/rdsquashfs/fill_files.c bin/rdsquashfs/dump_xattrs.c rdsquashfs_SOURCES += bin/rdsquashfs/stat.c rdsquashfs_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -rdsquashfs_LDADD = libcommon.a libfstream.a libcompat.a libsquashfs.la +rdsquashfs_LDADD = libcommon.a libio.a libcompat.a libsquashfs.la rdsquashfs_LDADD += libfstree.a $(LZO_LIBS) $(PTHREAD_LIBS) dist_man1_MANS += bin/rdsquashfs/rdsquashfs.1 diff --git a/bin/sqfs2tar/Makemodule.am b/bin/sqfs2tar/Makemodule.am index 5355157..22d523e 100644 --- a/bin/sqfs2tar/Makemodule.am +++ b/bin/sqfs2tar/Makemodule.am @@ -3,7 +3,7 @@ sqfs2tar_SOURCES += bin/sqfs2tar/options.c bin/sqfs2tar/write_tree.c sqfs2tar_SOURCES += bin/sqfs2tar/xattr.c sqfs2tar_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) sqfs2tar_LDADD = libcommon.a libutil.a libsquashfs.la libtar.a -sqfs2tar_LDADD += libfstream.a libcompat.a libfstree.a +sqfs2tar_LDADD += libio.a libcompat.a libfstree.a sqfs2tar_LDADD += $(ZLIB_LIBS) $(XZ_LIBS) $(LZO_LIBS) $(ZSTD_LIBS) $(BZIP2_LIBS) sqfs2tar_LDADD += $(PTHREAD_LIBS) diff --git a/bin/sqfs2tar/options.c b/bin/sqfs2tar/options.c index 1b652b5..4f783e0 100644 --- a/bin/sqfs2tar/options.c +++ b/bin/sqfs2tar/options.c @@ -91,14 +91,14 @@ void process_args(int argc, char **argv) switch (i) { case 'c': - compressor = fstream_compressor_id_from_name(optarg); + compressor = io_compressor_id_from_name(optarg); if (compressor <= 0) { fprintf(stderr, "unknown compressor '%s'.\n", optarg); goto fail; } - if (!fstream_compressor_exists(compressor)) { + if (!io_compressor_exists(compressor)) { fprintf(stderr, "%s compressor is not supported.\n", optarg); @@ -163,11 +163,11 @@ void process_args(int argc, char **argv) case 'h': fputs(usagestr, stdout); - i = FSTREAM_COMPRESSOR_MIN; + i = IO_COMPRESSOR_MIN; - while (i <= FSTREAM_COMPRESSOR_MAX) { - name = fstream_compressor_name_from_id(i); - if (fstream_compressor_exists(i)) + while (i <= IO_COMPRESSOR_MAX) { + name = io_compressor_name_from_id(i); + if (io_compressor_exists(i)) printf("\t%s\n", name); ++i; } diff --git a/bin/sqfs2tar/sqfs2tar.h b/bin/sqfs2tar/sqfs2tar.h index 1986c56..587e8ad 100644 --- a/bin/sqfs2tar/sqfs2tar.h +++ b/bin/sqfs2tar/sqfs2tar.h @@ -11,6 +11,8 @@ #include "common.h" #include "tar.h" +#include "io/xfrm.h" + #include #include #include diff --git a/bin/sqfsdiff/Makemodule.am b/bin/sqfsdiff/Makemodule.am index 8331f25..bd93a74 100644 --- a/bin/sqfsdiff/Makemodule.am +++ b/bin/sqfsdiff/Makemodule.am @@ -4,7 +4,7 @@ sqfsdiff_SOURCES += bin/sqfsdiff/compare_dir.c bin/sqfsdiff/node_compare.c sqfsdiff_SOURCES += bin/sqfsdiff/compare_files.c bin/sqfsdiff/super.c sqfsdiff_SOURCES += bin/sqfsdiff/extract.c sqfsdiff_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -sqfsdiff_LDADD = libcommon.a libsquashfs.la libfstream.a libcompat.a +sqfsdiff_LDADD = libcommon.a libsquashfs.la libio.a libcompat.a sqfsdiff_LDADD += $(LZO_LIBS) libfstree.a $(PTHREAD_LIBS) dist_man1_MANS += bin/sqfsdiff/sqfsdiff.1 diff --git a/bin/tar2sqfs/Makemodule.am b/bin/tar2sqfs/Makemodule.am index 6db3628..818f6e2 100644 --- a/bin/tar2sqfs/Makemodule.am +++ b/bin/tar2sqfs/Makemodule.am @@ -1,7 +1,7 @@ tar2sqfs_SOURCES = bin/tar2sqfs/tar2sqfs.c bin/tar2sqfs/tar2sqfs.h tar2sqfs_SOURCES += bin/tar2sqfs/options.c bin/tar2sqfs/process_tarball.c tar2sqfs_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -tar2sqfs_LDADD = libcommon.a libsquashfs.la libtar.a libfstream.a +tar2sqfs_LDADD = libcommon.a libsquashfs.la libtar.a libio.a tar2sqfs_LDADD += libfstree.a libcompat.a libfstree.a $(LZO_LIBS) tar2sqfs_LDADD += $(ZLIB_LIBS) $(XZ_LIBS) $(ZSTD_LIBS) $(BZIP2_LIBS) tar2sqfs_LDADD += $(PTHREAD_LIBS) diff --git a/bin/tar2sqfs/options.c b/bin/tar2sqfs/options.c index 7727a47..94e7036 100644 --- a/bin/tar2sqfs/options.c +++ b/bin/tar2sqfs/options.c @@ -94,15 +94,15 @@ char *root_becomes = NULL; static void input_compressor_print_available(void) { - int i = FSTREAM_COMPRESSOR_MIN; + int i = IO_COMPRESSOR_MIN; const char *name; fputs("\nSupported tar compression formats:\n", stdout); - while (i <= FSTREAM_COMPRESSOR_MAX) { - name = fstream_compressor_name_from_id(i); + while (i <= IO_COMPRESSOR_MAX) { + name = io_compressor_name_from_id(i); - if (fstream_compressor_exists(i)) + if (io_compressor_exists(i)) printf("\t%s\n", name); ++i; diff --git a/bin/tar2sqfs/tar2sqfs.c b/bin/tar2sqfs/tar2sqfs.c index 603ee25..4e9ade9 100644 --- a/bin/tar2sqfs/tar2sqfs.c +++ b/bin/tar2sqfs/tar2sqfs.c @@ -50,11 +50,11 @@ int main(int argc, char **argv) goto out_if; if (ret > 0) { - if (!fstream_compressor_exists(ret)) { + if (!io_compressor_exists(ret)) { fprintf(stderr, "%s: %s compression is not supported.\n", istream_get_filename(input_file), - fstream_compressor_name_from_id(ret)); + io_compressor_name_from_id(ret)); goto out_if; } diff --git a/bin/tar2sqfs/tar2sqfs.h b/bin/tar2sqfs/tar2sqfs.h index 915d89c..d5a4ada 100644 --- a/bin/tar2sqfs/tar2sqfs.h +++ b/bin/tar2sqfs/tar2sqfs.h @@ -12,6 +12,8 @@ #include "compat.h" #include "tar.h" +#include "io/xfrm.h" + #include #include #include diff --git a/include/common.h b/include/common.h index df3017a..ab07461 100644 --- a/include/common.h +++ b/include/common.h @@ -20,7 +20,9 @@ #include "simple_writer.h" #include "compress_cli.h" -#include "fstream.h" +#include "io/ostream.h" +#include "io/file.h" +#include "io/std.h" #include "compat.h" #include "fstree.h" #include "tar.h" diff --git a/include/compat.h b/include/compat.h index 6b4d83d..8969d6c 100644 --- a/include/compat.h +++ b/include/compat.h @@ -8,7 +8,7 @@ #define COMPAT_H #include "sqfs/predef.h" -#include "fstream.h" +#include "io/ostream.h" #include "config.h" #include diff --git a/include/fstream.h b/include/fstream.h deleted file mode 100644 index 0e8905e..0000000 --- a/include/fstream.h +++ /dev/null @@ -1,402 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * fstream.h - * - * Copyright (C) 2019 David Oberhollenzer - */ -#ifndef FSTREAM_H -#define FSTREAM_H - -#include "sqfs/predef.h" - -#if defined(__GNUC__) || defined(__clang__) -# define PRINTF_ATTRIB(fmt, elipsis) \ - __attribute__ ((format (printf, fmt, elipsis))) -#else -# define PRINTF_ATTRIB(fmt, elipsis) -#endif - -/** - * @struct ostream_t - * - * @extends sqfs_object_t - * - * @brief An append-only data stream. - */ -typedef struct ostream_t { - sqfs_object_t base; - - int (*append)(struct ostream_t *strm, const void *data, size_t size); - - int (*append_sparse)(struct ostream_t *strm, size_t size); - - int (*flush)(struct ostream_t *strm); - - const char *(*get_filename)(struct ostream_t *strm); -} ostream_t; - -/** - * @struct istream_t - * - * @extends sqfs_object_t - * - * @brief A sequential, read-only data stream. - */ -typedef struct istream_t { - sqfs_object_t base; - - size_t buffer_used; - size_t buffer_offset; - bool eof; - - sqfs_u8 *buffer; - - int (*precache)(struct istream_t *strm); - - const char *(*get_filename)(struct istream_t *strm); -} istream_t; - - -enum { - OSTREAM_OPEN_OVERWRITE = 0x01, - OSTREAM_OPEN_SPARSE = 0x02, -}; - -enum { - ISTREAM_LINE_LTRIM = 0x01, - ISTREAM_LINE_RTRIM = 0x02, - ISTREAM_LINE_SKIP_EMPTY = 0x04, -}; - -enum { - /** - * @brief Deflate compressor with gzip headers. - * - * This actually creates a gzip compatible file, including a - * gzip header and trailer. - */ - FSTREAM_COMPRESSOR_GZIP = 1, - - FSTREAM_COMPRESSOR_XZ = 2, - - FSTREAM_COMPRESSOR_ZSTD = 3, - - FSTREAM_COMPRESSOR_BZIP2 = 4, - - FSTREAM_COMPRESSOR_MIN = 1, - FSTREAM_COMPRESSOR_MAX = 4, -}; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Create an output stream that writes to a file. - * - * @memberof ostream_t - * - * If the file does not yet exist, it is created. If it does exist this - * function fails, unless the flag OSTREAM_OPEN_OVERWRITE is set, in which - * case the file is opened and its contents are discarded. - * - * If the flag OSTREAM_OPEN_SPARSE is set, the underlying implementation tries - * to support sparse output files. If the flag is not set, holes will always - * be filled with zero bytes. - * - * @param path A path to the file to open or create. - * @param flags A combination of flags controling how to open/create the file. - * - * @return A pointer to an output stream on success, NULL on failure. - */ -SQFS_INTERNAL ostream_t *ostream_open_file(const char *path, int flags); - -/** - * @brief Create an output stream that writes to standard output. - * - * @memberof ostream_t - * - * @return A pointer to an output stream on success, NULL on failure. - */ -SQFS_INTERNAL ostream_t *ostream_open_stdout(void); - -/** - * @brief Create an input stream that reads from a file. - * - * @memberof istream_t - * - * @param path A path to the file to open or create. - * - * @return A pointer to an output stream on success, NULL on failure. - */ -SQFS_INTERNAL istream_t *istream_open_file(const char *path); - -/** - * @brief Create an input stream that reads from standard input. - * - * @memberof istream_t - * - * @return A pointer to an input stream on success, NULL on failure. - */ -SQFS_INTERNAL istream_t *istream_open_stdin(void); - -/** - * @brief Create an output stream that transparently compresses data. - * - * @memberof ostream_t - * - * This function creates an output stream that transparently compresses all - * data appended to it and writes the compressed data to an underlying, wrapped - * output stream. - * - * The new stream takes ownership of the wrapped stream and destroys it when - * the compressor stream is destroyed. If this function fails, the wrapped - * stream is also destroyed. - * - * @param strm A pointer to another stream that should be wrapped. - * @param comp_id An identifier describing the compressor to use. - * - * @return A pointer to an output stream on success, NULL on failure. - */ -SQFS_INTERNAL ostream_t *ostream_compressor_create(ostream_t *strm, - int comp_id); - -/** - * @brief Create an input stream that transparently uncompresses data. - * - * @memberof istream_t - * - * This function creates an input stream that wraps an underlying input stream - * that is compressed and transparently uncompresses the data when reading - * from it. - * - * The new stream takes ownership of the wrapped stream and destroys it when - * the compressor stream is destroyed. If this function fails, the wrapped - * stream is also destroyed. - * - * @param strm A pointer to another stream that should be wrapped. - * @param comp_id An identifier describing the compressor to use. - * - * @return A pointer to an input stream on success, NULL on failure. - */ -SQFS_INTERNAL istream_t *istream_compressor_create(istream_t *strm, - int comp_id); - -/** - * @brief Probe the buffered data in an istream to check if it is compressed. - * - * @memberof istream_t - * - * This function peeks into the internal buffer of an input stream to check - * for magic signatures of various compressors. - * - * @param strm A pointer to an input stream to check - * @param probe A callback used to check if raw/decoded data matches an - * expected format. Returns 0 if not, -1 on failure and +1 - * on success. - * - * @return A compressor ID on success, 0 if no match was found, -1 on failure. - */ -SQFS_INTERNAL int istream_detect_compressor(istream_t *strm, - int (*probe)(const sqfs_u8 *data, - size_t size)); - -/** - * @brief Append a block of data to an output stream. - * - * @memberof ostream_t - * - * @param strm A pointer to an output stream. - * @param data A pointer to the data block to append. - * @param size The number of bytes to append. - * - * @return Zero on success, -1 on failure. - */ -SQFS_INTERNAL int ostream_append(ostream_t *strm, const void *data, - size_t size); - -/** - * @brief Append a number of zero bytes to an output stream. - * - * @memberof ostream_t - * - * If the unerlying implementation supports sparse files, this function can be - * used to create a "hole". If the implementation does not support it, a - * fallback is used that just appends a block of zeros manualy. - * - * @param strm A pointer to an output stream. - * @param size The number of zero bytes to append. - * - * @return Zero on success, -1 on failure. - */ -SQFS_INTERNAL int ostream_append_sparse(ostream_t *strm, size_t size); - -/** - * @brief Process all pending, buffered data and flush it to disk. - * - * @memberof ostream_t - * - * If the stream performs some kind of transformation (e.g. transparent data - * compression), flushing caues the wrapped format to insert a termination - * token. Only call this function when you are absolutely DONE appending data, - * shortly before destroying the stream. - * - * @param strm A pointer to an output stream. - * - * @return Zero on success, -1 on failure. - */ -SQFS_INTERNAL int ostream_flush(ostream_t *strm); - -/** - * @brief Get the underlying filename of a output stream. - * - * @memberof ostream_t - * - * @param strm The output stream to get the filename from. - * - * @return A string holding the underlying filename. - */ -SQFS_INTERNAL const char *ostream_get_filename(ostream_t *strm); - -/** - * @brief Printf like function that appends to an output stream - * - * @memberof ostream_t - * - * @param strm The output stream to append to. - * @param fmt A printf style format string. - * - * @return The number of characters written on success, -1 on failure. - */ -SQFS_INTERNAL int ostream_printf(ostream_t *strm, const char *fmt, ...) - PRINTF_ATTRIB(2, 3); - -/** - * @brief Read a line of text from an input stream - * - * @memberof istream_t - * - * The line returned is allocated using malloc and must subsequently be - * freed when it is no longer needed. The line itself is always null-terminated - * and never includes the line break characters (LF or CR-LF). - * - * If the flag @ref ISTREAM_LINE_LTRIM is set, leading white space characters - * are removed. If the flag @ref ISTREAM_LINE_RTRIM is set, trailing white space - * characters are remvoed. - * - * If the flag @ref ISTREAM_LINE_SKIP_EMPTY is set and a line is discovered to - * be empty (after the optional trimming), the function discards the empty line - * and retries. The given line_num pointer is used to increment the line - * number. - * - * @param strm A pointer to an input stream. - * @param out Returns a pointer to a line on success. - * @param line_num This is incremented if lines are skipped. - * @param flags A combination of flags controling the functions behaviour. - * - * @return Zero on success, a negative value on error, a positive value if - * end-of-file was reached without reading any data. - */ -SQFS_INTERNAL int istream_get_line(istream_t *strm, char **out, - size_t *line_num, int flags); - -/** - * @brief Read data from an input stream - * - * @memberof istream_t - * - * @param strm A pointer to an input stream. - * @param data A buffer to read into. - * @param size The number of bytes to read into the buffer. - * - * @return The number of bytes actually read on success, -1 on failure, - * 0 on end-of-file. - */ -SQFS_INTERNAL sqfs_s32 istream_read(istream_t *strm, void *data, size_t size); - -/** - * @brief Adjust and refill the internal buffer of an input stream - * - * @memberof istream_t - * - * This function resets the buffer offset of an input stream (moving any unread - * data up front if it has to) and calls an internal callback of the input - * stream to fill the rest of the buffer to the extent possible. - * - * @param strm A pointer to an input stream. - * - * @return 0 on success, -1 on failure. - */ -SQFS_INTERNAL int istream_precache(istream_t *strm); - -/** - * @brief Get the underlying filename of an input stream. - * - * @memberof istream_t - * - * @param strm The input stream to get the filename from. - * - * @return A string holding the underlying filename. - */ -SQFS_INTERNAL const char *istream_get_filename(istream_t *strm); - -/** - * @brief Skip over a number of bytes in an input stream. - * - * @memberof istream_t - * - * @param strm A pointer to an input stream. - * @param size The number of bytes to seek forward. - * - * @return Zero on success, -1 on failure. - */ -SQFS_INTERNAL int istream_skip(istream_t *strm, sqfs_u64 size); - -/** - * @brief Read data from an input stream and append it to an output stream - * - * @memberof ostream_t - * - * @param out A pointer to an output stream to append to. - * @param in A pointer to an input stream to read from. - * @param size The number of bytes to copy over. - * - * @return The number of bytes copied on success, -1 on failure, - * 0 on end-of-file. - */ -SQFS_INTERNAL sqfs_s32 ostream_append_from_istream(ostream_t *out, - istream_t *in, - sqfs_u32 size); - -/** - * @brief Resolve a compressor name to an ID. - * - * @param name A compressor name. - * - * @return A compressor ID on success, -1 on failure. - */ -SQFS_INTERNAL int fstream_compressor_id_from_name(const char *name); - -/** - * @brief Resolve a id to a compressor name. - * - * @param id A compressor ID. - * - * @return A compressor name on success, NULL on failure. - */ -SQFS_INTERNAL const char *fstream_compressor_name_from_id(int id); - -/** - * @brief Check if support for a given compressor has been built in. - * - * @param id A compressor ID. - * - * @return True if the compressor is supported, false if not. - */ -SQFS_INTERNAL bool fstream_compressor_exists(int id); - -#ifdef __cplusplus -} -#endif - -#endif /* FSTREAM_H */ diff --git a/include/fstree.h b/include/fstree.h index 58936d7..3fb4f47 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -15,7 +15,7 @@ #include #include "sqfs/predef.h" -#include "fstream.h" +#include "io/istream.h" #include "compat.h" enum { diff --git a/include/io/file.h b/include/io/file.h new file mode 100644 index 0000000..8c6e851 --- /dev/null +++ b/include/io/file.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * file.h + * + * Copyright (C) 2019 David Oberhollenzer + */ +#ifndef IO_FILE_H +#define IO_FILE_H + +#include "io/istream.h" +#include "io/ostream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create an input stream that reads from a file. + * + * @memberof istream_t + * + * @param path A path to the file to open or create. + * + * @return A pointer to an output stream on success, NULL on failure. + */ +SQFS_INTERNAL istream_t *istream_open_file(const char *path); + +/** + * @brief Create an output stream that writes to a file. + * + * @memberof ostream_t + * + * If the file does not yet exist, it is created. If it does exist this + * function fails, unless the flag OSTREAM_OPEN_OVERWRITE is set, in which + * case the file is opened and its contents are discarded. + * + * If the flag OSTREAM_OPEN_SPARSE is set, the underlying implementation tries + * to support sparse output files. If the flag is not set, holes will always + * be filled with zero bytes. + * + * @param path A path to the file to open or create. + * @param flags A combination of flags controling how to open/create the file. + * + * @return A pointer to an output stream on success, NULL on failure. + */ +SQFS_INTERNAL ostream_t *ostream_open_file(const char *path, int flags); + +#ifdef __cplusplus +} +#endif + +#endif /* IO_FILE_H */ diff --git a/include/io/istream.h b/include/io/istream.h new file mode 100644 index 0000000..567d7e3 --- /dev/null +++ b/include/io/istream.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream.h + * + * Copyright (C) 2019 David Oberhollenzer + */ +#ifndef IO_ISTREAM_H +#define IO_ISTREAM_H + +#include "sqfs/predef.h" + +/** + * @struct istream_t + * + * @extends sqfs_object_t + * + * @brief A sequential, read-only data stream. + */ +typedef struct istream_t { + sqfs_object_t base; + + size_t buffer_used; + size_t buffer_offset; + bool eof; + + sqfs_u8 *buffer; + + int (*precache)(struct istream_t *strm); + + const char *(*get_filename)(struct istream_t *strm); +} istream_t; + +enum { + ISTREAM_LINE_LTRIM = 0x01, + ISTREAM_LINE_RTRIM = 0x02, + ISTREAM_LINE_SKIP_EMPTY = 0x04, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Read a line of text from an input stream + * + * @memberof istream_t + * + * The line returned is allocated using malloc and must subsequently be + * freed when it is no longer needed. The line itself is always null-terminated + * and never includes the line break characters (LF or CR-LF). + * + * If the flag @ref ISTREAM_LINE_LTRIM is set, leading white space characters + * are removed. If the flag @ref ISTREAM_LINE_RTRIM is set, trailing white space + * characters are remvoed. + * + * If the flag @ref ISTREAM_LINE_SKIP_EMPTY is set and a line is discovered to + * be empty (after the optional trimming), the function discards the empty line + * and retries. The given line_num pointer is used to increment the line + * number. + * + * @param strm A pointer to an input stream. + * @param out Returns a pointer to a line on success. + * @param line_num This is incremented if lines are skipped. + * @param flags A combination of flags controling the functions behaviour. + * + * @return Zero on success, a negative value on error, a positive value if + * end-of-file was reached without reading any data. + */ +SQFS_INTERNAL int istream_get_line(istream_t *strm, char **out, + size_t *line_num, int flags); + +/** + * @brief Read data from an input stream + * + * @memberof istream_t + * + * @param strm A pointer to an input stream. + * @param data A buffer to read into. + * @param size The number of bytes to read into the buffer. + * + * @return The number of bytes actually read on success, -1 on failure, + * 0 on end-of-file. + */ +SQFS_INTERNAL sqfs_s32 istream_read(istream_t *strm, void *data, size_t size); + +/** + * @brief Adjust and refill the internal buffer of an input stream + * + * @memberof istream_t + * + * This function resets the buffer offset of an input stream (moving any unread + * data up front if it has to) and calls an internal callback of the input + * stream to fill the rest of the buffer to the extent possible. + * + * @param strm A pointer to an input stream. + * + * @return 0 on success, -1 on failure. + */ +SQFS_INTERNAL int istream_precache(istream_t *strm); + +/** + * @brief Get the underlying filename of an input stream. + * + * @memberof istream_t + * + * @param strm The input stream to get the filename from. + * + * @return A string holding the underlying filename. + */ +SQFS_INTERNAL const char *istream_get_filename(istream_t *strm); + +/** + * @brief Skip over a number of bytes in an input stream. + * + * @memberof istream_t + * + * @param strm A pointer to an input stream. + * @param size The number of bytes to seek forward. + * + * @return Zero on success, -1 on failure. + */ +SQFS_INTERNAL int istream_skip(istream_t *strm, sqfs_u64 size); + +#ifdef __cplusplus +} +#endif + +#endif /* IO_ISTREAM_H */ diff --git a/include/io/ostream.h b/include/io/ostream.h new file mode 100644 index 0000000..15585f9 --- /dev/null +++ b/include/io/ostream.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * ostream.h + * + * Copyright (C) 2019 David Oberhollenzer + */ +#ifndef IO_OSTREAM_H +#define IO_OSTREAM_H + +#include "sqfs/predef.h" +#include "io/istream.h" + +#if defined(__GNUC__) || defined(__clang__) +# define PRINTF_ATTRIB(fmt, elipsis) \ + __attribute__ ((format (printf, fmt, elipsis))) +#else +# define PRINTF_ATTRIB(fmt, elipsis) +#endif + +/** + * @struct ostream_t + * + * @extends sqfs_object_t + * + * @brief An append-only data stream. + */ +typedef struct ostream_t { + sqfs_object_t base; + + int (*append)(struct ostream_t *strm, const void *data, size_t size); + + int (*append_sparse)(struct ostream_t *strm, size_t size); + + int (*flush)(struct ostream_t *strm); + + const char *(*get_filename)(struct ostream_t *strm); +} ostream_t; + +enum { + OSTREAM_OPEN_OVERWRITE = 0x01, + OSTREAM_OPEN_SPARSE = 0x02, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Append a block of data to an output stream. + * + * @memberof ostream_t + * + * @param strm A pointer to an output stream. + * @param data A pointer to the data block to append. + * @param size The number of bytes to append. + * + * @return Zero on success, -1 on failure. + */ +SQFS_INTERNAL int ostream_append(ostream_t *strm, const void *data, + size_t size); + +/** + * @brief Append a number of zero bytes to an output stream. + * + * @memberof ostream_t + * + * If the unerlying implementation supports sparse files, this function can be + * used to create a "hole". If the implementation does not support it, a + * fallback is used that just appends a block of zeros manualy. + * + * @param strm A pointer to an output stream. + * @param size The number of zero bytes to append. + * + * @return Zero on success, -1 on failure. + */ +SQFS_INTERNAL int ostream_append_sparse(ostream_t *strm, size_t size); + +/** + * @brief Process all pending, buffered data and flush it to disk. + * + * @memberof ostream_t + * + * If the stream performs some kind of transformation (e.g. transparent data + * compression), flushing caues the wrapped format to insert a termination + * token. Only call this function when you are absolutely DONE appending data, + * shortly before destroying the stream. + * + * @param strm A pointer to an output stream. + * + * @return Zero on success, -1 on failure. + */ +SQFS_INTERNAL int ostream_flush(ostream_t *strm); + +/** + * @brief Get the underlying filename of a output stream. + * + * @memberof ostream_t + * + * @param strm The output stream to get the filename from. + * + * @return A string holding the underlying filename. + */ +SQFS_INTERNAL const char *ostream_get_filename(ostream_t *strm); + +/** + * @brief Printf like function that appends to an output stream + * + * @memberof ostream_t + * + * @param strm The output stream to append to. + * @param fmt A printf style format string. + * + * @return The number of characters written on success, -1 on failure. + */ +SQFS_INTERNAL int ostream_printf(ostream_t *strm, const char *fmt, ...) + PRINTF_ATTRIB(2, 3); + +/** + * @brief Read data from an input stream and append it to an output stream + * + * @memberof ostream_t + * + * @param out A pointer to an output stream to append to. + * @param in A pointer to an input stream to read from. + * @param size The number of bytes to copy over. + * + * @return The number of bytes copied on success, -1 on failure, + * 0 on end-of-file. + */ +SQFS_INTERNAL sqfs_s32 ostream_append_from_istream(ostream_t *out, + istream_t *in, + sqfs_u32 size); + +#ifdef __cplusplus +} +#endif + +#endif /* IO_OSTREAM_H */ diff --git a/include/io/std.h b/include/io/std.h new file mode 100644 index 0000000..805bebd --- /dev/null +++ b/include/io/std.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * std.h + * + * Copyright (C) 2019 David Oberhollenzer + */ +#ifndef IO_STD_H +#define IO_STD_H + +#include "io/istream.h" +#include "io/ostream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create an input stream that reads from standard input. + * + * @memberof istream_t + * + * @return A pointer to an input stream on success, NULL on failure. + */ +SQFS_INTERNAL istream_t *istream_open_stdin(void); + +/** + * @brief Create an output stream that writes to standard output. + * + * @memberof ostream_t + * + * @return A pointer to an output stream on success, NULL on failure. + */ +SQFS_INTERNAL ostream_t *ostream_open_stdout(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IO_STD_H */ diff --git a/include/io/xfrm.h b/include/io/xfrm.h new file mode 100644 index 0000000..22a42b6 --- /dev/null +++ b/include/io/xfrm.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * xfrm.h + * + * Copyright (C) 2019 David Oberhollenzer + */ +#ifndef IO_XFRM_H +#define IO_XFRM_H + +#include "io/istream.h" +#include "io/ostream.h" + +enum { + /** + * @brief Deflate compressor with gzip headers. + * + * This actually creates a gzip compatible file, including a + * gzip header and trailer. + */ + IO_COMPRESSOR_GZIP = 1, + + IO_COMPRESSOR_XZ = 2, + + IO_COMPRESSOR_ZSTD = 3, + + IO_COMPRESSOR_BZIP2 = 4, + + IO_COMPRESSOR_MIN = 1, + IO_COMPRESSOR_MAX = 4, +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create an input stream that transparently uncompresses data. + * + * @memberof istream_t + * + * This function creates an input stream that wraps an underlying input stream + * that is compressed and transparently uncompresses the data when reading + * from it. + * + * The new stream takes ownership of the wrapped stream and destroys it when + * the compressor stream is destroyed. If this function fails, the wrapped + * stream is also destroyed. + * + * @param strm A pointer to another stream that should be wrapped. + * @param comp_id An identifier describing the compressor to use. + * + * @return A pointer to an input stream on success, NULL on failure. + */ +SQFS_INTERNAL istream_t *istream_compressor_create(istream_t *strm, + int comp_id); + +/** + * @brief Create an output stream that transparently compresses data. + * + * @memberof ostream_t + * + * This function creates an output stream that transparently compresses all + * data appended to it and writes the compressed data to an underlying, wrapped + * output stream. + * + * The new stream takes ownership of the wrapped stream and destroys it when + * the compressor stream is destroyed. If this function fails, the wrapped + * stream is also destroyed. + * + * @param strm A pointer to another stream that should be wrapped. + * @param comp_id An identifier describing the compressor to use. + * + * @return A pointer to an output stream on success, NULL on failure. + */ +SQFS_INTERNAL ostream_t *ostream_compressor_create(ostream_t *strm, + int comp_id); + +/** + * @brief Probe the buffered data in an istream to check if it is compressed. + * + * @memberof istream_t + * + * This function peeks into the internal buffer of an input stream to check + * for magic signatures of various compressors. + * + * @param strm A pointer to an input stream to check + * @param probe A callback used to check if raw/decoded data matches an + * expected format. Returns 0 if not, -1 on failure and +1 + * on success. + * + * @return A compressor ID on success, 0 if no match was found, -1 on failure. + */ +SQFS_INTERNAL int istream_detect_compressor(istream_t *strm, + int (*probe)(const sqfs_u8 *data, + size_t size)); + +/** + * @brief Resolve a compressor name to an ID. + * + * @param name A compressor name. + * + * @return A compressor ID on success, -1 on failure. + */ +SQFS_INTERNAL int io_compressor_id_from_name(const char *name); + +/** + * @brief Resolve a id to a compressor name. + * + * @param id A compressor ID. + * + * @return A compressor name on success, NULL on failure. + */ +SQFS_INTERNAL const char *io_compressor_name_from_id(int id); + +/** + * @brief Check if support for a given compressor has been built in. + * + * @param id A compressor ID. + * + * @return True if the compressor is supported, false if not. + */ +SQFS_INTERNAL bool io_compressor_exists(int id); + +#ifdef __cplusplus +} +#endif + +#endif /* IO_XFRM_H */ diff --git a/include/tar.h b/include/tar.h index 41be57f..dadc16e 100644 --- a/include/tar.h +++ b/include/tar.h @@ -9,7 +9,8 @@ #include "config.h" #include "compat.h" -#include "fstream.h" +#include "io/istream.h" +#include "io/ostream.h" #include #include diff --git a/lib/fstream/Makemodule.am b/lib/fstream/Makemodule.am deleted file mode 100644 index ad5f426..0000000 --- a/lib/fstream/Makemodule.am +++ /dev/null @@ -1,45 +0,0 @@ -libfstream_a_SOURCES = include/fstream.h -libfstream_a_SOURCES += lib/fstream/internal.h -libfstream_a_SOURCES += lib/fstream/ostream.c lib/fstream/printf.c -libfstream_a_SOURCES += lib/fstream/istream.c lib/fstream/get_line.c -libfstream_a_SOURCES += lib/fstream/compressor.c -libfstream_a_SOURCES += lib/fstream/compress/ostream_compressor.c -libfstream_a_SOURCES += lib/fstream/uncompress/istream_compressor.c -libfstream_a_SOURCES += lib/fstream/uncompress/autodetect.c -libfstream_a_CFLAGS = $(AM_CFLAGS) $(ZLIB_CFLAGS) $(XZ_CFLAGS) -libfstream_a_CFLAGS += $(ZSTD_CFLAGS) $(BZIP2_CFLAGS) -libfstream_a_CPPFLAGS = $(AM_CPPFLAGS) - -if WINDOWS -libfstream_a_SOURCES += lib/fstream/win32/ostream.c -libfstream_a_SOURCES += lib/fstream/win32/istream.c -libfstream_a_CFLAGS += -DWINVER=0x0600 -D_WIN32_WINNT=0x0600 -else -libfstream_a_SOURCES += lib/fstream/unix/ostream.c -libfstream_a_SOURCES += lib/fstream/unix/istream.c -endif - -if WITH_XZ -libfstream_a_SOURCES += lib/fstream/compress/xz.c lib/fstream/uncompress/xz.c -libfstream_a_CPPFLAGS += -DWITH_XZ -endif - -if WITH_GZIP -libfstream_a_SOURCES += lib/fstream/compress/gzip.c -libfstream_a_SOURCES += lib/fstream/uncompress/gzip.c -libfstream_a_CPPFLAGS += -DWITH_GZIP -endif - -if WITH_ZSTD -libfstream_a_SOURCES += lib/fstream/compress/zstd.c -libfstream_a_SOURCES += lib/fstream/uncompress/zstd.c -libfstream_a_CPPFLAGS += -DWITH_ZSTD -endif - -if WITH_BZIP2 -libfstream_a_SOURCES += lib/fstream/compress/bzip2.c -libfstream_a_SOURCES += lib/fstream/uncompress/bzip2.c -libfstream_a_CPPFLAGS += -DWITH_BZIP2 -endif - -noinst_LIBRARIES += libfstream.a diff --git a/lib/fstream/compress/bzip2.c b/lib/fstream/compress/bzip2.c deleted file mode 100644 index 7f0c09a..0000000 --- a/lib/fstream/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/fstream/compress/gzip.c b/lib/fstream/compress/gzip.c deleted file mode 100644 index b73a258..0000000 --- a/lib/fstream/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/fstream/compress/ostream_compressor.c b/lib/fstream/compress/ostream_compressor.c deleted file mode 100644 index 30ff7eb..0000000 --- a/lib/fstream/compress/ostream_compressor.c +++ /dev/null @@ -1,108 +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_destroy(comp->wrapped); - free(comp); -} - -ostream_t *ostream_compressor_create(ostream_t *strm, int comp_id) -{ - ostream_comp_t *comp = NULL; - sqfs_object_t *obj; - ostream_t *base; - - switch (comp_id) { - case FSTREAM_COMPRESSOR_GZIP: -#ifdef WITH_GZIP - comp = ostream_gzip_create(strm->get_filename(strm)); -#endif - break; - case FSTREAM_COMPRESSOR_XZ: -#ifdef WITH_XZ - comp = ostream_xz_create(strm->get_filename(strm)); -#endif - break; - case FSTREAM_COMPRESSOR_ZSTD: -#if defined(WITH_ZSTD) && defined(HAVE_ZSTD_STREAM) - comp = ostream_zstd_create(strm->get_filename(strm)); -#endif - break; - case FSTREAM_COMPRESSOR_BZIP2: -#ifdef WITH_BZIP2 - comp = ostream_bzip2_create(strm->get_filename(strm)); -#endif - break; - default: - break; - } - - if (comp == NULL) - return NULL; - - comp->wrapped = strm; - comp->inbuf_used = 0; - - base = (ostream_t *)comp; - base->append = comp_append; - base->flush = comp_flush; - base->get_filename = comp_get_filename; - - obj = (sqfs_object_t *)comp; - obj->destroy = comp_destroy; - return base; -} diff --git a/lib/fstream/compress/xz.c b/lib/fstream/compress/xz.c deleted file mode 100644 index 65bda0b..0000000 --- a/lib/fstream/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/fstream/compress/zstd.c b/lib/fstream/compress/zstd.c deleted file mode 100644 index c0b002e..0000000 --- a/lib/fstream/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 */ diff --git a/lib/fstream/compressor.c b/lib/fstream/compressor.c deleted file mode 100644 index 48f9567..0000000 --- a/lib/fstream/compressor.c +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * compressor.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "internal.h" - -int fstream_compressor_id_from_name(const char *name) -{ - if (strcmp(name, "gzip") == 0) - return FSTREAM_COMPRESSOR_GZIP; - - if (strcmp(name, "xz") == 0) - return FSTREAM_COMPRESSOR_XZ; - - if (strcmp(name, "zstd") == 0) - return FSTREAM_COMPRESSOR_ZSTD; - - if (strcmp(name, "bzip2") == 0) - return FSTREAM_COMPRESSOR_BZIP2; - - return -1; -} - -const char *fstream_compressor_name_from_id(int id) -{ - if (id == FSTREAM_COMPRESSOR_GZIP) - return "gzip"; - - if (id == FSTREAM_COMPRESSOR_XZ) - return "xz"; - - if (id == FSTREAM_COMPRESSOR_ZSTD) - return "zstd"; - - if (id == FSTREAM_COMPRESSOR_BZIP2) - return "bzip2"; - - return NULL; -} - -bool fstream_compressor_exists(int id) -{ - switch (id) { -#ifdef WITH_GZIP - case FSTREAM_COMPRESSOR_GZIP: - return true; -#endif -#ifdef WITH_XZ - case FSTREAM_COMPRESSOR_XZ: - return true; -#endif -#if defined(WITH_ZSTD) && defined(HAVE_ZSTD_STREAM) - case FSTREAM_COMPRESSOR_ZSTD: - return true; -#endif -#ifdef WITH_BZIP2 - case FSTREAM_COMPRESSOR_BZIP2: - return true; -#endif - default: - break; - } - - return false; -} diff --git a/lib/fstream/get_line.c b/lib/fstream/get_line.c deleted file mode 100644 index f7e0b59..0000000 --- a/lib/fstream/get_line.c +++ /dev/null @@ -1,118 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * get_line.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "internal.h" - -static void ltrim(char *buffer) -{ - size_t i = 0; - - while (isspace(buffer[i])) - ++i; - - if (i > 0) - memmove(buffer, buffer + i, strlen(buffer + i) + 1); -} - -static void rtrim(char *buffer) -{ - size_t i = strlen(buffer); - - while (i > 0 && isspace(buffer[i - 1])) - --i; - - buffer[i] = '\0'; -} - -static size_t trim(char *buffer, int flags) -{ - if (flags & ISTREAM_LINE_LTRIM) - ltrim(buffer); - - if (flags & ISTREAM_LINE_RTRIM) - rtrim(buffer); - - return strlen(buffer); -} - -int istream_get_line(istream_t *strm, char **out, - size_t *line_num, int flags) -{ - char *line = NULL, *new; - size_t i, line_len = 0; - bool have_line = false; - - *out = NULL; - - for (;;) { - if (istream_precache(strm)) - return -1; - - if (strm->buffer_used == 0) { - if (line_len == 0) - goto out_eof; - - line_len = trim(line, flags); - - if (line_len == 0 && - (flags & ISTREAM_LINE_SKIP_EMPTY)) { - goto out_eof; - } - break; - } - - for (i = 0; i < strm->buffer_used; ++i) { - if (strm->buffer[i] == '\n') - break; - } - - if (i < strm->buffer_used) { - have_line = true; - strm->buffer_offset = i + 1; - - if (i > 0 && strm->buffer[i - 1] == '\r') - --i; - } else { - strm->buffer_offset = i; - } - - new = realloc(line, line_len + i + 1); - if (new == NULL) - goto fail_errno; - - line = new; - memcpy(line + line_len, strm->buffer, i); - line_len += i; - line[line_len] = '\0'; - - if (have_line) { - line_len = trim(line, flags); - - if (line_len == 0 && - (flags & ISTREAM_LINE_SKIP_EMPTY)) { - free(line); - line = NULL; - have_line = false; - *line_num += 1; - continue; - } - break; - } - } - - *out = line; - return 0; -fail_errno: - fprintf(stderr, "%s: " PRI_SZ ": %s.\n", strm->get_filename(strm), - *line_num, strerror(errno)); - free(line); - *out = NULL; - return -1; -out_eof: - free(line); - *out = NULL; - return 1; -} diff --git a/lib/fstream/internal.h b/lib/fstream/internal.h deleted file mode 100644 index 4f02f8c..0000000 --- a/lib/fstream/internal.h +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * internal.h - * - * Copyright (C) 2019 David Oberhollenzer - */ -#ifndef INTERNAL_H -#define INTERNAL_H - -#include "config.h" -#include "compat.h" -#include "fstream.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFSZ (262144) - -typedef struct ostream_comp_t { - ostream_t base; - - ostream_t *wrapped; - - size_t inbuf_used; - - sqfs_u8 inbuf[BUFSZ]; - sqfs_u8 outbuf[BUFSZ]; - - int (*flush_inbuf)(struct ostream_comp_t *ostrm, bool finish); - - void (*cleanup)(struct ostream_comp_t *ostrm); -} ostream_comp_t; - -typedef struct istream_comp_t { - istream_t base; - - istream_t *wrapped; - - sqfs_u8 uncompressed[BUFSZ]; - - bool eof; - - void (*cleanup)(struct istream_comp_t *strm); -} istream_comp_t; - -#ifdef __cplusplus -extern "C" { -#endif - -SQFS_INTERNAL ostream_comp_t *ostream_gzip_create(const char *filename); - -SQFS_INTERNAL ostream_comp_t *ostream_xz_create(const char *filename); - -SQFS_INTERNAL ostream_comp_t *ostream_zstd_create(const char *filename); - -SQFS_INTERNAL ostream_comp_t *ostream_bzip2_create(const char *filename); - -SQFS_INTERNAL istream_comp_t *istream_gzip_create(const char *filename); - -SQFS_INTERNAL istream_comp_t *istream_xz_create(const char *filename); - -SQFS_INTERNAL istream_comp_t *istream_zstd_create(const char *filename); - -SQFS_INTERNAL istream_comp_t *istream_bzip2_create(const char *filename); - -#ifdef __cplusplus -} -#endif - -#endif /* INTERNAL_H */ diff --git a/lib/fstream/istream.c b/lib/fstream/istream.c deleted file mode 100644 index 6318a23..0000000 --- a/lib/fstream/istream.c +++ /dev/null @@ -1,91 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * istream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "internal.h" - - -sqfs_s32 istream_read(istream_t *strm, void *data, size_t size) -{ - sqfs_s32 total = 0; - size_t diff; - - if (size > 0x7FFFFFFF) - size = 0x7FFFFFFF; - - while (size > 0) { - if (strm->buffer_offset >= strm->buffer_used) { - if (istream_precache(strm)) - return -1; - - if (strm->buffer_used == 0) - break; - } - - diff = strm->buffer_used - strm->buffer_offset; - if (diff > size) - diff = size; - - memcpy(data, strm->buffer + strm->buffer_offset, diff); - data = (char *)data + diff; - strm->buffer_offset += diff; - size -= diff; - total += diff; - } - - return total; -} - -int istream_precache(istream_t *strm) -{ - if (strm->buffer_offset >= strm->buffer_used) { - strm->buffer_offset = 0; - strm->buffer_used = 0; - } else if (strm->buffer_offset > 0) { - memmove(strm->buffer, - strm->buffer + strm->buffer_offset, - strm->buffer_used - strm->buffer_offset); - - strm->buffer_used -= strm->buffer_offset; - strm->buffer_offset = 0; - } - - if (strm->eof) - return 0; - - return strm->precache(strm); -} - -const char *istream_get_filename(istream_t *strm) -{ - return strm->get_filename(strm); -} - -int istream_skip(istream_t *strm, sqfs_u64 size) -{ - size_t diff; - - while (size > 0) { - if (strm->buffer_offset >= strm->buffer_used) { - if (istream_precache(strm)) - return -1; - - if (strm->buffer_used == 0) { - fprintf(stderr, "%s: unexpected end-of-file\n", - strm->get_filename(strm)); - return -1; - } - } - - diff = strm->buffer_used - strm->buffer_offset; - if ((sqfs_u64)diff > size) - diff = size; - - strm->buffer_offset += diff; - size -= diff; - } - - return 0; -} diff --git a/lib/fstream/ostream.c b/lib/fstream/ostream.c deleted file mode 100644 index afe76e8..0000000 --- a/lib/fstream/ostream.c +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * ostream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "internal.h" - - -static int append_sparse_fallback(ostream_t *strm, size_t size) -{ - char buffer[512]; - size_t diff; - - memset(buffer, 0, sizeof(buffer)); - - while (size > 0) { - diff = size < sizeof(buffer) ? size : sizeof(buffer); - - if (strm->append(strm, buffer, diff)) - return -1; - - size -= diff; - } - - return 0; -} - - -int ostream_append(ostream_t *strm, const void *data, size_t size) -{ - return strm->append(strm, data, size); -} - -int ostream_append_sparse(ostream_t *strm, size_t size) -{ - if (strm->append_sparse == NULL) - return append_sparse_fallback(strm, size); - - return strm->append_sparse(strm, size); -} - -int ostream_flush(ostream_t *strm) -{ - return strm->flush(strm); -} - -const char *ostream_get_filename(ostream_t *strm) -{ - return strm->get_filename(strm); -} - -sqfs_s32 ostream_append_from_istream(ostream_t *out, istream_t *in, - sqfs_u32 size) -{ - sqfs_s32 total = 0; - size_t diff; - - if (size > 0x7FFFFFFF) - size = 0x7FFFFFFF; - - while (size > 0) { - if (in->buffer_offset >= in->buffer_used) { - if (istream_precache(in)) - return -1; - - if (in->buffer_used == 0) - break; - } - - diff = in->buffer_used - in->buffer_offset; - if (diff > size) - diff = size; - - if (out->append(out, in->buffer + in->buffer_offset, diff)) - return -1; - - in->buffer_offset += diff; - size -= diff; - total += diff; - } - - return total; -} diff --git a/lib/fstream/printf.c b/lib/fstream/printf.c deleted file mode 100644 index 3850487..0000000 --- a/lib/fstream/printf.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * printf.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "internal.h" - -int ostream_printf(ostream_t *strm, const char *fmt, ...) -{ - char *temp = NULL; - va_list ap; - int ret; - - va_start(ap, fmt); - - ret = vasprintf(&temp, fmt, ap); - if (ret < 0) - perror(strm->get_filename(strm)); - va_end(ap); - - if (ret < 0) - return -1; - - if (strm->append(strm, temp, ret)) - ret = -1; - - free(temp); - return ret; -} diff --git a/lib/fstream/uncompress/autodetect.c b/lib/fstream/uncompress/autodetect.c deleted file mode 100644 index 61628f8..0000000 --- a/lib/fstream/uncompress/autodetect.c +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * autodetect.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -static const struct { - int id; - const sqfs_u8 *value; - size_t len; -} magic[] = { - { FSTREAM_COMPRESSOR_GZIP, (const sqfs_u8 *)"\x1F\x8B\x08", 3 }, - { FSTREAM_COMPRESSOR_XZ, (const sqfs_u8 *)("\xFD" "7zXZ"), 6 }, - { FSTREAM_COMPRESSOR_ZSTD, (const sqfs_u8 *)"\x28\xB5\x2F\xFD", 4 }, - { FSTREAM_COMPRESSOR_BZIP2, (const sqfs_u8 *)"BZh", 3 }, -}; - -int istream_detect_compressor(istream_t *strm, - int (*probe)(const sqfs_u8 *data, size_t size)) -{ - size_t i; - int ret; - - ret = istream_precache(strm); - if (ret != 0) - return ret; - - if (probe != NULL) { - ret = probe(strm->buffer + strm->buffer_offset, - strm->buffer_used - strm->buffer_offset); - if (ret < 0) - return ret; - - /* XXX: this means the data is uncompressed. We do this check - first since it might be perfectly OK for the uncompressed - data to contain a magic number from the table. */ - if (ret > 0) - return 0; - } - - for (i = 0; i < sizeof(magic) / sizeof(magic[0]); ++i) { - if ((strm->buffer_used - strm->buffer_offset) < magic[i].len) - continue; - - ret = memcmp(strm->buffer + strm->buffer_offset, - magic[i].value, magic[i].len); - - if (ret == 0) - return magic[i].id; - } - - return 0; -} diff --git a/lib/fstream/uncompress/bzip2.c b/lib/fstream/uncompress/bzip2.c deleted file mode 100644 index 3b44383..0000000 --- a/lib/fstream/uncompress/bzip2.c +++ /dev/null @@ -1,118 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * bzip2.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#include - -typedef struct { - istream_comp_t base; - - bool initialized; - bz_stream strm; -} istream_bzip2_t; - -static int precache(istream_t *base) -{ - istream_bzip2_t *bzip2 = (istream_bzip2_t *)base; - istream_t *wrapped = ((istream_comp_t *)base)->wrapped; - size_t avail; - int ret; - - for (;;) { - if (!bzip2->initialized) { - if (BZ2_bzDecompressInit(&bzip2->strm, 0, 0) != BZ_OK) { - fprintf(stderr, "%s: error initializing " - "bzip2 decompressor.\n", - wrapped->get_filename(wrapped)); - return -1; - } - - bzip2->initialized = true; - } - - ret = istream_precache(wrapped); - if (ret != 0) - return ret; - - avail = wrapped->buffer_used; - if ((sizeof(size_t) > sizeof(unsigned int)) && - (avail > (size_t)UINT_MAX)) { - avail = UINT_MAX; - } - - bzip2->strm.next_in = (char *)wrapped->buffer; - bzip2->strm.avail_in = (unsigned int)avail; - - if (base->buffer_used > BUFSZ) - base->buffer_used = BUFSZ; - - avail = BUFSZ - base->buffer_used; - - if ((sizeof(size_t) > sizeof(unsigned int)) && - (avail > (size_t)UINT_MAX)) { - avail = UINT_MAX; - } - - bzip2->strm.next_out = (char *)base->buffer + base->buffer_used; - bzip2->strm.avail_out = (unsigned int)avail; - - if (bzip2->strm.avail_out < 1) - break; - - ret = BZ2_bzDecompress(&bzip2->strm); - - if (ret < 0) { - fprintf(stderr, "%s: internal error in bzip2 " - "decompressor.\n", - wrapped->get_filename(wrapped)); - return -1; - } - - base->buffer_used = BUFSZ - bzip2->strm.avail_out; - wrapped->buffer_offset = wrapped->buffer_used - - bzip2->strm.avail_in; - - if (ret == BZ_STREAM_END) { - if (istream_precache(wrapped)) - return -1; - - BZ2_bzDecompressEnd(&bzip2->strm); - bzip2->initialized = false; - - if (wrapped->buffer_used == 0) { - base->eof = true; - break; - } - } - } - - return 0; -} - -static void cleanup(istream_comp_t *base) -{ - istream_bzip2_t *bzip2 = (istream_bzip2_t *)base; - - if (bzip2->initialized) - BZ2_bzDecompressEnd(&bzip2->strm); -} - -istream_comp_t *istream_bzip2_create(const char *filename) -{ - istream_bzip2_t *bzip2 = calloc(1, sizeof(*bzip2)); - istream_comp_t *base = (istream_comp_t *)bzip2; - - if (bzip2 == NULL) { - fprintf(stderr, "%s: creating bzip2 compressor: %s.\n", - filename, strerror(errno)); - return NULL; - } - - ((istream_t *)base)->precache = precache; - base->cleanup = cleanup; - return base; -} diff --git a/lib/fstream/uncompress/gzip.c b/lib/fstream/uncompress/gzip.c deleted file mode 100644 index 1d6274c..0000000 --- a/lib/fstream/uncompress/gzip.c +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * gzip.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#include - -typedef struct { - istream_comp_t base; - - z_stream strm; -} istream_gzip_t; - -static int precache(istream_t *base) -{ - istream_t *wrapped = ((istream_comp_t *)base)->wrapped; - istream_gzip_t *gzip = (istream_gzip_t *)base; - size_t avail_in, avail_out; - int ret; - - for (;;) { - ret = istream_precache(wrapped); - if (ret != 0) - return ret; - - avail_in = wrapped->buffer_used; - avail_out = BUFSZ - base->buffer_used; - - if (sizeof(size_t) > sizeof(uInt)) { - gzip->strm.avail_in = ~((uInt)0U); - gzip->strm.avail_out = ~((uInt)0U); - - if ((size_t)gzip->strm.avail_in > avail_in) - gzip->strm.avail_in = (uInt)avail_in; - - if ((size_t)gzip->strm.avail_out > avail_out) - gzip->strm.avail_out = (uInt)avail_out; - } else { - gzip->strm.avail_in = (uInt)avail_in; - gzip->strm.avail_out = (uInt)avail_out; - } - - gzip->strm.next_in = wrapped->buffer; - gzip->strm.next_out = base->buffer + base->buffer_used; - - ret = inflate(&gzip->strm, Z_NO_FLUSH); - - wrapped->buffer_offset = wrapped->buffer_used - - gzip->strm.avail_in; - - base->buffer_used = BUFSZ - gzip->strm.avail_out; - - if (ret == Z_BUF_ERROR) - break; - - if (ret == Z_STREAM_END) { - base->eof = true; - break; - } - - if (ret != Z_OK) { - fprintf(stderr, - "%s: internal error in gzip decoder.\n", - wrapped->get_filename(wrapped)); - return -1; - } - } - - return 0; -} - -static void cleanup(istream_comp_t *base) -{ - istream_gzip_t *gzip = (istream_gzip_t *)base; - - inflateEnd(&gzip->strm); -} - -istream_comp_t *istream_gzip_create(const char *filename) -{ - istream_gzip_t *gzip = calloc(1, sizeof(*gzip)); - istream_comp_t *base = (istream_comp_t *)gzip; - int ret; - - if (gzip == NULL) { - fprintf(stderr, "%s: creating gzip decoder: %s.\n", - filename, strerror(errno)); - return NULL; - } - - ret = inflateInit2(&gzip->strm, 16 + 15); - if (ret != Z_OK) { - fprintf(stderr, - "%s: internal error creating gzip reader.\n", - filename); - free(gzip); - return NULL; - } - - ((istream_t *)base)->precache = precache; - base->cleanup = cleanup; - return base; -} diff --git a/lib/fstream/uncompress/istream_compressor.c b/lib/fstream/uncompress/istream_compressor.c deleted file mode 100644 index 75edd1b..0000000 --- a/lib/fstream/uncompress/istream_compressor.c +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * istream_compressor.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -static const char *comp_get_filename(istream_t *strm) -{ - istream_comp_t *comp = (istream_comp_t *)strm; - - return comp->wrapped->get_filename(comp->wrapped); -} - -static void comp_destroy(sqfs_object_t *obj) -{ - istream_comp_t *comp = (istream_comp_t *)obj; - - comp->cleanup(comp); - sqfs_destroy(comp->wrapped); - free(comp); -} - -istream_t *istream_compressor_create(istream_t *strm, int comp_id) -{ - istream_comp_t *comp = NULL; - sqfs_object_t *obj; - istream_t *base; - - switch (comp_id) { - case FSTREAM_COMPRESSOR_GZIP: -#ifdef WITH_GZIP - comp = istream_gzip_create(strm->get_filename(strm)); -#endif - break; - case FSTREAM_COMPRESSOR_XZ: -#ifdef WITH_XZ - comp = istream_xz_create(strm->get_filename(strm)); -#endif - break; - case FSTREAM_COMPRESSOR_ZSTD: -#if defined(WITH_ZSTD) && defined(HAVE_ZSTD_STREAM) - comp = istream_zstd_create(strm->get_filename(strm)); -#endif - break; - case FSTREAM_COMPRESSOR_BZIP2: -#ifdef WITH_BZIP2 - comp = istream_bzip2_create(strm->get_filename(strm)); -#endif - break; - default: - break; - } - - if (comp == NULL) - return NULL; - - comp->wrapped = strm; - - base = (istream_t *)comp; - base->get_filename = comp_get_filename; - base->buffer = comp->uncompressed; - base->eof = false; - - obj = (sqfs_object_t *)comp; - obj->destroy = comp_destroy; - return base; -} diff --git a/lib/fstream/uncompress/xz.c b/lib/fstream/uncompress/xz.c deleted file mode 100644 index 0fd9ce6..0000000 --- a/lib/fstream/uncompress/xz.c +++ /dev/null @@ -1,96 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * xz.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#include - -typedef struct { - istream_comp_t base; - - lzma_stream strm; -} istream_xz_t; - -static int precache(istream_t *base) -{ - istream_xz_t *xz = (istream_xz_t *)base; - istream_t *wrapped = ((istream_comp_t *)base)->wrapped; - lzma_action action; - lzma_ret ret_xz; - int ret; - - for (;;) { - ret = istream_precache(wrapped); - if (ret != 0) - return ret; - - action = wrapped->eof ? LZMA_FINISH : LZMA_RUN; - - xz->strm.avail_in = wrapped->buffer_used; - xz->strm.next_in = wrapped->buffer; - - xz->strm.avail_out = BUFSZ - base->buffer_used; - xz->strm.next_out = base->buffer + base->buffer_used; - - ret_xz = lzma_code(&xz->strm, action); - - base->buffer_used = BUFSZ - xz->strm.avail_out; - wrapped->buffer_offset = wrapped->buffer_used - - xz->strm.avail_in; - - if (ret_xz == LZMA_BUF_ERROR) - break; - - if (ret_xz == LZMA_STREAM_END) { - base->eof = true; - break; - } - - if (ret_xz != LZMA_OK) { - fprintf(stderr, - "%s: internal error in xz decoder.\n", - wrapped->get_filename(wrapped)); - return -1; - } - } - - return 0; -} - -static void cleanup(istream_comp_t *base) -{ - istream_xz_t *xz = (istream_xz_t *)base; - - lzma_end(&xz->strm); -} - -istream_comp_t *istream_xz_create(const char *filename) -{ - istream_xz_t *xz = calloc(1, sizeof(*xz)); - istream_comp_t *base = (istream_comp_t *)xz; - sqfs_u64 memlimit = 65 * 1024 * 1024; - lzma_ret ret_xz; - - if (xz == NULL) { - fprintf(stderr, "%s: creating xz decoder: %s.\n", - filename, strerror(errno)); - return NULL; - } - - ret_xz = lzma_stream_decoder(&xz->strm, memlimit, LZMA_CONCATENATED); - - if (ret_xz != LZMA_OK) { - fprintf(stderr, - "%s: error initializing xz decoder.\n", - filename); - free(xz); - return NULL; - } - - ((istream_t *)base)->precache = precache; - base->cleanup = cleanup; - return base; -} diff --git a/lib/fstream/uncompress/zstd.c b/lib/fstream/uncompress/zstd.c deleted file mode 100644 index fd22cbf..0000000 --- a/lib/fstream/uncompress/zstd.c +++ /dev/null @@ -1,81 +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 { - istream_comp_t base; - - ZSTD_DStream* strm; -} istream_zstd_t; - -static int precache(istream_t *base) -{ - istream_zstd_t *zstd = (istream_zstd_t *)base; - istream_t *wrapped = ((istream_comp_t *)base)->wrapped; - ZSTD_outBuffer out; - ZSTD_inBuffer in; - size_t ret; - - if (istream_precache(wrapped)) - return -1; - - memset(&in, 0, sizeof(in)); - memset(&out, 0, sizeof(out)); - - in.src = wrapped->buffer; - in.size = wrapped->buffer_used; - - out.dst = ((istream_comp_t *)base)->uncompressed + base->buffer_used; - out.size = BUFSZ - base->buffer_used; - - ret = ZSTD_decompressStream(zstd->strm, &out, &in); - - if (ZSTD_isError(ret)) { - fprintf(stderr, "%s: error in zstd decoder.\n", - wrapped->get_filename(wrapped)); - return -1; - } - - wrapped->buffer_offset = in.pos; - base->buffer_used += out.pos; - return 0; -} - -static void cleanup(istream_comp_t *base) -{ - istream_zstd_t *zstd = (istream_zstd_t *)base; - - ZSTD_freeDStream(zstd->strm); -} - -istream_comp_t *istream_zstd_create(const char *filename) -{ - istream_zstd_t *zstd = calloc(1, sizeof(*zstd)); - istream_comp_t *base = (istream_comp_t *)zstd; - - if (zstd == NULL) { - fprintf(stderr, "%s: creating zstd decoder: %s.\n", - filename, strerror(errno)); - return NULL; - } - - zstd->strm = ZSTD_createDStream(); - if (zstd->strm == NULL) { - fprintf(stderr, "%s: error creating zstd decoder.\n", - filename); - free(zstd); - return NULL; - } - - ((istream_t *)base)->precache = precache; - base->cleanup = cleanup; - return base; -} -#endif /* HAVE_ZSTD_STREAM */ diff --git a/lib/fstream/unix/istream.c b/lib/fstream/unix/istream.c deleted file mode 100644 index 5898141..0000000 --- a/lib/fstream/unix/istream.c +++ /dev/null @@ -1,124 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * istream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -typedef struct { - istream_t base; - char *path; - int fd; - bool eof; - - sqfs_u8 buffer[BUFSZ]; -} file_istream_t; - -static int file_precache(istream_t *strm) -{ - file_istream_t *file = (file_istream_t *)strm; - ssize_t ret; - size_t diff; - - while (strm->buffer_used < sizeof(file->buffer)) { - diff = sizeof(file->buffer) - strm->buffer_used; - - ret = read(file->fd, strm->buffer + strm->buffer_used, diff); - - if (ret == 0) { - file->eof = true; - break; - } - - if (ret < 0) { - if (errno == EINTR) - continue; - - perror(file->path); - return -1; - } - - strm->buffer_used += ret; - } - - return 0; -} - -static const char *file_get_filename(istream_t *strm) -{ - file_istream_t *file = (file_istream_t *)strm; - - return file->path; -} - -static void file_destroy(sqfs_object_t *obj) -{ - file_istream_t *file = (file_istream_t *)obj; - - if (file->fd != STDIN_FILENO) - close(file->fd); - - free(file->path); - free(file); -} - -istream_t *istream_open_file(const char *path) -{ - file_istream_t *file = calloc(1, sizeof(*file)); - sqfs_object_t *obj = (sqfs_object_t *)file; - istream_t *strm = (istream_t *)file; - - if (file == NULL) { - perror(path); - return NULL; - } - - file->path = strdup(path); - if (file->path == NULL) { - perror(path); - goto fail_free; - } - - file->fd = open(path, O_RDONLY); - if (file->fd < 0) { - perror(path); - goto fail_path; - } - - strm->buffer = file->buffer; - strm->precache = file_precache; - strm->get_filename = file_get_filename; - obj->destroy = file_destroy; - return strm; -fail_path: - free(file->path); -fail_free: - free(file); - return NULL; -} - -istream_t *istream_open_stdin(void) -{ - file_istream_t *file = calloc(1, sizeof(*file)); - sqfs_object_t *obj = (sqfs_object_t *)file; - istream_t *strm = (istream_t *)file; - - if (file == NULL) - goto fail; - - file->path = strdup("stdin"); - if (file->path == NULL) - goto fail; - - file->fd = STDIN_FILENO; - strm->buffer = file->buffer; - strm->precache = file_precache; - strm->get_filename = file_get_filename; - obj->destroy = file_destroy; - return strm; -fail: - perror("creating file wrapper for stdin"); - free(file); - return NULL; -} diff --git a/lib/fstream/unix/ostream.c b/lib/fstream/unix/ostream.c deleted file mode 100644 index 17f1998..0000000 --- a/lib/fstream/unix/ostream.c +++ /dev/null @@ -1,173 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * ostream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -typedef struct { - ostream_t base; - char *path; - int fd; - - off_t sparse_count; - off_t size; -} file_ostream_t; - -static int file_append(ostream_t *strm, const void *data, size_t size) -{ - file_ostream_t *file = (file_ostream_t *)strm; - ssize_t ret; - - if (size == 0) - return 0; - - if (file->sparse_count > 0) { - if (lseek(file->fd, file->sparse_count, SEEK_CUR) == (off_t)-1) - goto fail_errno; - - file->sparse_count = 0; - } - - while (size > 0) { - ret = write(file->fd, data, size); - - if (ret == 0) { - fprintf(stderr, "%s: truncated data write.\n", - file->path); - return -1; - } - - if (ret < 0) { - if (errno == EINTR) - continue; - goto fail_errno; - } - - file->size += ret; - size -= ret; - data = (const char *)data + ret; - } - - return 0; -fail_errno: - perror(file->path); - return -1; -} - -static int file_append_sparse(ostream_t *strm, size_t size) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - file->sparse_count += size; - file->size += size; - return 0; -} - -static int file_flush(ostream_t *strm) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - if (file->sparse_count > 0) { - if (ftruncate(file->fd, file->size) != 0) - goto fail; - } - - if (fsync(file->fd) != 0) { - if (errno == EINVAL) - return 0; - goto fail; - } - - return 0; -fail: - perror(file->path); - return -1; -} - -static void file_destroy(sqfs_object_t *obj) -{ - file_ostream_t *file = (file_ostream_t *)obj; - - if (file->fd != STDOUT_FILENO) - close(file->fd); - - free(file->path); - free(file); -} - -static const char *file_get_filename(ostream_t *strm) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - return file->path; -} - -ostream_t *ostream_open_file(const char *path, int flags) -{ - file_ostream_t *file = calloc(1, sizeof(*file)); - sqfs_object_t *obj = (sqfs_object_t *)file; - ostream_t *strm = (ostream_t *)file; - - if (file == NULL) { - perror(path); - return NULL; - } - - file->path = strdup(path); - if (file->path == NULL) { - perror(path); - goto fail_free; - } - - if (flags & OSTREAM_OPEN_OVERWRITE) { - file->fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - } else { - file->fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644); - } - - if (file->fd < 0) { - perror(path); - goto fail_path; - } - - if (flags & OSTREAM_OPEN_SPARSE) - strm->append_sparse = file_append_sparse; - - strm->append = file_append; - strm->flush = file_flush; - strm->get_filename = file_get_filename; - obj->destroy = file_destroy; - return strm; -fail_path: - free(file->path); -fail_free: - free(file); - return NULL; -} - -ostream_t *ostream_open_stdout(void) -{ - file_ostream_t *file = calloc(1, sizeof(*file)); - sqfs_object_t *obj = (sqfs_object_t *)file; - ostream_t *strm = (ostream_t *)file; - - if (file == NULL) - goto fail; - - file->path = strdup("stdout"); - if (file->path == NULL) - goto fail; - - file->fd = STDOUT_FILENO; - strm->append = file_append; - strm->flush = file_flush; - strm->get_filename = file_get_filename; - obj->destroy = file_destroy; - return strm; -fail: - perror("creating file wrapper for stdout"); - free(file); - return NULL; -} diff --git a/lib/fstream/win32/istream.c b/lib/fstream/win32/istream.c deleted file mode 100644 index b591584..0000000 --- a/lib/fstream/win32/istream.c +++ /dev/null @@ -1,138 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * istream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#define WIN32_LEAN_AND_MEAN -#include - -typedef struct { - istream_t base; - char *path; - HANDLE hnd; - - sqfs_u8 buffer[BUFSZ]; -} file_istream_t; - -static int file_precache(istream_t *strm) -{ - file_istream_t *file = (file_istream_t *)strm; - DWORD diff, actual; - HANDLE hnd; - - hnd = file->path == NULL ? GetStdHandle(STD_INPUT_HANDLE) : file->hnd; - - while (strm->buffer_used < sizeof(file->buffer)) { - diff = sizeof(file->buffer) - strm->buffer_used; - - if (!ReadFile(hnd, strm->buffer + strm->buffer_used, - diff, &actual, NULL)) { - DWORD error = GetLastError(); - - if (error == ERROR_HANDLE_EOF || - error == ERROR_BROKEN_PIPE) { - strm->eof = true; - break; - } - - SetLastError(error); - - w32_perror(file->path == NULL ? "stdin" : file->path); - return -1; - } - - if (actual == 0) { - strm->eof = true; - break; - } - - strm->buffer_used += actual; - } - - return 0; -} - -static const char *file_get_filename(istream_t *strm) -{ - file_istream_t *file = (file_istream_t *)strm; - - return file->path == NULL ? "stdin" : file->path; -} - -static void file_destroy(sqfs_object_t *obj) -{ - file_istream_t *file = (file_istream_t *)obj; - - if (file->path != NULL) { - CloseHandle(file->hnd); - free(file->path); - } - - free(file); -} - -istream_t *istream_open_file(const char *path) -{ - file_istream_t *file = calloc(1, sizeof(*file)); - sqfs_object_t *obj = (sqfs_object_t *)file; - istream_t *strm = (istream_t *)file; - WCHAR *wpath = NULL; - - if (file == NULL) { - perror(path); - return NULL; - } - - wpath = path_to_windows(path); - if (wpath == NULL) - goto fail_free; - - file->path = strdup(path); - if (file->path == NULL) { - perror(path); - goto fail_free; - } - - file->hnd = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (file->hnd == INVALID_HANDLE_VALUE) { - perror(path); - goto fail_path; - } - - free(wpath); - - strm->buffer = file->buffer; - strm->precache = file_precache; - strm->get_filename = file_get_filename; - obj->destroy = file_destroy; - return strm; -fail_path: - free(file->path); -fail_free: - free(wpath); - free(file); - return NULL; -} - -istream_t *istream_open_stdin(void) -{ - file_istream_t *file = calloc(1, sizeof(*file)); - sqfs_object_t *obj = (sqfs_object_t *)file; - istream_t *strm = (istream_t *)file; - - if (file == NULL) { - perror("stdin"); - return NULL; - } - - strm->buffer = file->buffer; - strm->precache = file_precache; - strm->get_filename = file_get_filename; - obj->destroy = file_destroy; - return strm; -} diff --git a/lib/fstream/win32/ostream.c b/lib/fstream/win32/ostream.c deleted file mode 100644 index 2bd78c8..0000000 --- a/lib/fstream/win32/ostream.c +++ /dev/null @@ -1,197 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * ostream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#define WIN32_LEAN_AND_MEAN -#include - -typedef struct { - ostream_t base; - char *path; - HANDLE hnd; -} file_ostream_t; - -static int w32_append(HANDLE hnd, const char *filename, - const void *data, size_t size) -{ - DWORD diff; - - while (size > 0) { - if (!WriteFile(hnd, data, size, &diff, NULL)) { - w32_perror(filename); - return -1; - } - - size -= diff; - data = (const char *)data + diff; - } - - return 0; -} - -static int w32_flush(HANDLE hnd, const char *filename) -{ - if (!FlushFileBuffers(hnd)) { - w32_perror(filename); - return -1; - } - - return 0; -} - -/*****************************************************************************/ - -static int file_append(ostream_t *strm, const void *data, size_t size) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - return w32_append(file->hnd, file->path, data, size); -} - -static int file_append_sparse(ostream_t *strm, size_t size) -{ - file_ostream_t *file = (file_ostream_t *)strm; - LARGE_INTEGER pos; - - pos.QuadPart = size; - - if (!SetFilePointerEx(file->hnd, pos, NULL, FILE_CURRENT)) - goto fail; - - if (!SetEndOfFile(file->hnd)) - goto fail; - - return 0; -fail: - w32_perror(file->path); - return -1; -} - -static int file_flush(ostream_t *strm) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - return w32_flush(file->hnd, file->path); -} - -static void file_destroy(sqfs_object_t *obj) -{ - file_ostream_t *file = (file_ostream_t *)obj; - - CloseHandle(file->hnd); - free(file->path); - free(file); -} - -static const char *file_get_filename(ostream_t *strm) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - return file->path; -} - -/*****************************************************************************/ - -static int stdout_append(ostream_t *strm, const void *data, size_t size) -{ - (void)strm; - return w32_append(GetStdHandle(STD_OUTPUT_HANDLE), "stdout", - data, size); -} - -static int stdout_flush(ostream_t *strm) -{ - (void)strm; - return w32_flush(GetStdHandle(STD_OUTPUT_HANDLE), "stdout"); -} - -static void stdout_destroy(sqfs_object_t *obj) -{ - free(obj); -} - -static const char *stdout_get_filename(ostream_t *strm) -{ - (void)strm; - return "stdout"; -} - -/*****************************************************************************/ - -ostream_t *ostream_open_file(const char *path, int flags) -{ - file_ostream_t *file = calloc(1, sizeof(*file)); - sqfs_object_t *obj = (sqfs_object_t *)file; - ostream_t *strm = (ostream_t *)file; - int access_flags, creation_mode; - WCHAR *wpath = NULL; - - if (file == NULL) { - perror(path); - return NULL; - } - - wpath = path_to_windows(path); - if (wpath == NULL) - goto fail_free; - - file->path = strdup(path); - if (file->path == NULL) { - perror(path); - goto fail_free; - } - - access_flags = GENERIC_WRITE; - - if (flags & OSTREAM_OPEN_OVERWRITE) { - creation_mode = CREATE_ALWAYS; - } else { - creation_mode = CREATE_NEW; - } - - file->hnd = CreateFileW(wpath, access_flags, 0, NULL, creation_mode, - FILE_ATTRIBUTE_NORMAL, NULL); - - if (file->hnd == INVALID_HANDLE_VALUE) { - w32_perror(path); - goto fail_path; - } - - free(wpath); - - if (flags & OSTREAM_OPEN_SPARSE) - strm->append_sparse = file_append_sparse; - - strm->append = file_append; - strm->flush = file_flush; - strm->get_filename = file_get_filename; - obj->destroy = file_destroy; - return strm; -fail_path: - free(file->path); -fail_free: - free(file); - free(wpath); - return NULL; -} - -ostream_t *ostream_open_stdout(void) -{ - ostream_t *strm = calloc(1, sizeof(*strm)); - sqfs_object_t *obj = (sqfs_object_t *)strm; - - if (strm == NULL) { - perror("creating stdout file wrapper"); - return NULL; - } - - strm->append = stdout_append; - strm->flush = stdout_flush; - strm->get_filename = stdout_get_filename; - obj->destroy = stdout_destroy; - return strm; -} diff --git a/lib/fstree/fstree_from_file.c b/lib/fstree/fstree_from_file.c index e77f19a..dd289bc 100644 --- a/lib/fstree/fstree_from_file.c +++ b/lib/fstree/fstree_from_file.c @@ -6,8 +6,8 @@ */ #include "config.h" +#include "io/file.h" #include "fstree.h" -#include "fstream.h" #include "compat.h" #include diff --git a/lib/io/Makemodule.am b/lib/io/Makemodule.am new file mode 100644 index 0000000..63ce958 --- /dev/null +++ b/lib/io/Makemodule.am @@ -0,0 +1,45 @@ +libio_a_SOURCES = lib/io/internal.h +libio_a_SOURCES += include/io/istream.h lib/io/ostream.c lib/io/printf.c +libio_a_SOURCES += include/io/ostream.h lib/io/istream.c lib/io/get_line.c +libio_a_SOURCES += include/io/xfrm.h lib/io/xfrm.c +libio_a_SOURCES += include/io/file.h include/io/std.h +libio_a_SOURCES += lib/io/compress/ostream_compressor.c +libio_a_SOURCES += lib/io/uncompress/istream_compressor.c +libio_a_SOURCES += lib/io/uncompress/autodetect.c +libio_a_CFLAGS = $(AM_CFLAGS) $(ZLIB_CFLAGS) $(XZ_CFLAGS) +libio_a_CFLAGS += $(ZSTD_CFLAGS) $(BZIP2_CFLAGS) +libio_a_CPPFLAGS = $(AM_CPPFLAGS) + +if WINDOWS +libio_a_SOURCES += lib/io/win32/ostream.c +libio_a_SOURCES += lib/io/win32/istream.c +libio_a_CFLAGS += -DWINVER=0x0600 -D_WIN32_WINNT=0x0600 +else +libio_a_SOURCES += lib/io/unix/ostream.c +libio_a_SOURCES += lib/io/unix/istream.c +endif + +if WITH_XZ +libio_a_SOURCES += lib/io/compress/xz.c lib/io/uncompress/xz.c +libio_a_CPPFLAGS += -DWITH_XZ +endif + +if WITH_GZIP +libio_a_SOURCES += lib/io/compress/gzip.c +libio_a_SOURCES += lib/io/uncompress/gzip.c +libio_a_CPPFLAGS += -DWITH_GZIP +endif + +if WITH_ZSTD +libio_a_SOURCES += lib/io/compress/zstd.c +libio_a_SOURCES += lib/io/uncompress/zstd.c +libio_a_CPPFLAGS += -DWITH_ZSTD +endif + +if WITH_BZIP2 +libio_a_SOURCES += lib/io/compress/bzip2.c +libio_a_SOURCES += lib/io/uncompress/bzip2.c +libio_a_CPPFLAGS += -DWITH_BZIP2 +endif + +noinst_LIBRARIES += libio.a diff --git a/lib/io/compress/bzip2.c b/lib/io/compress/bzip2.c new file mode 100644 index 0000000..7f0c09a --- /dev/null +++ b/lib/io/compress/bzip2.c @@ -0,0 +1,96 @@ +/* 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 new file mode 100644 index 0000000..b73a258 --- /dev/null +++ b/lib/io/compress/gzip.c @@ -0,0 +1,92 @@ +/* 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 new file mode 100644 index 0000000..314ce6b --- /dev/null +++ b/lib/io/compress/ostream_compressor.c @@ -0,0 +1,108 @@ +/* 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_destroy(comp->wrapped); + free(comp); +} + +ostream_t *ostream_compressor_create(ostream_t *strm, int comp_id) +{ + ostream_comp_t *comp = NULL; + sqfs_object_t *obj; + 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; + + comp->wrapped = strm; + comp->inbuf_used = 0; + + base = (ostream_t *)comp; + base->append = comp_append; + base->flush = comp_flush; + base->get_filename = comp_get_filename; + + obj = (sqfs_object_t *)comp; + obj->destroy = comp_destroy; + return base; +} diff --git a/lib/io/compress/xz.c b/lib/io/compress/xz.c new file mode 100644 index 0000000..65bda0b --- /dev/null +++ b/lib/io/compress/xz.c @@ -0,0 +1,80 @@ +/* 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 new file mode 100644 index 0000000..c0b002e --- /dev/null +++ b/lib/io/compress/zstd.c @@ -0,0 +1,94 @@ +/* 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 */ diff --git a/lib/io/get_line.c b/lib/io/get_line.c new file mode 100644 index 0000000..f7e0b59 --- /dev/null +++ b/lib/io/get_line.c @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * get_line.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "internal.h" + +static void ltrim(char *buffer) +{ + size_t i = 0; + + while (isspace(buffer[i])) + ++i; + + if (i > 0) + memmove(buffer, buffer + i, strlen(buffer + i) + 1); +} + +static void rtrim(char *buffer) +{ + size_t i = strlen(buffer); + + while (i > 0 && isspace(buffer[i - 1])) + --i; + + buffer[i] = '\0'; +} + +static size_t trim(char *buffer, int flags) +{ + if (flags & ISTREAM_LINE_LTRIM) + ltrim(buffer); + + if (flags & ISTREAM_LINE_RTRIM) + rtrim(buffer); + + return strlen(buffer); +} + +int istream_get_line(istream_t *strm, char **out, + size_t *line_num, int flags) +{ + char *line = NULL, *new; + size_t i, line_len = 0; + bool have_line = false; + + *out = NULL; + + for (;;) { + if (istream_precache(strm)) + return -1; + + if (strm->buffer_used == 0) { + if (line_len == 0) + goto out_eof; + + line_len = trim(line, flags); + + if (line_len == 0 && + (flags & ISTREAM_LINE_SKIP_EMPTY)) { + goto out_eof; + } + break; + } + + for (i = 0; i < strm->buffer_used; ++i) { + if (strm->buffer[i] == '\n') + break; + } + + if (i < strm->buffer_used) { + have_line = true; + strm->buffer_offset = i + 1; + + if (i > 0 && strm->buffer[i - 1] == '\r') + --i; + } else { + strm->buffer_offset = i; + } + + new = realloc(line, line_len + i + 1); + if (new == NULL) + goto fail_errno; + + line = new; + memcpy(line + line_len, strm->buffer, i); + line_len += i; + line[line_len] = '\0'; + + if (have_line) { + line_len = trim(line, flags); + + if (line_len == 0 && + (flags & ISTREAM_LINE_SKIP_EMPTY)) { + free(line); + line = NULL; + have_line = false; + *line_num += 1; + continue; + } + break; + } + } + + *out = line; + return 0; +fail_errno: + fprintf(stderr, "%s: " PRI_SZ ": %s.\n", strm->get_filename(strm), + *line_num, strerror(errno)); + free(line); + *out = NULL; + return -1; +out_eof: + free(line); + *out = NULL; + return 1; +} diff --git a/lib/io/internal.h b/lib/io/internal.h new file mode 100644 index 0000000..4ac38f5 --- /dev/null +++ b/lib/io/internal.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * internal.h + * + * Copyright (C) 2019 David Oberhollenzer + */ +#ifndef INTERNAL_H +#define INTERNAL_H + +#include "config.h" +#include "compat.h" +#include "io/istream.h" +#include "io/ostream.h" +#include "io/file.h" +#include "io/xfrm.h" +#include "io/std.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSZ (262144) + +typedef struct ostream_comp_t { + ostream_t base; + + ostream_t *wrapped; + + size_t inbuf_used; + + sqfs_u8 inbuf[BUFSZ]; + sqfs_u8 outbuf[BUFSZ]; + + int (*flush_inbuf)(struct ostream_comp_t *ostrm, bool finish); + + void (*cleanup)(struct ostream_comp_t *ostrm); +} ostream_comp_t; + +typedef struct istream_comp_t { + istream_t base; + + istream_t *wrapped; + + sqfs_u8 uncompressed[BUFSZ]; + + bool eof; + + void (*cleanup)(struct istream_comp_t *strm); +} istream_comp_t; + +#ifdef __cplusplus +extern "C" { +#endif + +SQFS_INTERNAL ostream_comp_t *ostream_gzip_create(const char *filename); + +SQFS_INTERNAL ostream_comp_t *ostream_xz_create(const char *filename); + +SQFS_INTERNAL ostream_comp_t *ostream_zstd_create(const char *filename); + +SQFS_INTERNAL ostream_comp_t *ostream_bzip2_create(const char *filename); + +SQFS_INTERNAL istream_comp_t *istream_gzip_create(const char *filename); + +SQFS_INTERNAL istream_comp_t *istream_xz_create(const char *filename); + +SQFS_INTERNAL istream_comp_t *istream_zstd_create(const char *filename); + +SQFS_INTERNAL istream_comp_t *istream_bzip2_create(const char *filename); + +#ifdef __cplusplus +} +#endif + +#endif /* INTERNAL_H */ diff --git a/lib/io/istream.c b/lib/io/istream.c new file mode 100644 index 0000000..6318a23 --- /dev/null +++ b/lib/io/istream.c @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "internal.h" + + +sqfs_s32 istream_read(istream_t *strm, void *data, size_t size) +{ + sqfs_s32 total = 0; + size_t diff; + + if (size > 0x7FFFFFFF) + size = 0x7FFFFFFF; + + while (size > 0) { + if (strm->buffer_offset >= strm->buffer_used) { + if (istream_precache(strm)) + return -1; + + if (strm->buffer_used == 0) + break; + } + + diff = strm->buffer_used - strm->buffer_offset; + if (diff > size) + diff = size; + + memcpy(data, strm->buffer + strm->buffer_offset, diff); + data = (char *)data + diff; + strm->buffer_offset += diff; + size -= diff; + total += diff; + } + + return total; +} + +int istream_precache(istream_t *strm) +{ + if (strm->buffer_offset >= strm->buffer_used) { + strm->buffer_offset = 0; + strm->buffer_used = 0; + } else if (strm->buffer_offset > 0) { + memmove(strm->buffer, + strm->buffer + strm->buffer_offset, + strm->buffer_used - strm->buffer_offset); + + strm->buffer_used -= strm->buffer_offset; + strm->buffer_offset = 0; + } + + if (strm->eof) + return 0; + + return strm->precache(strm); +} + +const char *istream_get_filename(istream_t *strm) +{ + return strm->get_filename(strm); +} + +int istream_skip(istream_t *strm, sqfs_u64 size) +{ + size_t diff; + + while (size > 0) { + if (strm->buffer_offset >= strm->buffer_used) { + if (istream_precache(strm)) + return -1; + + if (strm->buffer_used == 0) { + fprintf(stderr, "%s: unexpected end-of-file\n", + strm->get_filename(strm)); + return -1; + } + } + + diff = strm->buffer_used - strm->buffer_offset; + if ((sqfs_u64)diff > size) + diff = size; + + strm->buffer_offset += diff; + size -= diff; + } + + return 0; +} diff --git a/lib/io/ostream.c b/lib/io/ostream.c new file mode 100644 index 0000000..afe76e8 --- /dev/null +++ b/lib/io/ostream.c @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * ostream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "internal.h" + + +static int append_sparse_fallback(ostream_t *strm, size_t size) +{ + char buffer[512]; + size_t diff; + + memset(buffer, 0, sizeof(buffer)); + + while (size > 0) { + diff = size < sizeof(buffer) ? size : sizeof(buffer); + + if (strm->append(strm, buffer, diff)) + return -1; + + size -= diff; + } + + return 0; +} + + +int ostream_append(ostream_t *strm, const void *data, size_t size) +{ + return strm->append(strm, data, size); +} + +int ostream_append_sparse(ostream_t *strm, size_t size) +{ + if (strm->append_sparse == NULL) + return append_sparse_fallback(strm, size); + + return strm->append_sparse(strm, size); +} + +int ostream_flush(ostream_t *strm) +{ + return strm->flush(strm); +} + +const char *ostream_get_filename(ostream_t *strm) +{ + return strm->get_filename(strm); +} + +sqfs_s32 ostream_append_from_istream(ostream_t *out, istream_t *in, + sqfs_u32 size) +{ + sqfs_s32 total = 0; + size_t diff; + + if (size > 0x7FFFFFFF) + size = 0x7FFFFFFF; + + while (size > 0) { + if (in->buffer_offset >= in->buffer_used) { + if (istream_precache(in)) + return -1; + + if (in->buffer_used == 0) + break; + } + + diff = in->buffer_used - in->buffer_offset; + if (diff > size) + diff = size; + + if (out->append(out, in->buffer + in->buffer_offset, diff)) + return -1; + + in->buffer_offset += diff; + size -= diff; + total += diff; + } + + return total; +} diff --git a/lib/io/printf.c b/lib/io/printf.c new file mode 100644 index 0000000..3850487 --- /dev/null +++ b/lib/io/printf.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * printf.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "internal.h" + +int ostream_printf(ostream_t *strm, const char *fmt, ...) +{ + char *temp = NULL; + va_list ap; + int ret; + + va_start(ap, fmt); + + ret = vasprintf(&temp, fmt, ap); + if (ret < 0) + perror(strm->get_filename(strm)); + va_end(ap); + + if (ret < 0) + return -1; + + if (strm->append(strm, temp, ret)) + ret = -1; + + free(temp); + return ret; +} diff --git a/lib/io/uncompress/autodetect.c b/lib/io/uncompress/autodetect.c new file mode 100644 index 0000000..dde33c8 --- /dev/null +++ b/lib/io/uncompress/autodetect.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * autodetect.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +static const struct { + int id; + const sqfs_u8 *value; + size_t len; +} magic[] = { + { IO_COMPRESSOR_GZIP, (const sqfs_u8 *)"\x1F\x8B\x08", 3 }, + { IO_COMPRESSOR_XZ, (const sqfs_u8 *)("\xFD" "7zXZ"), 6 }, + { IO_COMPRESSOR_ZSTD, (const sqfs_u8 *)"\x28\xB5\x2F\xFD", 4 }, + { IO_COMPRESSOR_BZIP2, (const sqfs_u8 *)"BZh", 3 }, +}; + +int istream_detect_compressor(istream_t *strm, + int (*probe)(const sqfs_u8 *data, size_t size)) +{ + size_t i; + int ret; + + ret = istream_precache(strm); + if (ret != 0) + return ret; + + if (probe != NULL) { + ret = probe(strm->buffer + strm->buffer_offset, + strm->buffer_used - strm->buffer_offset); + if (ret < 0) + return ret; + + /* XXX: this means the data is uncompressed. We do this check + first since it might be perfectly OK for the uncompressed + data to contain a magic number from the table. */ + if (ret > 0) + return 0; + } + + for (i = 0; i < sizeof(magic) / sizeof(magic[0]); ++i) { + if ((strm->buffer_used - strm->buffer_offset) < magic[i].len) + continue; + + ret = memcmp(strm->buffer + strm->buffer_offset, + magic[i].value, magic[i].len); + + if (ret == 0) + return magic[i].id; + } + + return 0; +} diff --git a/lib/io/uncompress/bzip2.c b/lib/io/uncompress/bzip2.c new file mode 100644 index 0000000..3b44383 --- /dev/null +++ b/lib/io/uncompress/bzip2.c @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * bzip2.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +#include + +typedef struct { + istream_comp_t base; + + bool initialized; + bz_stream strm; +} istream_bzip2_t; + +static int precache(istream_t *base) +{ + istream_bzip2_t *bzip2 = (istream_bzip2_t *)base; + istream_t *wrapped = ((istream_comp_t *)base)->wrapped; + size_t avail; + int ret; + + for (;;) { + if (!bzip2->initialized) { + if (BZ2_bzDecompressInit(&bzip2->strm, 0, 0) != BZ_OK) { + fprintf(stderr, "%s: error initializing " + "bzip2 decompressor.\n", + wrapped->get_filename(wrapped)); + return -1; + } + + bzip2->initialized = true; + } + + ret = istream_precache(wrapped); + if (ret != 0) + return ret; + + avail = wrapped->buffer_used; + if ((sizeof(size_t) > sizeof(unsigned int)) && + (avail > (size_t)UINT_MAX)) { + avail = UINT_MAX; + } + + bzip2->strm.next_in = (char *)wrapped->buffer; + bzip2->strm.avail_in = (unsigned int)avail; + + if (base->buffer_used > BUFSZ) + base->buffer_used = BUFSZ; + + avail = BUFSZ - base->buffer_used; + + if ((sizeof(size_t) > sizeof(unsigned int)) && + (avail > (size_t)UINT_MAX)) { + avail = UINT_MAX; + } + + bzip2->strm.next_out = (char *)base->buffer + base->buffer_used; + bzip2->strm.avail_out = (unsigned int)avail; + + if (bzip2->strm.avail_out < 1) + break; + + ret = BZ2_bzDecompress(&bzip2->strm); + + if (ret < 0) { + fprintf(stderr, "%s: internal error in bzip2 " + "decompressor.\n", + wrapped->get_filename(wrapped)); + return -1; + } + + base->buffer_used = BUFSZ - bzip2->strm.avail_out; + wrapped->buffer_offset = wrapped->buffer_used - + bzip2->strm.avail_in; + + if (ret == BZ_STREAM_END) { + if (istream_precache(wrapped)) + return -1; + + BZ2_bzDecompressEnd(&bzip2->strm); + bzip2->initialized = false; + + if (wrapped->buffer_used == 0) { + base->eof = true; + break; + } + } + } + + return 0; +} + +static void cleanup(istream_comp_t *base) +{ + istream_bzip2_t *bzip2 = (istream_bzip2_t *)base; + + if (bzip2->initialized) + BZ2_bzDecompressEnd(&bzip2->strm); +} + +istream_comp_t *istream_bzip2_create(const char *filename) +{ + istream_bzip2_t *bzip2 = calloc(1, sizeof(*bzip2)); + istream_comp_t *base = (istream_comp_t *)bzip2; + + if (bzip2 == NULL) { + fprintf(stderr, "%s: creating bzip2 compressor: %s.\n", + filename, strerror(errno)); + return NULL; + } + + ((istream_t *)base)->precache = precache; + base->cleanup = cleanup; + return base; +} diff --git a/lib/io/uncompress/gzip.c b/lib/io/uncompress/gzip.c new file mode 100644 index 0000000..1d6274c --- /dev/null +++ b/lib/io/uncompress/gzip.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * gzip.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +#include + +typedef struct { + istream_comp_t base; + + z_stream strm; +} istream_gzip_t; + +static int precache(istream_t *base) +{ + istream_t *wrapped = ((istream_comp_t *)base)->wrapped; + istream_gzip_t *gzip = (istream_gzip_t *)base; + size_t avail_in, avail_out; + int ret; + + for (;;) { + ret = istream_precache(wrapped); + if (ret != 0) + return ret; + + avail_in = wrapped->buffer_used; + avail_out = BUFSZ - base->buffer_used; + + if (sizeof(size_t) > sizeof(uInt)) { + gzip->strm.avail_in = ~((uInt)0U); + gzip->strm.avail_out = ~((uInt)0U); + + if ((size_t)gzip->strm.avail_in > avail_in) + gzip->strm.avail_in = (uInt)avail_in; + + if ((size_t)gzip->strm.avail_out > avail_out) + gzip->strm.avail_out = (uInt)avail_out; + } else { + gzip->strm.avail_in = (uInt)avail_in; + gzip->strm.avail_out = (uInt)avail_out; + } + + gzip->strm.next_in = wrapped->buffer; + gzip->strm.next_out = base->buffer + base->buffer_used; + + ret = inflate(&gzip->strm, Z_NO_FLUSH); + + wrapped->buffer_offset = wrapped->buffer_used - + gzip->strm.avail_in; + + base->buffer_used = BUFSZ - gzip->strm.avail_out; + + if (ret == Z_BUF_ERROR) + break; + + if (ret == Z_STREAM_END) { + base->eof = true; + break; + } + + if (ret != Z_OK) { + fprintf(stderr, + "%s: internal error in gzip decoder.\n", + wrapped->get_filename(wrapped)); + return -1; + } + } + + return 0; +} + +static void cleanup(istream_comp_t *base) +{ + istream_gzip_t *gzip = (istream_gzip_t *)base; + + inflateEnd(&gzip->strm); +} + +istream_comp_t *istream_gzip_create(const char *filename) +{ + istream_gzip_t *gzip = calloc(1, sizeof(*gzip)); + istream_comp_t *base = (istream_comp_t *)gzip; + int ret; + + if (gzip == NULL) { + fprintf(stderr, "%s: creating gzip decoder: %s.\n", + filename, strerror(errno)); + return NULL; + } + + ret = inflateInit2(&gzip->strm, 16 + 15); + if (ret != Z_OK) { + fprintf(stderr, + "%s: internal error creating gzip reader.\n", + filename); + free(gzip); + return NULL; + } + + ((istream_t *)base)->precache = precache; + base->cleanup = cleanup; + return base; +} diff --git a/lib/io/uncompress/istream_compressor.c b/lib/io/uncompress/istream_compressor.c new file mode 100644 index 0000000..ab9ad8b --- /dev/null +++ b/lib/io/uncompress/istream_compressor.c @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream_compressor.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +static const char *comp_get_filename(istream_t *strm) +{ + istream_comp_t *comp = (istream_comp_t *)strm; + + return comp->wrapped->get_filename(comp->wrapped); +} + +static void comp_destroy(sqfs_object_t *obj) +{ + istream_comp_t *comp = (istream_comp_t *)obj; + + comp->cleanup(comp); + sqfs_destroy(comp->wrapped); + free(comp); +} + +istream_t *istream_compressor_create(istream_t *strm, int comp_id) +{ + istream_comp_t *comp = NULL; + sqfs_object_t *obj; + istream_t *base; + + switch (comp_id) { + case IO_COMPRESSOR_GZIP: +#ifdef WITH_GZIP + comp = istream_gzip_create(strm->get_filename(strm)); +#endif + break; + case IO_COMPRESSOR_XZ: +#ifdef WITH_XZ + comp = istream_xz_create(strm->get_filename(strm)); +#endif + break; + case IO_COMPRESSOR_ZSTD: +#if defined(WITH_ZSTD) && defined(HAVE_ZSTD_STREAM) + comp = istream_zstd_create(strm->get_filename(strm)); +#endif + break; + case IO_COMPRESSOR_BZIP2: +#ifdef WITH_BZIP2 + comp = istream_bzip2_create(strm->get_filename(strm)); +#endif + break; + default: + break; + } + + if (comp == NULL) + return NULL; + + comp->wrapped = strm; + + base = (istream_t *)comp; + base->get_filename = comp_get_filename; + base->buffer = comp->uncompressed; + base->eof = false; + + obj = (sqfs_object_t *)comp; + obj->destroy = comp_destroy; + return base; +} diff --git a/lib/io/uncompress/xz.c b/lib/io/uncompress/xz.c new file mode 100644 index 0000000..0fd9ce6 --- /dev/null +++ b/lib/io/uncompress/xz.c @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * xz.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +#include + +typedef struct { + istream_comp_t base; + + lzma_stream strm; +} istream_xz_t; + +static int precache(istream_t *base) +{ + istream_xz_t *xz = (istream_xz_t *)base; + istream_t *wrapped = ((istream_comp_t *)base)->wrapped; + lzma_action action; + lzma_ret ret_xz; + int ret; + + for (;;) { + ret = istream_precache(wrapped); + if (ret != 0) + return ret; + + action = wrapped->eof ? LZMA_FINISH : LZMA_RUN; + + xz->strm.avail_in = wrapped->buffer_used; + xz->strm.next_in = wrapped->buffer; + + xz->strm.avail_out = BUFSZ - base->buffer_used; + xz->strm.next_out = base->buffer + base->buffer_used; + + ret_xz = lzma_code(&xz->strm, action); + + base->buffer_used = BUFSZ - xz->strm.avail_out; + wrapped->buffer_offset = wrapped->buffer_used - + xz->strm.avail_in; + + if (ret_xz == LZMA_BUF_ERROR) + break; + + if (ret_xz == LZMA_STREAM_END) { + base->eof = true; + break; + } + + if (ret_xz != LZMA_OK) { + fprintf(stderr, + "%s: internal error in xz decoder.\n", + wrapped->get_filename(wrapped)); + return -1; + } + } + + return 0; +} + +static void cleanup(istream_comp_t *base) +{ + istream_xz_t *xz = (istream_xz_t *)base; + + lzma_end(&xz->strm); +} + +istream_comp_t *istream_xz_create(const char *filename) +{ + istream_xz_t *xz = calloc(1, sizeof(*xz)); + istream_comp_t *base = (istream_comp_t *)xz; + sqfs_u64 memlimit = 65 * 1024 * 1024; + lzma_ret ret_xz; + + if (xz == NULL) { + fprintf(stderr, "%s: creating xz decoder: %s.\n", + filename, strerror(errno)); + return NULL; + } + + ret_xz = lzma_stream_decoder(&xz->strm, memlimit, LZMA_CONCATENATED); + + if (ret_xz != LZMA_OK) { + fprintf(stderr, + "%s: error initializing xz decoder.\n", + filename); + free(xz); + return NULL; + } + + ((istream_t *)base)->precache = precache; + base->cleanup = cleanup; + return base; +} diff --git a/lib/io/uncompress/zstd.c b/lib/io/uncompress/zstd.c new file mode 100644 index 0000000..fd22cbf --- /dev/null +++ b/lib/io/uncompress/zstd.c @@ -0,0 +1,81 @@ +/* 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 { + istream_comp_t base; + + ZSTD_DStream* strm; +} istream_zstd_t; + +static int precache(istream_t *base) +{ + istream_zstd_t *zstd = (istream_zstd_t *)base; + istream_t *wrapped = ((istream_comp_t *)base)->wrapped; + ZSTD_outBuffer out; + ZSTD_inBuffer in; + size_t ret; + + if (istream_precache(wrapped)) + return -1; + + memset(&in, 0, sizeof(in)); + memset(&out, 0, sizeof(out)); + + in.src = wrapped->buffer; + in.size = wrapped->buffer_used; + + out.dst = ((istream_comp_t *)base)->uncompressed + base->buffer_used; + out.size = BUFSZ - base->buffer_used; + + ret = ZSTD_decompressStream(zstd->strm, &out, &in); + + if (ZSTD_isError(ret)) { + fprintf(stderr, "%s: error in zstd decoder.\n", + wrapped->get_filename(wrapped)); + return -1; + } + + wrapped->buffer_offset = in.pos; + base->buffer_used += out.pos; + return 0; +} + +static void cleanup(istream_comp_t *base) +{ + istream_zstd_t *zstd = (istream_zstd_t *)base; + + ZSTD_freeDStream(zstd->strm); +} + +istream_comp_t *istream_zstd_create(const char *filename) +{ + istream_zstd_t *zstd = calloc(1, sizeof(*zstd)); + istream_comp_t *base = (istream_comp_t *)zstd; + + if (zstd == NULL) { + fprintf(stderr, "%s: creating zstd decoder: %s.\n", + filename, strerror(errno)); + return NULL; + } + + zstd->strm = ZSTD_createDStream(); + if (zstd->strm == NULL) { + fprintf(stderr, "%s: error creating zstd decoder.\n", + filename); + free(zstd); + return NULL; + } + + ((istream_t *)base)->precache = precache; + base->cleanup = cleanup; + return base; +} +#endif /* HAVE_ZSTD_STREAM */ diff --git a/lib/io/unix/istream.c b/lib/io/unix/istream.c new file mode 100644 index 0000000..5898141 --- /dev/null +++ b/lib/io/unix/istream.c @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +typedef struct { + istream_t base; + char *path; + int fd; + bool eof; + + sqfs_u8 buffer[BUFSZ]; +} file_istream_t; + +static int file_precache(istream_t *strm) +{ + file_istream_t *file = (file_istream_t *)strm; + ssize_t ret; + size_t diff; + + while (strm->buffer_used < sizeof(file->buffer)) { + diff = sizeof(file->buffer) - strm->buffer_used; + + ret = read(file->fd, strm->buffer + strm->buffer_used, diff); + + if (ret == 0) { + file->eof = true; + break; + } + + if (ret < 0) { + if (errno == EINTR) + continue; + + perror(file->path); + return -1; + } + + strm->buffer_used += ret; + } + + return 0; +} + +static const char *file_get_filename(istream_t *strm) +{ + file_istream_t *file = (file_istream_t *)strm; + + return file->path; +} + +static void file_destroy(sqfs_object_t *obj) +{ + file_istream_t *file = (file_istream_t *)obj; + + if (file->fd != STDIN_FILENO) + close(file->fd); + + free(file->path); + free(file); +} + +istream_t *istream_open_file(const char *path) +{ + file_istream_t *file = calloc(1, sizeof(*file)); + sqfs_object_t *obj = (sqfs_object_t *)file; + istream_t *strm = (istream_t *)file; + + if (file == NULL) { + perror(path); + return NULL; + } + + file->path = strdup(path); + if (file->path == NULL) { + perror(path); + goto fail_free; + } + + file->fd = open(path, O_RDONLY); + if (file->fd < 0) { + perror(path); + goto fail_path; + } + + strm->buffer = file->buffer; + strm->precache = file_precache; + strm->get_filename = file_get_filename; + obj->destroy = file_destroy; + return strm; +fail_path: + free(file->path); +fail_free: + free(file); + return NULL; +} + +istream_t *istream_open_stdin(void) +{ + file_istream_t *file = calloc(1, sizeof(*file)); + sqfs_object_t *obj = (sqfs_object_t *)file; + istream_t *strm = (istream_t *)file; + + if (file == NULL) + goto fail; + + file->path = strdup("stdin"); + if (file->path == NULL) + goto fail; + + file->fd = STDIN_FILENO; + strm->buffer = file->buffer; + strm->precache = file_precache; + strm->get_filename = file_get_filename; + obj->destroy = file_destroy; + return strm; +fail: + perror("creating file wrapper for stdin"); + free(file); + return NULL; +} diff --git a/lib/io/unix/ostream.c b/lib/io/unix/ostream.c new file mode 100644 index 0000000..17f1998 --- /dev/null +++ b/lib/io/unix/ostream.c @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * ostream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +typedef struct { + ostream_t base; + char *path; + int fd; + + off_t sparse_count; + off_t size; +} file_ostream_t; + +static int file_append(ostream_t *strm, const void *data, size_t size) +{ + file_ostream_t *file = (file_ostream_t *)strm; + ssize_t ret; + + if (size == 0) + return 0; + + if (file->sparse_count > 0) { + if (lseek(file->fd, file->sparse_count, SEEK_CUR) == (off_t)-1) + goto fail_errno; + + file->sparse_count = 0; + } + + while (size > 0) { + ret = write(file->fd, data, size); + + if (ret == 0) { + fprintf(stderr, "%s: truncated data write.\n", + file->path); + return -1; + } + + if (ret < 0) { + if (errno == EINTR) + continue; + goto fail_errno; + } + + file->size += ret; + size -= ret; + data = (const char *)data + ret; + } + + return 0; +fail_errno: + perror(file->path); + return -1; +} + +static int file_append_sparse(ostream_t *strm, size_t size) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + file->sparse_count += size; + file->size += size; + return 0; +} + +static int file_flush(ostream_t *strm) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + if (file->sparse_count > 0) { + if (ftruncate(file->fd, file->size) != 0) + goto fail; + } + + if (fsync(file->fd) != 0) { + if (errno == EINVAL) + return 0; + goto fail; + } + + return 0; +fail: + perror(file->path); + return -1; +} + +static void file_destroy(sqfs_object_t *obj) +{ + file_ostream_t *file = (file_ostream_t *)obj; + + if (file->fd != STDOUT_FILENO) + close(file->fd); + + free(file->path); + free(file); +} + +static const char *file_get_filename(ostream_t *strm) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + return file->path; +} + +ostream_t *ostream_open_file(const char *path, int flags) +{ + file_ostream_t *file = calloc(1, sizeof(*file)); + sqfs_object_t *obj = (sqfs_object_t *)file; + ostream_t *strm = (ostream_t *)file; + + if (file == NULL) { + perror(path); + return NULL; + } + + file->path = strdup(path); + if (file->path == NULL) { + perror(path); + goto fail_free; + } + + if (flags & OSTREAM_OPEN_OVERWRITE) { + file->fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + } else { + file->fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644); + } + + if (file->fd < 0) { + perror(path); + goto fail_path; + } + + if (flags & OSTREAM_OPEN_SPARSE) + strm->append_sparse = file_append_sparse; + + strm->append = file_append; + strm->flush = file_flush; + strm->get_filename = file_get_filename; + obj->destroy = file_destroy; + return strm; +fail_path: + free(file->path); +fail_free: + free(file); + return NULL; +} + +ostream_t *ostream_open_stdout(void) +{ + file_ostream_t *file = calloc(1, sizeof(*file)); + sqfs_object_t *obj = (sqfs_object_t *)file; + ostream_t *strm = (ostream_t *)file; + + if (file == NULL) + goto fail; + + file->path = strdup("stdout"); + if (file->path == NULL) + goto fail; + + file->fd = STDOUT_FILENO; + strm->append = file_append; + strm->flush = file_flush; + strm->get_filename = file_get_filename; + obj->destroy = file_destroy; + return strm; +fail: + perror("creating file wrapper for stdout"); + free(file); + return NULL; +} diff --git a/lib/io/win32/istream.c b/lib/io/win32/istream.c new file mode 100644 index 0000000..b591584 --- /dev/null +++ b/lib/io/win32/istream.c @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +#define WIN32_LEAN_AND_MEAN +#include + +typedef struct { + istream_t base; + char *path; + HANDLE hnd; + + sqfs_u8 buffer[BUFSZ]; +} file_istream_t; + +static int file_precache(istream_t *strm) +{ + file_istream_t *file = (file_istream_t *)strm; + DWORD diff, actual; + HANDLE hnd; + + hnd = file->path == NULL ? GetStdHandle(STD_INPUT_HANDLE) : file->hnd; + + while (strm->buffer_used < sizeof(file->buffer)) { + diff = sizeof(file->buffer) - strm->buffer_used; + + if (!ReadFile(hnd, strm->buffer + strm->buffer_used, + diff, &actual, NULL)) { + DWORD error = GetLastError(); + + if (error == ERROR_HANDLE_EOF || + error == ERROR_BROKEN_PIPE) { + strm->eof = true; + break; + } + + SetLastError(error); + + w32_perror(file->path == NULL ? "stdin" : file->path); + return -1; + } + + if (actual == 0) { + strm->eof = true; + break; + } + + strm->buffer_used += actual; + } + + return 0; +} + +static const char *file_get_filename(istream_t *strm) +{ + file_istream_t *file = (file_istream_t *)strm; + + return file->path == NULL ? "stdin" : file->path; +} + +static void file_destroy(sqfs_object_t *obj) +{ + file_istream_t *file = (file_istream_t *)obj; + + if (file->path != NULL) { + CloseHandle(file->hnd); + free(file->path); + } + + free(file); +} + +istream_t *istream_open_file(const char *path) +{ + file_istream_t *file = calloc(1, sizeof(*file)); + sqfs_object_t *obj = (sqfs_object_t *)file; + istream_t *strm = (istream_t *)file; + WCHAR *wpath = NULL; + + if (file == NULL) { + perror(path); + return NULL; + } + + wpath = path_to_windows(path); + if (wpath == NULL) + goto fail_free; + + file->path = strdup(path); + if (file->path == NULL) { + perror(path); + goto fail_free; + } + + file->hnd = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (file->hnd == INVALID_HANDLE_VALUE) { + perror(path); + goto fail_path; + } + + free(wpath); + + strm->buffer = file->buffer; + strm->precache = file_precache; + strm->get_filename = file_get_filename; + obj->destroy = file_destroy; + return strm; +fail_path: + free(file->path); +fail_free: + free(wpath); + free(file); + return NULL; +} + +istream_t *istream_open_stdin(void) +{ + file_istream_t *file = calloc(1, sizeof(*file)); + sqfs_object_t *obj = (sqfs_object_t *)file; + istream_t *strm = (istream_t *)file; + + if (file == NULL) { + perror("stdin"); + return NULL; + } + + strm->buffer = file->buffer; + strm->precache = file_precache; + strm->get_filename = file_get_filename; + obj->destroy = file_destroy; + return strm; +} diff --git a/lib/io/win32/ostream.c b/lib/io/win32/ostream.c new file mode 100644 index 0000000..2bd78c8 --- /dev/null +++ b/lib/io/win32/ostream.c @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * ostream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +#define WIN32_LEAN_AND_MEAN +#include + +typedef struct { + ostream_t base; + char *path; + HANDLE hnd; +} file_ostream_t; + +static int w32_append(HANDLE hnd, const char *filename, + const void *data, size_t size) +{ + DWORD diff; + + while (size > 0) { + if (!WriteFile(hnd, data, size, &diff, NULL)) { + w32_perror(filename); + return -1; + } + + size -= diff; + data = (const char *)data + diff; + } + + return 0; +} + +static int w32_flush(HANDLE hnd, const char *filename) +{ + if (!FlushFileBuffers(hnd)) { + w32_perror(filename); + return -1; + } + + return 0; +} + +/*****************************************************************************/ + +static int file_append(ostream_t *strm, const void *data, size_t size) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + return w32_append(file->hnd, file->path, data, size); +} + +static int file_append_sparse(ostream_t *strm, size_t size) +{ + file_ostream_t *file = (file_ostream_t *)strm; + LARGE_INTEGER pos; + + pos.QuadPart = size; + + if (!SetFilePointerEx(file->hnd, pos, NULL, FILE_CURRENT)) + goto fail; + + if (!SetEndOfFile(file->hnd)) + goto fail; + + return 0; +fail: + w32_perror(file->path); + return -1; +} + +static int file_flush(ostream_t *strm) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + return w32_flush(file->hnd, file->path); +} + +static void file_destroy(sqfs_object_t *obj) +{ + file_ostream_t *file = (file_ostream_t *)obj; + + CloseHandle(file->hnd); + free(file->path); + free(file); +} + +static const char *file_get_filename(ostream_t *strm) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + return file->path; +} + +/*****************************************************************************/ + +static int stdout_append(ostream_t *strm, const void *data, size_t size) +{ + (void)strm; + return w32_append(GetStdHandle(STD_OUTPUT_HANDLE), "stdout", + data, size); +} + +static int stdout_flush(ostream_t *strm) +{ + (void)strm; + return w32_flush(GetStdHandle(STD_OUTPUT_HANDLE), "stdout"); +} + +static void stdout_destroy(sqfs_object_t *obj) +{ + free(obj); +} + +static const char *stdout_get_filename(ostream_t *strm) +{ + (void)strm; + return "stdout"; +} + +/*****************************************************************************/ + +ostream_t *ostream_open_file(const char *path, int flags) +{ + file_ostream_t *file = calloc(1, sizeof(*file)); + sqfs_object_t *obj = (sqfs_object_t *)file; + ostream_t *strm = (ostream_t *)file; + int access_flags, creation_mode; + WCHAR *wpath = NULL; + + if (file == NULL) { + perror(path); + return NULL; + } + + wpath = path_to_windows(path); + if (wpath == NULL) + goto fail_free; + + file->path = strdup(path); + if (file->path == NULL) { + perror(path); + goto fail_free; + } + + access_flags = GENERIC_WRITE; + + if (flags & OSTREAM_OPEN_OVERWRITE) { + creation_mode = CREATE_ALWAYS; + } else { + creation_mode = CREATE_NEW; + } + + file->hnd = CreateFileW(wpath, access_flags, 0, NULL, creation_mode, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (file->hnd == INVALID_HANDLE_VALUE) { + w32_perror(path); + goto fail_path; + } + + free(wpath); + + if (flags & OSTREAM_OPEN_SPARSE) + strm->append_sparse = file_append_sparse; + + strm->append = file_append; + strm->flush = file_flush; + strm->get_filename = file_get_filename; + obj->destroy = file_destroy; + return strm; +fail_path: + free(file->path); +fail_free: + free(file); + free(wpath); + return NULL; +} + +ostream_t *ostream_open_stdout(void) +{ + ostream_t *strm = calloc(1, sizeof(*strm)); + sqfs_object_t *obj = (sqfs_object_t *)strm; + + if (strm == NULL) { + perror("creating stdout file wrapper"); + return NULL; + } + + strm->append = stdout_append; + strm->flush = stdout_flush; + strm->get_filename = stdout_get_filename; + obj->destroy = stdout_destroy; + return strm; +} diff --git a/lib/io/xfrm.c b/lib/io/xfrm.c new file mode 100644 index 0000000..22fd953 --- /dev/null +++ b/lib/io/xfrm.c @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * compressor.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "internal.h" + +int io_compressor_id_from_name(const char *name) +{ + if (strcmp(name, "gzip") == 0) + return IO_COMPRESSOR_GZIP; + + if (strcmp(name, "xz") == 0) + return IO_COMPRESSOR_XZ; + + if (strcmp(name, "zstd") == 0) + return IO_COMPRESSOR_ZSTD; + + if (strcmp(name, "bzip2") == 0) + return IO_COMPRESSOR_BZIP2; + + return -1; +} + +const char *io_compressor_name_from_id(int id) +{ + if (id == IO_COMPRESSOR_GZIP) + return "gzip"; + + if (id == IO_COMPRESSOR_XZ) + return "xz"; + + if (id == IO_COMPRESSOR_ZSTD) + return "zstd"; + + if (id == IO_COMPRESSOR_BZIP2) + return "bzip2"; + + return NULL; +} + +bool io_compressor_exists(int id) +{ + switch (id) { +#ifdef WITH_GZIP + case IO_COMPRESSOR_GZIP: + return true; +#endif +#ifdef WITH_XZ + case IO_COMPRESSOR_XZ: + return true; +#endif +#if defined(WITH_ZSTD) && defined(HAVE_ZSTD_STREAM) + case IO_COMPRESSOR_ZSTD: + return true; +#endif +#ifdef WITH_BZIP2 + case IO_COMPRESSOR_BZIP2: + return true; +#endif + default: + break; + } + + return false; +} diff --git a/tests/Makemodule.am b/tests/Makemodule.am index 3165889..0ae3f8b 100644 --- a/tests/Makemodule.am +++ b/tests/Makemodule.am @@ -1,5 +1,5 @@ include tests/libutil/Makemodule.am -include tests/libfstream/Makemodule.am +include tests/libio/Makemodule.am include tests/libfstree/Makemodule.am include tests/libtar/Makemodule.am include tests/libsqfs/Makemodule.am diff --git a/tests/libfstream/Makemodule.am b/tests/libfstream/Makemodule.am deleted file mode 100644 index 57a98bc..0000000 --- a/tests/libfstream/Makemodule.am +++ /dev/null @@ -1,68 +0,0 @@ -test_get_line_SOURCES = tests/libfstream/get_line.c tests/test.h -test_get_line_LDADD = libfstream.a libcompat.a -test_get_line_CPPFLAGS = $(AM_CPPFLAGS) -test_get_line_CPPFLAGS += -DTESTFILE=$(top_srcdir)/tests/libfstream/get_line.txt - -test_xfrm_bzip2_SOURCES = tests/libfstream/uncompress.c tests/test.h -test_xfrm_bzip2_LDADD = libfstream.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) -test_xfrm_bzip2_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) -test_xfrm_bzip2_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_BZIP2=1 - -test_xfrm_bzip22_SOURCES = tests/libfstream/uncompress.c tests/test.h -test_xfrm_bzip22_LDADD = libfstream.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) -test_xfrm_bzip22_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) -test_xfrm_bzip22_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_BZIP22=1 - -test_xfrm_xz_SOURCES = tests/libfstream/uncompress.c tests/test.h -test_xfrm_xz_LDADD = libfstream.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) -test_xfrm_xz_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) -test_xfrm_xz_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_XZ=1 - -test_xfrm_xz2_SOURCES = tests/libfstream/uncompress.c tests/test.h -test_xfrm_xz2_LDADD = libfstream.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) -test_xfrm_xz2_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) -test_xfrm_xz2_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_XZ2=1 - -test_xfrm_gzip_SOURCES = tests/libfstream/uncompress.c tests/test.h -test_xfrm_gzip_LDADD = libfstream.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) -test_xfrm_gzip_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) -test_xfrm_gzip_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_GZIP=1 - -test_xfrm_zstd_SOURCES = tests/libfstream/uncompress.c tests/test.h -test_xfrm_zstd_LDADD = libfstream.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) -test_xfrm_zstd_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) -test_xfrm_zstd_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_ZSTD=1 - -test_xfrm_zstd2_SOURCES = tests/libfstream/uncompress.c tests/test.h -test_xfrm_zstd2_LDADD = libfstream.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) -test_xfrm_zstd2_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) -test_xfrm_zstd2_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_ZSTD2=1 - -if BUILD_TOOLS -check_PROGRAMS += test_get_line -TESTS += test_get_line - -if WITH_BZIP2 -check_PROGRAMS += test_xfrm_bzip2 test_xfrm_bzip22 -TESTS += test_xfrm_bzip2 test_xfrm_bzip22 -endif - -if WITH_XZ -check_PROGRAMS += test_xfrm_xz test_xfrm_xz2 -TESTS += test_xfrm_xz test_xfrm_xz2 -endif - -if WITH_GZIP -check_PROGRAMS += test_xfrm_gzip -TESTS += test_xfrm_gzip -endif - -if WITH_ZSTD -if HAVE_ZSTD_STREAM -check_PROGRAMS += test_xfrm_zstd test_xfrm_zstd2 -TESTS += test_xfrm_zstd test_xfrm_zstd2 -endif -endif -endif - -EXTRA_DIST += $(top_srcdir)/tests/libfstream/get_line.txt diff --git a/tests/libfstream/get_line.c b/tests/libfstream/get_line.c deleted file mode 100644 index 7d9a26a..0000000 --- a/tests/libfstream/get_line.c +++ /dev/null @@ -1,166 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * get_line.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "config.h" - -#include "fstream.h" -#include "../test.h" - -typedef struct { - size_t line_num; - const char *str; -} line_t; - -static void run_test_case(const line_t *lines, size_t count, - int flags) -{ - size_t i, line_num, old_line_num; - istream_t *fp; - char *line; - int ret; - - fp = istream_open_file(STRVALUE(TESTFILE)); - TEST_NOT_NULL(fp); - - line_num = 1; - line = NULL; - - for (i = 0; i < count; ++i) { - old_line_num = line_num; - ret = istream_get_line(fp, &line, &line_num, flags); - - TEST_ASSERT(line_num >= old_line_num); - TEST_EQUAL_I(ret, 0); - TEST_NOT_NULL(line); - - TEST_EQUAL_UI(line_num, lines[i].line_num); - TEST_STR_EQUAL(line, lines[i].str); - - free(line); - line = NULL; - line_num += 1; - } - - ret = istream_get_line(fp, &line, &line_num, flags); - TEST_ASSERT(ret > 0); - - sqfs_destroy(fp); -} - -static const line_t lines_raw[] = { - { 1, "" }, - { 2, "The quick" }, - { 3, " " }, - { 4, " brown fox " }, - { 5, "" }, - { 6, "jumps over" }, - { 7, "the" }, - { 8, "lazy" }, - { 9, "" }, - { 10, "dog" }, - { 11, "" }, -}; - -static const line_t lines_ltrim[] = { - { 1, "" }, - { 2, "The quick" }, - { 3, "" }, - { 4, "brown fox " }, - { 5, "" }, - { 6, "jumps over" }, - { 7, "the" }, - { 8, "lazy" }, - { 9, "" }, - { 10, "dog" }, - { 11, "" }, -}; - -static const line_t lines_rtrim[] = { - { 1, "" }, - { 2, "The quick" }, - { 3, "" }, - { 4, " brown fox" }, - { 5, "" }, - { 6, "jumps over" }, - { 7, "the" }, - { 8, "lazy" }, - { 9, "" }, - { 10, "dog" }, - { 11, "" }, -}; - -static const line_t lines_trim[] = { - { 1, "" }, - { 2, "The quick" }, - { 3, "" }, - { 4, "brown fox" }, - { 5, "" }, - { 6, "jumps over" }, - { 7, "the" }, - { 8, "lazy" }, - { 9, "" }, - { 10, "dog" }, - { 11, "" }, -}; - -static const line_t lines_no_empty[] = { - { 2, "The quick" }, - { 3, " " }, - { 4, " brown fox " }, - { 6, "jumps over" }, - { 7, "the" }, - { 8, "lazy" }, - { 10, "dog" }, -}; - -static const line_t lines_no_empty_ltrim[] = { - { 2, "The quick" }, - { 4, "brown fox " }, - { 6, "jumps over" }, - { 7, "the" }, - { 8, "lazy" }, - { 10, "dog" }, -}; - -static const line_t lines_no_empty_rtrim[] = { - { 2, "The quick" }, - { 4, " brown fox" }, - { 6, "jumps over" }, - { 7, "the" }, - { 8, "lazy" }, - { 10, "dog" }, -}; - -static const line_t lines_no_empty_trim[] = { - { 2, "The quick" }, - { 4, "brown fox" }, - { 6, "jumps over" }, - { 7, "the" }, - { 8, "lazy" }, - { 10, "dog" }, -}; - -int main(int argc, char **argv) -{ - (void)argc; (void)argv; - - run_test_case(lines_raw, 11, 0); - run_test_case(lines_ltrim, 11, ISTREAM_LINE_LTRIM); - run_test_case(lines_rtrim, 11, ISTREAM_LINE_RTRIM); - run_test_case(lines_trim, 11, - ISTREAM_LINE_LTRIM | ISTREAM_LINE_RTRIM); - - run_test_case(lines_no_empty, 7, ISTREAM_LINE_SKIP_EMPTY); - run_test_case(lines_no_empty_ltrim, 6, - ISTREAM_LINE_SKIP_EMPTY | ISTREAM_LINE_LTRIM); - run_test_case(lines_no_empty_rtrim, 6, - ISTREAM_LINE_SKIP_EMPTY | ISTREAM_LINE_RTRIM); - run_test_case(lines_no_empty_trim, 6, - ISTREAM_LINE_SKIP_EMPTY | ISTREAM_LINE_LTRIM | - ISTREAM_LINE_RTRIM); - - return EXIT_SUCCESS; -} diff --git a/tests/libfstream/get_line.txt b/tests/libfstream/get_line.txt deleted file mode 100644 index a1994f0..0000000 --- a/tests/libfstream/get_line.txt +++ /dev/null @@ -1,11 +0,0 @@ - -The quick - - brown fox - -jumps over -the -lazy - -dog - diff --git a/tests/libfstream/uncompress.c b/tests/libfstream/uncompress.c deleted file mode 100644 index 5f0cbec..0000000 --- a/tests/libfstream/uncompress.c +++ /dev/null @@ -1,431 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * uncompress.c - * - * Copyright (C) 2021 David Oberhollenzer - */ -#include "fstream.h" -#include "../test.h" - -static sqfs_u8 data_in[] = { -#if defined(TEST_BZIP2) - 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, - 0x53, 0x59, 0x05, 0x24, 0x28, 0x04, 0x00, 0x00, - 0x27, 0xd7, 0x80, 0x00, 0x10, 0x40, 0x05, 0x06, - 0x04, 0x02, 0x00, 0x3f, 0xe7, 0xff, 0x40, 0x30, - 0x01, 0x2d, 0x23, 0x62, 0x26, 0x05, 0x3d, 0x03, - 0x54, 0xfd, 0x53, 0x4c, 0x86, 0x9e, 0x90, 0x6a, - 0x9e, 0x9e, 0x85, 0x3c, 0xa0, 0x00, 0x00, 0x1a, - 0x9e, 0x41, 0x13, 0x13, 0x28, 0x69, 0x03, 0xd4, - 0x0f, 0x1c, 0x70, 0xd0, 0xb4, 0xe3, 0xe4, 0x75, - 0x4e, 0x8b, 0x67, 0x43, 0x7b, 0x38, 0x27, 0x77, - 0xe4, 0xc1, 0x98, 0x3a, 0x2d, 0x3a, 0xe4, 0x44, - 0x98, 0xdc, 0x49, 0x8b, 0x22, 0x48, 0xfc, 0xc8, - 0xe7, 0x57, 0x05, 0x3c, 0x5a, 0xee, 0x5a, 0x84, - 0xcd, 0x7c, 0x8f, 0x26, 0x6b, 0x6e, 0xf7, 0xb5, - 0x49, 0x1f, 0x79, 0x42, 0x5d, 0x09, 0x8c, 0xc6, - 0xde, 0x0c, 0x0d, 0xb1, 0x46, 0xb4, 0xee, 0xd9, - 0x8f, 0x33, 0x37, 0x04, 0xa9, 0x05, 0x49, 0xe3, - 0x04, 0x16, 0x62, 0x36, 0x3a, 0x01, 0xda, 0xd4, - 0xc8, 0x8a, 0x32, 0x02, 0x1f, 0x62, 0x4b, 0xa4, - 0x49, 0x59, 0xda, 0x50, 0x85, 0x69, 0x35, 0x21, - 0x10, 0xc6, 0x8a, 0x3c, 0x44, 0x95, 0xb0, 0xbc, - 0xc5, 0x6b, 0xea, 0xfb, 0x40, 0xbd, 0x14, 0x01, - 0x6a, 0xfa, 0xcd, 0x67, 0xd8, 0x2d, 0x93, 0x8b, - 0xda, 0x44, 0x1b, 0xe9, 0x5a, 0x87, 0x60, 0xb0, - 0xe0, 0x73, 0xd1, 0x01, 0x3a, 0x66, 0x05, 0xcc, - 0x34, 0xa0, 0x63, 0x8d, 0x35, 0x5e, 0xa0, 0x9f, - 0x05, 0x89, 0x15, 0x51, 0x48, 0x16, 0x0c, 0x61, - 0xf4, 0x30, 0xb8, 0x07, 0x29, 0xc0, 0xf5, 0x1a, - 0xe1, 0x0d, 0x6c, 0xfe, 0x91, 0xda, 0x13, 0x2f, - 0x8e, 0x5b, 0x1c, 0xfc, 0xb3, 0xb2, 0x30, 0x9d, - 0xf6, 0x09, 0x30, 0x55, 0x30, 0x67, 0xc2, 0x87, - 0xe9, 0x9a, 0xd4, 0x1d, 0x66, 0x11, 0x54, 0x89, - 0x21, 0xe1, 0x55, 0x84, 0xbf, 0xa6, 0x11, 0xa4, - 0xb8, 0x40, 0xed, 0x42, 0x20, 0xb9, 0xb7, 0x26, - 0x31, 0x14, 0x4f, 0x86, 0xdc, 0x50, 0x34, 0x38, - 0x8b, 0x57, 0x77, 0x21, 0xf6, 0x89, 0xbd, 0xc5, - 0x65, 0xc3, 0x23, 0x45, 0xec, 0x7f, 0x8b, 0xb9, - 0x22, 0x9c, 0x28, 0x48, 0x02, 0x92, 0x14, 0x02, - 0x00, -#elif defined(TEST_BZIP22) - 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, - 0x53, 0x59, 0x5d, 0x09, 0x24, 0x1d, 0x00, 0x00, - 0x13, 0xd7, 0x80, 0x00, 0x10, 0x40, 0x05, 0x00, - 0x04, 0x02, 0x00, 0x3e, 0xa7, 0xff, 0x40, 0x30, - 0x00, 0xac, 0x43, 0x54, 0xf5, 0x36, 0x4c, 0xa7, - 0xa8, 0xd3, 0x6a, 0x60, 0x81, 0x40, 0x00, 0xd0, - 0x32, 0x64, 0x0d, 0x53, 0xda, 0x02, 0x09, 0xa2, - 0x68, 0x34, 0xd1, 0x27, 0x4a, 0xdd, 0xf2, 0x0a, - 0x73, 0x43, 0xf9, 0xa2, 0x51, 0x85, 0x76, 0x45, - 0x9a, 0x68, 0x3a, 0xe7, 0x0d, 0xc0, 0x21, 0x4a, - 0xc4, 0xf9, 0xf7, 0x40, 0xc3, 0x10, 0xb2, 0x9b, - 0x58, 0x56, 0x71, 0x50, 0x2f, 0xa4, 0xc5, 0x61, - 0x19, 0xf6, 0x59, 0x06, 0x82, 0x03, 0x7f, 0xeb, - 0xd2, 0x61, 0x88, 0xcd, 0xe8, 0xf7, 0xe8, 0x87, - 0x59, 0x9d, 0xe1, 0xf8, 0x19, 0x6e, 0xad, 0x77, - 0xbf, 0x34, 0x17, 0x21, 0x6b, 0x91, 0xc9, 0x52, - 0xd0, 0x81, 0x1e, 0xb5, 0x0b, 0xee, 0x42, 0x84, - 0x80, 0xd5, 0xa1, 0x8a, 0x04, 0x18, 0x4d, 0xf3, - 0xda, 0x7e, 0x3c, 0x40, 0xa4, 0xdb, 0xe5, 0xf0, - 0x37, 0x40, 0x3a, 0x7d, 0xa7, 0x45, 0x21, 0xf2, - 0x5a, 0x7b, 0x59, 0x56, 0x16, 0xd5, 0xac, 0x9f, - 0x60, 0x85, 0x0e, 0xf5, 0x73, 0xd9, 0x47, 0xe2, - 0xee, 0x48, 0xa7, 0x0a, 0x12, 0x0b, 0xa1, 0x24, - 0x83, 0xa0, - 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, - 0x53, 0x59, 0x2c, 0x24, 0x39, 0xa0, 0x00, 0x00, - 0x1f, 0x55, 0x80, 0x00, 0x10, 0x40, 0x05, 0x06, - 0x00, 0x3f, 0xe7, 0xff, 0x40, 0x30, 0x00, 0xb5, - 0x91, 0x13, 0x4f, 0x54, 0x7a, 0x6a, 0x6d, 0x4d, - 0xa2, 0x68, 0x0c, 0x84, 0x53, 0xf5, 0x30, 0x89, - 0xa3, 0xd4, 0x0d, 0x0f, 0x49, 0xa0, 0xd4, 0xf4, - 0xd1, 0x53, 0xf4, 0x93, 0x69, 0x3c, 0x81, 0x1a, - 0x65, 0x53, 0x90, 0x51, 0x07, 0x2a, 0xad, 0x8f, - 0x63, 0xba, 0x25, 0xc2, 0x0c, 0x8b, 0xb9, 0x95, - 0x15, 0xd8, 0xda, 0x61, 0x5c, 0xa9, 0xe4, 0x0b, - 0x21, 0xc9, 0x97, 0x57, 0x01, 0x28, 0x9b, 0xfb, - 0x94, 0xb9, 0x48, 0xa3, 0x0a, 0xc6, 0x1c, 0x54, - 0x98, 0x9a, 0x39, 0xc3, 0x87, 0x90, 0x33, 0x58, - 0x2d, 0x3e, 0x16, 0xb1, 0xae, 0x26, 0x89, 0x75, - 0xf5, 0x77, 0xa5, 0x8e, 0x5b, 0x8c, 0x8a, 0x39, - 0xbd, 0x75, 0x21, 0x9d, 0x99, 0x18, 0x4a, 0x91, - 0xab, 0xbc, 0x08, 0x87, 0xa4, 0xf1, 0x81, 0xb5, - 0xb4, 0xb0, 0xfe, 0x6b, 0x9f, 0xbe, 0x19, 0x82, - 0xd1, 0x50, 0xe1, 0x5e, 0x13, 0xb5, 0xc6, 0x2c, - 0xa4, 0x82, 0xf2, 0x5c, 0xc3, 0x20, 0x41, 0x13, - 0x56, 0x63, 0x3d, 0xec, 0x71, 0x2a, 0xbf, 0x2c, - 0x60, 0x2f, 0x7a, 0x4d, 0xcb, 0x3f, 0x8b, 0xb9, - 0x22, 0x9c, 0x28, 0x48, 0x16, 0x12, 0x1c, 0xd0, - 0x00, -#elif defined(TEST_XZ) - 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x00, - 0xff, 0x12, 0xd9, 0x41, 0x02, 0x00, 0x21, 0x01, - 0x1c, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x58, 0xcc, - 0xe0, 0x01, 0xbd, 0x01, 0x43, 0x5d, 0x00, 0x26, - 0x1b, 0xca, 0x46, 0x67, 0x5a, 0xf2, 0x77, 0xb8, - 0x7d, 0x86, 0xd8, 0x41, 0xdb, 0x05, 0x35, 0xcd, - 0x83, 0xa5, 0x7c, 0x12, 0xa5, 0x05, 0xdb, 0x90, - 0xbd, 0x2f, 0x14, 0xd3, 0x71, 0x72, 0x96, 0xa8, - 0x8a, 0x7d, 0x84, 0x56, 0x71, 0x8d, 0x6a, 0x22, - 0x98, 0xab, 0x9e, 0x3d, 0xc3, 0x55, 0xef, 0xcc, - 0xa5, 0xc3, 0xdd, 0x5b, 0x8e, 0xbf, 0x03, 0x81, - 0x21, 0x40, 0xd6, 0x26, 0x91, 0x02, 0x45, 0x4e, - 0x20, 0x91, 0xcf, 0x8c, 0x51, 0x22, 0x02, 0x70, - 0xba, 0x05, 0x6b, 0x83, 0xef, 0x3f, 0x8e, 0x09, - 0xef, 0x88, 0xf5, 0x37, 0x1b, 0x89, 0x8d, 0xff, - 0x1e, 0xee, 0xe8, 0xb0, 0xac, 0xf2, 0x6e, 0xd4, - 0x3e, 0x25, 0xaf, 0xa0, 0x6d, 0x2e, 0xc0, 0x7f, - 0xb5, 0xa0, 0xcb, 0x90, 0x1f, 0x08, 0x1a, 0xe2, - 0x90, 0x20, 0x19, 0x71, 0x0c, 0xe8, 0x3f, 0xe5, - 0x39, 0xeb, 0x9a, 0x62, 0x4f, 0x06, 0xda, 0x3c, - 0x32, 0x59, 0xcc, 0x83, 0xe3, 0x83, 0x0f, 0x38, - 0x7d, 0x43, 0x37, 0x6c, 0x0b, 0x05, 0x65, 0x98, - 0x25, 0xdb, 0xf2, 0xc0, 0x2d, 0x39, 0x36, 0x5d, - 0xd4, 0xb6, 0xc2, 0x79, 0x73, 0x3e, 0xc2, 0x6e, - 0x54, 0xec, 0x78, 0x2b, 0x5d, 0xf1, 0xd1, 0xb4, - 0xb3, 0xcd, 0xf3, 0x89, 0xf5, 0x81, 0x3e, 0x2c, - 0x65, 0xd6, 0x73, 0xd3, 0x1b, 0x20, 0x68, 0x0c, - 0x93, 0xd4, 0xfc, 0x9f, 0xf8, 0xa7, 0xd4, 0xfa, - 0x3a, 0xb1, 0x13, 0x93, 0x4b, 0xec, 0x78, 0x7d, - 0x5c, 0x81, 0x80, 0xe5, 0x14, 0x78, 0xfe, 0x7e, - 0xde, 0xf7, 0xad, 0x9e, 0x84, 0xba, 0xf1, 0x00, - 0xe9, 0xbd, 0x2c, 0xf4, 0x70, 0x7d, 0xbe, 0x29, - 0xb9, 0xf0, 0x10, 0xb9, 0x01, 0xf1, 0x76, 0x8a, - 0x5a, 0xad, 0x02, 0xa1, 0x32, 0xc8, 0x53, 0x59, - 0x11, 0x4c, 0xe2, 0x98, 0x34, 0xd9, 0x23, 0x51, - 0x4a, 0x40, 0x2b, 0x87, 0x41, 0xdd, 0x50, 0xcd, - 0x98, 0x1e, 0x29, 0x86, 0x23, 0x93, 0x3e, 0x9b, - 0x6b, 0x16, 0xa1, 0x40, 0xac, 0xe7, 0x40, 0xfe, - 0xa9, 0x87, 0x48, 0x25, 0x52, 0x02, 0x8b, 0xc4, - 0x68, 0x08, 0x5a, 0x62, 0xc1, 0xb2, 0x07, 0x3b, - 0x26, 0x1e, 0x59, 0x5c, 0x47, 0x24, 0xae, 0x8e, - 0xe5, 0xf7, 0xe6, 0x4b, 0x13, 0xb4, 0x6d, 0x46, - 0x65, 0x4f, 0xd0, 0x48, 0xcc, 0x51, 0x4b, 0x80, - 0xcb, 0xf1, 0xd4, 0x6c, 0x45, 0x98, 0x92, 0x47, - 0xeb, 0x60, 0x00, 0x00, 0x00, 0x01, 0xd7, 0x02, - 0xbe, 0x03, 0x00, 0x00, 0xda, 0x2c, 0x45, 0x49, - 0xa8, 0x00, 0x0a, 0xfc, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x59, 0x5a -#elif defined(TEST_XZ2) - 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x04, - 0xe6, 0xd6, 0xb4, 0x46, 0x02, 0x00, 0x21, 0x01, - 0x16, 0x00, 0x00, 0x00, 0x74, 0x2f, 0xe5, 0xa3, - 0xe0, 0x00, 0xdc, 0x00, 0xb3, 0x5d, 0x00, 0x26, - 0x1b, 0xca, 0x46, 0x67, 0x5a, 0xf2, 0x77, 0xb8, - 0x7d, 0x86, 0xd8, 0x41, 0xdb, 0x05, 0x35, 0xcd, - 0x83, 0xa5, 0x7c, 0x12, 0xa5, 0x05, 0xdb, 0x90, - 0xbd, 0x2f, 0x14, 0xd3, 0x71, 0x72, 0x96, 0xa8, - 0x8a, 0x7d, 0x84, 0x56, 0x71, 0x8d, 0x6a, 0x22, - 0x98, 0xab, 0x9e, 0x3d, 0xc3, 0x55, 0xef, 0xcc, - 0xa5, 0xc3, 0xdd, 0x5b, 0x8e, 0xbf, 0x03, 0x81, - 0x21, 0x40, 0xd6, 0x26, 0x91, 0x02, 0x45, 0x4e, - 0x20, 0x91, 0xcf, 0x8c, 0x51, 0x22, 0x02, 0x70, - 0xba, 0x05, 0x6b, 0x83, 0xef, 0x3f, 0x8e, 0x09, - 0xef, 0x88, 0xf5, 0x37, 0x1b, 0x89, 0x8d, 0xff, - 0x1e, 0xee, 0xe8, 0xb0, 0xac, 0xf2, 0x6e, 0xd4, - 0x3e, 0x25, 0xaf, 0xa0, 0x6d, 0x2e, 0xc0, 0x7f, - 0xb5, 0xa0, 0xcb, 0x90, 0x1f, 0x08, 0x1a, 0xe2, - 0x90, 0x20, 0x19, 0x71, 0x0c, 0xe8, 0x3f, 0xe5, - 0x39, 0xeb, 0x9a, 0x62, 0x4f, 0x06, 0xda, 0x3c, - 0x32, 0x59, 0xcc, 0x83, 0xe3, 0x83, 0x0f, 0x38, - 0x7d, 0x43, 0x37, 0x6c, 0x0b, 0x05, 0x65, 0x98, - 0x25, 0xdb, 0xf2, 0xc0, 0x2d, 0x39, 0x36, 0x5d, - 0xd4, 0xb6, 0xc2, 0x79, 0x73, 0x3e, 0xc2, 0x6e, - 0x54, 0xec, 0x78, 0x2b, 0x5d, 0xf1, 0xd1, 0xb4, - 0xb3, 0xcd, 0xf3, 0x89, 0xf5, 0x80, 0x79, 0x46, - 0xc0, 0x00, 0x00, 0x00, 0xc4, 0xf5, 0x1d, 0x08, - 0xf0, 0x34, 0x3a, 0x59, 0x00, 0x01, 0xcf, 0x01, - 0xdd, 0x01, 0x00, 0x00, 0x7f, 0x5a, 0x77, 0xcb, - 0xb1, 0xc4, 0x67, 0xfb, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x59, 0x5a, - 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x04, - 0xe6, 0xd6, 0xb4, 0x46, 0x02, 0x00, 0x21, 0x01, - 0x16, 0x00, 0x00, 0x00, 0x74, 0x2f, 0xe5, 0xa3, - 0xe0, 0x00, 0xe0, 0x00, 0xb7, 0x5d, 0x00, 0x31, - 0x9b, 0xca, 0x19, 0xc5, 0x54, 0xec, 0xb6, 0x54, - 0xe7, 0xb1, 0x7d, 0xc4, 0x57, 0x9e, 0x6c, 0x89, - 0xad, 0x4a, 0x6d, 0x16, 0xd8, 0x3c, 0x05, 0x94, - 0x10, 0x16, 0x99, 0x38, 0x21, 0xa3, 0xb9, 0xc5, - 0x80, 0xff, 0xfc, 0xee, 0xd4, 0xd5, 0x3f, 0xdd, - 0x8c, 0xd7, 0x3d, 0x8f, 0x76, 0xec, 0x96, 0x9d, - 0x20, 0xac, 0xcb, 0x18, 0xf5, 0xb2, 0x9c, 0x12, - 0xf6, 0x7c, 0x33, 0xdc, 0x4f, 0x9a, 0xe5, 0x2d, - 0x63, 0x68, 0xa4, 0x2b, 0x1d, 0x0a, 0x1e, 0xf0, - 0xfe, 0x73, 0xf2, 0x5f, 0x7b, 0xb4, 0xea, 0x54, - 0xad, 0x27, 0xd1, 0xff, 0xb6, 0x50, 0x06, 0x7b, - 0x51, 0x3f, 0x25, 0x8a, 0xcf, 0x4c, 0x03, 0x3e, - 0xc3, 0xad, 0x47, 0x34, 0xcf, 0xba, 0x45, 0x79, - 0xd0, 0x7b, 0xf6, 0x66, 0x63, 0xc0, 0xc6, 0x69, - 0xa7, 0x51, 0x84, 0xa8, 0xa0, 0x0b, 0xbc, 0x6f, - 0x13, 0x89, 0xd6, 0x5e, 0xac, 0xca, 0x2f, 0xd2, - 0xe7, 0xe1, 0x1e, 0x78, 0x22, 0x3a, 0x59, 0x6c, - 0x9c, 0x8c, 0x65, 0xf1, 0x5b, 0xf4, 0xbf, 0xd5, - 0xdc, 0x05, 0xeb, 0x70, 0x10, 0xb8, 0x6c, 0xf2, - 0x13, 0x20, 0xb0, 0xdd, 0x3e, 0xb2, 0x92, 0x5b, - 0xa3, 0xf7, 0x94, 0xa1, 0xa1, 0x74, 0x36, 0x9a, - 0xf1, 0xd8, 0xc2, 0xf0, 0xc6, 0x29, 0x7e, 0x85, - 0x28, 0xf5, 0xf2, 0x21, 0x00, 0x00, 0x00, 0x00, - 0xc8, 0x80, 0x67, 0x40, 0xc3, 0xaa, 0x17, 0x57, - 0x00, 0x01, 0xd3, 0x01, 0xe1, 0x01, 0x00, 0x00, - 0x86, 0xdf, 0x9e, 0x05, 0xb1, 0xc4, 0x67, 0xfb, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5a -#elif defined(TEST_GZIP) - 0x1f, 0x8b, 0x08, 0x08, 0x82, 0xd4, 0x97, 0x60, - 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, - 0x78, 0x74, 0x00, 0x35, 0x90, 0xc1, 0x71, 0x43, - 0x31, 0x08, 0x44, 0xef, 0xbf, 0x8a, 0x2d, 0x20, - 0xf3, 0xab, 0x48, 0x6e, 0xb9, 0xa6, 0x00, 0x82, - 0xb0, 0xc3, 0x8c, 0x24, 0x64, 0x09, 0x3c, 0x2e, - 0x3f, 0xc8, 0x4e, 0x6e, 0x42, 0xc0, 0xb2, 0xfb, - 0x3e, 0x6d, 0x4a, 0x83, 0x8e, 0x15, 0x0d, 0xc5, - 0xaa, 0x4d, 0x2c, 0x75, 0x50, 0x13, 0x7f, 0x03, - 0x5b, 0x5f, 0xc2, 0x2e, 0x1e, 0x13, 0x54, 0x74, - 0xe8, 0x62, 0xed, 0x57, 0x48, 0xd5, 0x6c, 0x2e, - 0x29, 0xb9, 0x00, 0xd1, 0x58, 0xcd, 0xca, 0xe1, - 0xd2, 0x46, 0x2e, 0x6b, 0x67, 0x2d, 0x5a, 0xa2, - 0x3b, 0xc2, 0x51, 0xe9, 0x3b, 0xe5, 0x21, 0xfe, - 0x92, 0x16, 0x34, 0xba, 0x76, 0x02, 0x55, 0xbd, - 0x05, 0x9d, 0xf8, 0x72, 0x48, 0xd7, 0x96, 0xda, - 0x68, 0xba, 0x1f, 0xf7, 0x2c, 0xa9, 0xbd, 0x1d, - 0xb7, 0xd0, 0x85, 0x6e, 0xcb, 0x67, 0x14, 0xc8, - 0x43, 0x26, 0xab, 0x93, 0xab, 0x75, 0x44, 0xad, - 0xd4, 0xd8, 0x5e, 0xca, 0x7b, 0x48, 0x97, 0xee, - 0x4b, 0x4f, 0x49, 0x1d, 0x39, 0x0c, 0xa1, 0x34, - 0xde, 0xd2, 0x93, 0x1d, 0xcf, 0x00, 0x79, 0xca, - 0x4f, 0xbc, 0x6f, 0x49, 0x0a, 0x17, 0xe8, 0x8c, - 0x74, 0xf2, 0xca, 0xaa, 0x1d, 0x53, 0xc6, 0x94, - 0x1f, 0xe9, 0x45, 0x66, 0x06, 0xcf, 0x8f, 0xbb, - 0xd5, 0x18, 0x79, 0x4e, 0xd2, 0x4e, 0x26, 0x85, - 0xac, 0x25, 0x07, 0x6b, 0xad, 0xff, 0x84, 0x32, - 0x50, 0xe0, 0x12, 0x57, 0x25, 0x47, 0xdf, 0x86, - 0x30, 0x68, 0x66, 0x11, 0xf3, 0xc4, 0xc7, 0x83, - 0x65, 0xb8, 0xc4, 0xc6, 0x98, 0x0c, 0x8c, 0x99, - 0x84, 0x73, 0x8e, 0x63, 0x68, 0x21, 0xdf, 0x1b, - 0xd6, 0x8f, 0x31, 0x4d, 0x8b, 0xf4, 0x4d, 0x71, - 0x93, 0xca, 0xa3, 0x1c, 0x75, 0x10, 0x32, 0x02, - 0xec, 0x72, 0x51, 0x56, 0x42, 0x91, 0x25, 0x73, - 0x77, 0x9b, 0xd5, 0x6d, 0x83, 0x36, 0x20, 0x4d, - 0x1c, 0xeb, 0x8f, 0x6b, 0xb4, 0xf3, 0xf8, 0x05, - 0x6b, 0x8b, 0x8b, 0x20, 0xbe, 0x01, 0x00, 0x00 -#elif defined(TEST_ZSTD) - 0x28, 0xb5, 0x2f, 0xfd, 0x04, 0x88, 0xa5, 0x08, - 0x00, 0x46, 0x97, 0x3a, 0x1a, 0x80, 0x37, 0xcd, - 0x01, 0xc0, 0x8a, 0xec, 0xfe, 0x2d, 0xf2, 0xb9, - 0x44, 0x6b, 0xb9, 0x24, 0x77, 0x56, 0x5a, 0x33, - 0x17, 0x0b, 0x67, 0x83, 0x2e, 0x47, 0x07, 0x31, - 0x00, 0x32, 0x00, 0x33, 0x00, 0xc5, 0x2c, 0x5a, - 0x92, 0x93, 0x0f, 0x7b, 0xd1, 0x1d, 0x63, 0x2c, - 0xc8, 0x99, 0x94, 0x77, 0x8f, 0x94, 0x38, 0x75, - 0x80, 0x2f, 0xae, 0xc1, 0x3e, 0xd2, 0xcf, 0x49, - 0x15, 0x25, 0x1a, 0x87, 0x93, 0xdd, 0xe8, 0x00, - 0x6d, 0xaa, 0xf8, 0x54, 0x74, 0xe5, 0x48, 0x4d, - 0xa6, 0xf3, 0x1a, 0xa3, 0x13, 0x08, 0xe5, 0x26, - 0xdc, 0x73, 0xcc, 0x3e, 0xfd, 0x86, 0xa9, 0x52, - 0xb2, 0x76, 0xc7, 0xc2, 0x0f, 0xe4, 0x84, 0x4b, - 0x12, 0x61, 0x3a, 0x6b, 0x7a, 0x1e, 0x8a, 0x81, - 0xa9, 0x9b, 0x11, 0x37, 0x25, 0x55, 0x73, 0x73, - 0x71, 0xa0, 0x84, 0xca, 0xc3, 0x4b, 0xb5, 0xcc, - 0x50, 0xa6, 0x46, 0xd7, 0xe8, 0x08, 0xaa, 0x04, - 0x28, 0xb1, 0x8e, 0xea, 0xb4, 0x4a, 0x49, 0x2b, - 0xd6, 0x0d, 0x59, 0x68, 0xda, 0x64, 0x29, 0x1f, - 0x85, 0x53, 0x72, 0xf1, 0xc5, 0x88, 0x1a, 0x0b, - 0x4f, 0x96, 0x43, 0xe0, 0x91, 0x89, 0xb9, 0xc0, - 0xe8, 0x18, 0xd5, 0x6e, 0x94, 0xe8, 0x35, 0x66, - 0x01, 0x94, 0x80, 0x95, 0x87, 0xe2, 0xc8, 0x19, - 0x73, 0xa3, 0x01, 0x05, 0xc1, 0x64, 0x72, 0xc9, - 0x6b, 0x6e, 0x55, 0x7c, 0x29, 0x67, 0x90, 0x93, - 0x49, 0xeb, 0xe3, 0x85, 0xc2, 0xf5, 0x79, 0x68, - 0x9d, 0x92, 0xc3, 0x32, 0x75, 0x80, 0x66, 0xf2, - 0x43, 0xa7, 0xb0, 0xc3, 0x22, 0x3f, 0x39, 0x8a, - 0x35, 0x5c, 0x63, 0x5c, 0xd1, 0x9e, 0x8a, 0xd2, - 0x78, 0x3c, 0x12, 0x01, 0x25, 0x04, 0x0e, 0x08, - 0x10, 0x88, 0xb6, 0x1b, 0xb7, 0x96, 0x35, 0xa8, - 0x0d, 0x1e, 0xae, 0xac, 0x4a, 0x70, 0xa5, 0x31, - 0xd0, 0x0c, 0x78, 0xbf, 0xdd, 0xc5, 0x24, 0x3e, - 0xcb, 0x0a, 0x0a, 0x69, 0x40, 0xba, 0xb0, 0xc4, - 0x2a, 0x9b, 0x1e, 0x0a, 0x51, 0xa6, 0x16, 0x98, - 0x76 -#elif defined(TEST_ZSTD2) - 0x28, 0xb5, 0x2f, 0xfd, 0x04, 0x58, 0x75, 0x04, - 0x00, 0xb2, 0x4c, 0x20, 0x17, 0xa0, 0x25, 0x69, - 0x03, 0xf0, 0xb2, 0x37, 0xb1, 0x5e, 0xb9, 0x24, - 0x56, 0x5b, 0x52, 0x22, 0x39, 0x01, 0x44, 0x2b, - 0x03, 0x55, 0xe3, 0x47, 0x03, 0x12, 0x9a, 0xe1, - 0xf0, 0x94, 0x0b, 0xe5, 0xe2, 0xba, 0x7e, 0xfe, - 0x9c, 0xc7, 0x61, 0x43, 0xc8, 0xfa, 0xf0, 0x3a, - 0xfa, 0x51, 0xaa, 0x50, 0xa6, 0x2d, 0x9a, 0x78, - 0xce, 0x2f, 0x61, 0x20, 0x6c, 0x7e, 0x35, 0x60, - 0xfb, 0xdd, 0x4c, 0x63, 0xfb, 0x95, 0x35, 0xc0, - 0x82, 0x59, 0xc2, 0xc9, 0x78, 0x6e, 0x30, 0xe6, - 0xd2, 0x72, 0x15, 0x14, 0x18, 0x62, 0x5d, 0xeb, - 0x2d, 0x9d, 0x3e, 0xee, 0x2e, 0x58, 0x58, 0xe9, - 0x40, 0x68, 0xb9, 0x2f, 0x23, 0x99, 0x2a, 0x4d, - 0xe8, 0x49, 0x79, 0x70, 0x1f, 0xf9, 0xe2, 0x34, - 0x2e, 0xab, 0xa5, 0xa3, 0xf2, 0x70, 0x98, 0xd0, - 0xb2, 0xb1, 0x3e, 0x5d, 0x90, 0x20, 0xd9, 0x36, - 0x8b, 0xdb, 0xaa, 0x20, 0x40, 0x03, 0x14, 0x06, - 0x03, 0x16, 0x2a, 0x9d, 0x31, 0xbd, 0x28, 0x3b, - 0x0c, 0xac, 0x41, - 0x28, 0xb5, 0x2f, 0xfd, 0x04, 0x58, 0xbd, 0x04, - 0x00, 0x62, 0xcd, 0x22, 0x19, 0xa0, 0x25, 0x69, - 0x03, 0x60, 0x72, 0xc9, 0x36, 0xda, 0xd2, 0x8b, - 0xfc, 0xbf, 0x25, 0x42, 0xa9, 0x82, 0x38, 0x70, - 0x1a, 0x2e, 0x54, 0x95, 0x33, 0x02, 0x03, 0x51, - 0x36, 0x51, 0x80, 0xcc, 0x7a, 0x6e, 0x52, 0x2e, - 0x75, 0x64, 0x2d, 0x33, 0x2c, 0xd6, 0xdb, 0xfc, - 0x39, 0x31, 0xd5, 0xa8, 0xa2, 0x40, 0xd7, 0x12, - 0x4c, 0xc6, 0x76, 0xdc, 0x1e, 0x0f, 0xf4, 0x4e, - 0x0a, 0xd3, 0x0c, 0x87, 0x67, 0x25, 0x25, 0x52, - 0x66, 0x87, 0x95, 0xc6, 0x69, 0x0c, 0xb4, 0x5e, - 0x1d, 0xe7, 0x5e, 0xcd, 0x47, 0x41, 0x80, 0x89, - 0x5c, 0xa5, 0x4a, 0x32, 0x26, 0xb3, 0x3d, 0x2b, - 0xd5, 0xc0, 0x16, 0xde, 0xfb, 0x65, 0xcd, 0x6a, - 0x0c, 0x3f, 0xe7, 0xd6, 0xb2, 0x17, 0x7c, 0x25, - 0x35, 0x6b, 0x58, 0xf0, 0x95, 0xb5, 0xf2, 0xe4, - 0x4e, 0xf0, 0x34, 0x4f, 0x5f, 0x39, 0xd1, 0x90, - 0xf8, 0xb9, 0x59, 0xbe, 0x2e, 0xf9, 0xd4, 0x02, - 0x98, 0x50, 0x5a, 0xc2, 0xcf, 0xe1, 0x08, 0x02, - 0x00, 0x0f, 0x1e, 0x44, 0x40, 0x79, 0x50, 0x67, - 0x3d, 0xd3, 0x35, 0x8f -#endif -}; - -static const char orig[] = -"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod\n" -"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\n" -"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n" -"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\n" -"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\n" -"proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n"; - -#if defined(TEST_BZIP2) || defined(TEST_BZIP22) -#define COMP_NAME "bzip2" -#define COMP_ID FSTREAM_COMPRESSOR_BZIP2 -#elif defined(TEST_XZ) || defined(TEST_XZ2) -#define COMP_NAME "xz" -#define COMP_ID FSTREAM_COMPRESSOR_XZ -#elif defined(TEST_GZIP) -#define COMP_NAME "gzip" -#define COMP_ID FSTREAM_COMPRESSOR_GZIP -#elif defined(TEST_ZSTD) || defined(TEST_ZSTD2) -#define COMP_NAME "zstd" -#define COMP_ID FSTREAM_COMPRESSOR_ZSTD -#endif - -static void destroy_noop(sqfs_object_t *obj) -{ - (void)obj; -} - -static int precache_noop(istream_t *strm) -{ - (void)strm; - return 0; -} - -static const char *get_filename(istream_t *strm) -{ - (void)strm; - return "memstream"; -} - -static istream_t memstream = { - .base = { - .destroy = destroy_noop, - }, - - .buffer_used = sizeof(data_in) / sizeof(data_in[0]), - .buffer_offset = 0, - .eof = true, - .buffer = data_in, - - .precache = precache_noop, - .get_filename = get_filename, -}; - -int main(int argc, char **argv) -{ - char buffer[2 * (sizeof(orig) / sizeof(orig[0]))]; - const char *name; - istream_t *xfrm; - size_t orig_sz; - int ret; - (void)argc; (void)argv; - - /* XXX: null terminator not included in the compressed blob */ - orig_sz = (sizeof(orig) / sizeof(orig[0])) - 1; - - /* generic API test */ - TEST_ASSERT(fstream_compressor_exists(COMP_ID)); - - name = fstream_compressor_name_from_id(COMP_ID); - TEST_STR_EQUAL(name, COMP_NAME); - - ret = fstream_compressor_id_from_name(name); - TEST_EQUAL_I(ret, COMP_ID); - - ret = istream_detect_compressor(&memstream, NULL); - TEST_EQUAL_I(ret, COMP_ID); - - /* decoder test */ - xfrm = istream_compressor_create(&memstream, COMP_ID); - TEST_NOT_NULL(xfrm); - - name = istream_get_filename(xfrm); - TEST_STR_EQUAL(name, "memstream"); - - ret = istream_read(xfrm, buffer, sizeof(buffer)); - TEST_ASSERT(ret > 0); - TEST_EQUAL_UI((size_t)ret, orig_sz); - - ret = memcmp(buffer, orig, ret); - TEST_EQUAL_I(ret, 0); - - ret = istream_read(xfrm, buffer, sizeof(buffer)); - TEST_EQUAL_I(ret, 0); - - /* cleanup */ - sqfs_destroy(xfrm); - return EXIT_SUCCESS; -} diff --git a/tests/libfstree/Makemodule.am b/tests/libfstree/Makemodule.am index 594ef7e..6b45ece 100644 --- a/tests/libfstree/Makemodule.am +++ b/tests/libfstree/Makemodule.am @@ -28,16 +28,16 @@ test_get_path_LDADD = libfstree.a libcompat.a test_fstree_sort_SOURCES = tests/libfstree/fstree_sort.c tests/test.h test_fstree_sort_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/lib/fstree -test_fstree_sort_LDADD = libfstree.a libfstream.a libcompat.a +test_fstree_sort_LDADD = libfstree.a libio.a libcompat.a test_fstree_from_file_SOURCES = tests/libfstree/fstree_from_file.c tests/test.h test_fstree_from_file_CPPFLAGS = $(AM_CPPFLAGS) test_fstree_from_file_CPPFLAGS += -DTESTPATH=$(FSTDATADIR)/fstree1.txt -test_fstree_from_file_LDADD = libfstree.a libfstream.a libcompat.a +test_fstree_from_file_LDADD = libfstree.a libio.a libcompat.a test_fstree_glob1_SOURCES = tests/libfstree/fstree_glob1.c tests/test.h test_fstree_glob1_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(FSTDATADIR) -test_fstree_glob1_LDADD = libfstree.a libfstream.a libcompat.a +test_fstree_glob1_LDADD = libfstree.a libio.a libcompat.a test_fstree_from_dir_SOURCES = tests/libfstree/fstree_from_dir.c tests/test.h test_fstree_from_dir_CPPFLAGS = $(AM_CPPFLAGS) @@ -46,7 +46,7 @@ test_fstree_from_dir_LDADD = libfstree.a libcompat.a test_fstree_init_SOURCES = tests/libfstree/fstree_init.c tests/test.h test_fstree_init_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/lib/fstree -test_fstree_init_LDADD = libfstree.a libfstream.a libcompat.a +test_fstree_init_LDADD = libfstree.a libio.a libcompat.a test_filename_sane_SOURCES = tests/libfstree/filename_sane.c test_filename_sane_SOURCES += lib/fstree/filename_sane.c @@ -63,10 +63,10 @@ test_fstree_epoch_SOURCES += lib/fstree/source_date_epoch.c test_fstree_epoch_LDADD = libcompat.a test_sort_file_SOURCES = tests/libfstree/sort_file.c -test_sort_file_LDADD = libfstree.a libfstream.a libcompat.a +test_sort_file_LDADD = libfstree.a libio.a libcompat.a fstree_fuzz_SOURCES = tests/libfstree/fstree_fuzz.c -fstree_fuzz_LDADD = libfstree.a libfstream.a libcompat.a +fstree_fuzz_LDADD = libfstree.a libio.a libcompat.a FSTREE_TESTS = \ test_canonicalize_name test_mknode_simple test_mknode_slink \ diff --git a/tests/libio/Makemodule.am b/tests/libio/Makemodule.am new file mode 100644 index 0000000..86f2e3a --- /dev/null +++ b/tests/libio/Makemodule.am @@ -0,0 +1,68 @@ +test_get_line_SOURCES = tests/libio/get_line.c tests/test.h +test_get_line_LDADD = libio.a libcompat.a +test_get_line_CPPFLAGS = $(AM_CPPFLAGS) +test_get_line_CPPFLAGS += -DTESTFILE=$(top_srcdir)/tests/libio/get_line.txt + +test_xfrm_bzip2_SOURCES = tests/libio/uncompress.c tests/test.h +test_xfrm_bzip2_LDADD = libio.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) +test_xfrm_bzip2_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) +test_xfrm_bzip2_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_BZIP2=1 + +test_xfrm_bzip22_SOURCES = tests/libio/uncompress.c tests/test.h +test_xfrm_bzip22_LDADD = libio.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) +test_xfrm_bzip22_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) +test_xfrm_bzip22_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_BZIP22=1 + +test_xfrm_xz_SOURCES = tests/libio/uncompress.c tests/test.h +test_xfrm_xz_LDADD = libio.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) +test_xfrm_xz_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) +test_xfrm_xz_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_XZ=1 + +test_xfrm_xz2_SOURCES = tests/libio/uncompress.c tests/test.h +test_xfrm_xz2_LDADD = libio.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) +test_xfrm_xz2_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) +test_xfrm_xz2_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_XZ2=1 + +test_xfrm_gzip_SOURCES = tests/libio/uncompress.c tests/test.h +test_xfrm_gzip_LDADD = libio.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) +test_xfrm_gzip_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) +test_xfrm_gzip_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_GZIP=1 + +test_xfrm_zstd_SOURCES = tests/libio/uncompress.c tests/test.h +test_xfrm_zstd_LDADD = libio.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) +test_xfrm_zstd_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) +test_xfrm_zstd_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_ZSTD=1 + +test_xfrm_zstd2_SOURCES = tests/libio/uncompress.c tests/test.h +test_xfrm_zstd2_LDADD = libio.a libcompat.a $(BZIP2_LIBS) $(ZLIB_LIBS) +test_xfrm_zstd2_LDADD += $(XZ_LIBS) $(ZSTD_LIBS) +test_xfrm_zstd2_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_ZSTD2=1 + +if BUILD_TOOLS +check_PROGRAMS += test_get_line +TESTS += test_get_line + +if WITH_BZIP2 +check_PROGRAMS += test_xfrm_bzip2 test_xfrm_bzip22 +TESTS += test_xfrm_bzip2 test_xfrm_bzip22 +endif + +if WITH_XZ +check_PROGRAMS += test_xfrm_xz test_xfrm_xz2 +TESTS += test_xfrm_xz test_xfrm_xz2 +endif + +if WITH_GZIP +check_PROGRAMS += test_xfrm_gzip +TESTS += test_xfrm_gzip +endif + +if WITH_ZSTD +if HAVE_ZSTD_STREAM +check_PROGRAMS += test_xfrm_zstd test_xfrm_zstd2 +TESTS += test_xfrm_zstd test_xfrm_zstd2 +endif +endif +endif + +EXTRA_DIST += $(top_srcdir)/tests/libio/get_line.txt diff --git a/tests/libio/get_line.c b/tests/libio/get_line.c new file mode 100644 index 0000000..66fced5 --- /dev/null +++ b/tests/libio/get_line.c @@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * get_line.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "config.h" + +#include "io/file.h" +#include "../test.h" + +typedef struct { + size_t line_num; + const char *str; +} line_t; + +static void run_test_case(const line_t *lines, size_t count, + int flags) +{ + size_t i, line_num, old_line_num; + istream_t *fp; + char *line; + int ret; + + fp = istream_open_file(STRVALUE(TESTFILE)); + TEST_NOT_NULL(fp); + + line_num = 1; + line = NULL; + + for (i = 0; i < count; ++i) { + old_line_num = line_num; + ret = istream_get_line(fp, &line, &line_num, flags); + + TEST_ASSERT(line_num >= old_line_num); + TEST_EQUAL_I(ret, 0); + TEST_NOT_NULL(line); + + TEST_EQUAL_UI(line_num, lines[i].line_num); + TEST_STR_EQUAL(line, lines[i].str); + + free(line); + line = NULL; + line_num += 1; + } + + ret = istream_get_line(fp, &line, &line_num, flags); + TEST_ASSERT(ret > 0); + + sqfs_destroy(fp); +} + +static const line_t lines_raw[] = { + { 1, "" }, + { 2, "The quick" }, + { 3, " " }, + { 4, " brown fox " }, + { 5, "" }, + { 6, "jumps over" }, + { 7, "the" }, + { 8, "lazy" }, + { 9, "" }, + { 10, "dog" }, + { 11, "" }, +}; + +static const line_t lines_ltrim[] = { + { 1, "" }, + { 2, "The quick" }, + { 3, "" }, + { 4, "brown fox " }, + { 5, "" }, + { 6, "jumps over" }, + { 7, "the" }, + { 8, "lazy" }, + { 9, "" }, + { 10, "dog" }, + { 11, "" }, +}; + +static const line_t lines_rtrim[] = { + { 1, "" }, + { 2, "The quick" }, + { 3, "" }, + { 4, " brown fox" }, + { 5, "" }, + { 6, "jumps over" }, + { 7, "the" }, + { 8, "lazy" }, + { 9, "" }, + { 10, "dog" }, + { 11, "" }, +}; + +static const line_t lines_trim[] = { + { 1, "" }, + { 2, "The quick" }, + { 3, "" }, + { 4, "brown fox" }, + { 5, "" }, + { 6, "jumps over" }, + { 7, "the" }, + { 8, "lazy" }, + { 9, "" }, + { 10, "dog" }, + { 11, "" }, +}; + +static const line_t lines_no_empty[] = { + { 2, "The quick" }, + { 3, " " }, + { 4, " brown fox " }, + { 6, "jumps over" }, + { 7, "the" }, + { 8, "lazy" }, + { 10, "dog" }, +}; + +static const line_t lines_no_empty_ltrim[] = { + { 2, "The quick" }, + { 4, "brown fox " }, + { 6, "jumps over" }, + { 7, "the" }, + { 8, "lazy" }, + { 10, "dog" }, +}; + +static const line_t lines_no_empty_rtrim[] = { + { 2, "The quick" }, + { 4, " brown fox" }, + { 6, "jumps over" }, + { 7, "the" }, + { 8, "lazy" }, + { 10, "dog" }, +}; + +static const line_t lines_no_empty_trim[] = { + { 2, "The quick" }, + { 4, "brown fox" }, + { 6, "jumps over" }, + { 7, "the" }, + { 8, "lazy" }, + { 10, "dog" }, +}; + +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + + run_test_case(lines_raw, 11, 0); + run_test_case(lines_ltrim, 11, ISTREAM_LINE_LTRIM); + run_test_case(lines_rtrim, 11, ISTREAM_LINE_RTRIM); + run_test_case(lines_trim, 11, + ISTREAM_LINE_LTRIM | ISTREAM_LINE_RTRIM); + + run_test_case(lines_no_empty, 7, ISTREAM_LINE_SKIP_EMPTY); + run_test_case(lines_no_empty_ltrim, 6, + ISTREAM_LINE_SKIP_EMPTY | ISTREAM_LINE_LTRIM); + run_test_case(lines_no_empty_rtrim, 6, + ISTREAM_LINE_SKIP_EMPTY | ISTREAM_LINE_RTRIM); + run_test_case(lines_no_empty_trim, 6, + ISTREAM_LINE_SKIP_EMPTY | ISTREAM_LINE_LTRIM | + ISTREAM_LINE_RTRIM); + + return EXIT_SUCCESS; +} diff --git a/tests/libio/get_line.txt b/tests/libio/get_line.txt new file mode 100644 index 0000000..a1994f0 --- /dev/null +++ b/tests/libio/get_line.txt @@ -0,0 +1,11 @@ + +The quick + + brown fox + +jumps over +the +lazy + +dog + diff --git a/tests/libio/uncompress.c b/tests/libio/uncompress.c new file mode 100644 index 0000000..9476877 --- /dev/null +++ b/tests/libio/uncompress.c @@ -0,0 +1,432 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * uncompress.c + * + * Copyright (C) 2021 David Oberhollenzer + */ +#include "io/istream.h" +#include "io/xfrm.h" +#include "../test.h" + +static sqfs_u8 data_in[] = { +#if defined(TEST_BZIP2) + 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, + 0x53, 0x59, 0x05, 0x24, 0x28, 0x04, 0x00, 0x00, + 0x27, 0xd7, 0x80, 0x00, 0x10, 0x40, 0x05, 0x06, + 0x04, 0x02, 0x00, 0x3f, 0xe7, 0xff, 0x40, 0x30, + 0x01, 0x2d, 0x23, 0x62, 0x26, 0x05, 0x3d, 0x03, + 0x54, 0xfd, 0x53, 0x4c, 0x86, 0x9e, 0x90, 0x6a, + 0x9e, 0x9e, 0x85, 0x3c, 0xa0, 0x00, 0x00, 0x1a, + 0x9e, 0x41, 0x13, 0x13, 0x28, 0x69, 0x03, 0xd4, + 0x0f, 0x1c, 0x70, 0xd0, 0xb4, 0xe3, 0xe4, 0x75, + 0x4e, 0x8b, 0x67, 0x43, 0x7b, 0x38, 0x27, 0x77, + 0xe4, 0xc1, 0x98, 0x3a, 0x2d, 0x3a, 0xe4, 0x44, + 0x98, 0xdc, 0x49, 0x8b, 0x22, 0x48, 0xfc, 0xc8, + 0xe7, 0x57, 0x05, 0x3c, 0x5a, 0xee, 0x5a, 0x84, + 0xcd, 0x7c, 0x8f, 0x26, 0x6b, 0x6e, 0xf7, 0xb5, + 0x49, 0x1f, 0x79, 0x42, 0x5d, 0x09, 0x8c, 0xc6, + 0xde, 0x0c, 0x0d, 0xb1, 0x46, 0xb4, 0xee, 0xd9, + 0x8f, 0x33, 0x37, 0x04, 0xa9, 0x05, 0x49, 0xe3, + 0x04, 0x16, 0x62, 0x36, 0x3a, 0x01, 0xda, 0xd4, + 0xc8, 0x8a, 0x32, 0x02, 0x1f, 0x62, 0x4b, 0xa4, + 0x49, 0x59, 0xda, 0x50, 0x85, 0x69, 0x35, 0x21, + 0x10, 0xc6, 0x8a, 0x3c, 0x44, 0x95, 0xb0, 0xbc, + 0xc5, 0x6b, 0xea, 0xfb, 0x40, 0xbd, 0x14, 0x01, + 0x6a, 0xfa, 0xcd, 0x67, 0xd8, 0x2d, 0x93, 0x8b, + 0xda, 0x44, 0x1b, 0xe9, 0x5a, 0x87, 0x60, 0xb0, + 0xe0, 0x73, 0xd1, 0x01, 0x3a, 0x66, 0x05, 0xcc, + 0x34, 0xa0, 0x63, 0x8d, 0x35, 0x5e, 0xa0, 0x9f, + 0x05, 0x89, 0x15, 0x51, 0x48, 0x16, 0x0c, 0x61, + 0xf4, 0x30, 0xb8, 0x07, 0x29, 0xc0, 0xf5, 0x1a, + 0xe1, 0x0d, 0x6c, 0xfe, 0x91, 0xda, 0x13, 0x2f, + 0x8e, 0x5b, 0x1c, 0xfc, 0xb3, 0xb2, 0x30, 0x9d, + 0xf6, 0x09, 0x30, 0x55, 0x30, 0x67, 0xc2, 0x87, + 0xe9, 0x9a, 0xd4, 0x1d, 0x66, 0x11, 0x54, 0x89, + 0x21, 0xe1, 0x55, 0x84, 0xbf, 0xa6, 0x11, 0xa4, + 0xb8, 0x40, 0xed, 0x42, 0x20, 0xb9, 0xb7, 0x26, + 0x31, 0x14, 0x4f, 0x86, 0xdc, 0x50, 0x34, 0x38, + 0x8b, 0x57, 0x77, 0x21, 0xf6, 0x89, 0xbd, 0xc5, + 0x65, 0xc3, 0x23, 0x45, 0xec, 0x7f, 0x8b, 0xb9, + 0x22, 0x9c, 0x28, 0x48, 0x02, 0x92, 0x14, 0x02, + 0x00, +#elif defined(TEST_BZIP22) + 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, + 0x53, 0x59, 0x5d, 0x09, 0x24, 0x1d, 0x00, 0x00, + 0x13, 0xd7, 0x80, 0x00, 0x10, 0x40, 0x05, 0x00, + 0x04, 0x02, 0x00, 0x3e, 0xa7, 0xff, 0x40, 0x30, + 0x00, 0xac, 0x43, 0x54, 0xf5, 0x36, 0x4c, 0xa7, + 0xa8, 0xd3, 0x6a, 0x60, 0x81, 0x40, 0x00, 0xd0, + 0x32, 0x64, 0x0d, 0x53, 0xda, 0x02, 0x09, 0xa2, + 0x68, 0x34, 0xd1, 0x27, 0x4a, 0xdd, 0xf2, 0x0a, + 0x73, 0x43, 0xf9, 0xa2, 0x51, 0x85, 0x76, 0x45, + 0x9a, 0x68, 0x3a, 0xe7, 0x0d, 0xc0, 0x21, 0x4a, + 0xc4, 0xf9, 0xf7, 0x40, 0xc3, 0x10, 0xb2, 0x9b, + 0x58, 0x56, 0x71, 0x50, 0x2f, 0xa4, 0xc5, 0x61, + 0x19, 0xf6, 0x59, 0x06, 0x82, 0x03, 0x7f, 0xeb, + 0xd2, 0x61, 0x88, 0xcd, 0xe8, 0xf7, 0xe8, 0x87, + 0x59, 0x9d, 0xe1, 0xf8, 0x19, 0x6e, 0xad, 0x77, + 0xbf, 0x34, 0x17, 0x21, 0x6b, 0x91, 0xc9, 0x52, + 0xd0, 0x81, 0x1e, 0xb5, 0x0b, 0xee, 0x42, 0x84, + 0x80, 0xd5, 0xa1, 0x8a, 0x04, 0x18, 0x4d, 0xf3, + 0xda, 0x7e, 0x3c, 0x40, 0xa4, 0xdb, 0xe5, 0xf0, + 0x37, 0x40, 0x3a, 0x7d, 0xa7, 0x45, 0x21, 0xf2, + 0x5a, 0x7b, 0x59, 0x56, 0x16, 0xd5, 0xac, 0x9f, + 0x60, 0x85, 0x0e, 0xf5, 0x73, 0xd9, 0x47, 0xe2, + 0xee, 0x48, 0xa7, 0x0a, 0x12, 0x0b, 0xa1, 0x24, + 0x83, 0xa0, + 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, + 0x53, 0x59, 0x2c, 0x24, 0x39, 0xa0, 0x00, 0x00, + 0x1f, 0x55, 0x80, 0x00, 0x10, 0x40, 0x05, 0x06, + 0x00, 0x3f, 0xe7, 0xff, 0x40, 0x30, 0x00, 0xb5, + 0x91, 0x13, 0x4f, 0x54, 0x7a, 0x6a, 0x6d, 0x4d, + 0xa2, 0x68, 0x0c, 0x84, 0x53, 0xf5, 0x30, 0x89, + 0xa3, 0xd4, 0x0d, 0x0f, 0x49, 0xa0, 0xd4, 0xf4, + 0xd1, 0x53, 0xf4, 0x93, 0x69, 0x3c, 0x81, 0x1a, + 0x65, 0x53, 0x90, 0x51, 0x07, 0x2a, 0xad, 0x8f, + 0x63, 0xba, 0x25, 0xc2, 0x0c, 0x8b, 0xb9, 0x95, + 0x15, 0xd8, 0xda, 0x61, 0x5c, 0xa9, 0xe4, 0x0b, + 0x21, 0xc9, 0x97, 0x57, 0x01, 0x28, 0x9b, 0xfb, + 0x94, 0xb9, 0x48, 0xa3, 0x0a, 0xc6, 0x1c, 0x54, + 0x98, 0x9a, 0x39, 0xc3, 0x87, 0x90, 0x33, 0x58, + 0x2d, 0x3e, 0x16, 0xb1, 0xae, 0x26, 0x89, 0x75, + 0xf5, 0x77, 0xa5, 0x8e, 0x5b, 0x8c, 0x8a, 0x39, + 0xbd, 0x75, 0x21, 0x9d, 0x99, 0x18, 0x4a, 0x91, + 0xab, 0xbc, 0x08, 0x87, 0xa4, 0xf1, 0x81, 0xb5, + 0xb4, 0xb0, 0xfe, 0x6b, 0x9f, 0xbe, 0x19, 0x82, + 0xd1, 0x50, 0xe1, 0x5e, 0x13, 0xb5, 0xc6, 0x2c, + 0xa4, 0x82, 0xf2, 0x5c, 0xc3, 0x20, 0x41, 0x13, + 0x56, 0x63, 0x3d, 0xec, 0x71, 0x2a, 0xbf, 0x2c, + 0x60, 0x2f, 0x7a, 0x4d, 0xcb, 0x3f, 0x8b, 0xb9, + 0x22, 0x9c, 0x28, 0x48, 0x16, 0x12, 0x1c, 0xd0, + 0x00, +#elif defined(TEST_XZ) + 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x00, + 0xff, 0x12, 0xd9, 0x41, 0x02, 0x00, 0x21, 0x01, + 0x1c, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x58, 0xcc, + 0xe0, 0x01, 0xbd, 0x01, 0x43, 0x5d, 0x00, 0x26, + 0x1b, 0xca, 0x46, 0x67, 0x5a, 0xf2, 0x77, 0xb8, + 0x7d, 0x86, 0xd8, 0x41, 0xdb, 0x05, 0x35, 0xcd, + 0x83, 0xa5, 0x7c, 0x12, 0xa5, 0x05, 0xdb, 0x90, + 0xbd, 0x2f, 0x14, 0xd3, 0x71, 0x72, 0x96, 0xa8, + 0x8a, 0x7d, 0x84, 0x56, 0x71, 0x8d, 0x6a, 0x22, + 0x98, 0xab, 0x9e, 0x3d, 0xc3, 0x55, 0xef, 0xcc, + 0xa5, 0xc3, 0xdd, 0x5b, 0x8e, 0xbf, 0x03, 0x81, + 0x21, 0x40, 0xd6, 0x26, 0x91, 0x02, 0x45, 0x4e, + 0x20, 0x91, 0xcf, 0x8c, 0x51, 0x22, 0x02, 0x70, + 0xba, 0x05, 0x6b, 0x83, 0xef, 0x3f, 0x8e, 0x09, + 0xef, 0x88, 0xf5, 0x37, 0x1b, 0x89, 0x8d, 0xff, + 0x1e, 0xee, 0xe8, 0xb0, 0xac, 0xf2, 0x6e, 0xd4, + 0x3e, 0x25, 0xaf, 0xa0, 0x6d, 0x2e, 0xc0, 0x7f, + 0xb5, 0xa0, 0xcb, 0x90, 0x1f, 0x08, 0x1a, 0xe2, + 0x90, 0x20, 0x19, 0x71, 0x0c, 0xe8, 0x3f, 0xe5, + 0x39, 0xeb, 0x9a, 0x62, 0x4f, 0x06, 0xda, 0x3c, + 0x32, 0x59, 0xcc, 0x83, 0xe3, 0x83, 0x0f, 0x38, + 0x7d, 0x43, 0x37, 0x6c, 0x0b, 0x05, 0x65, 0x98, + 0x25, 0xdb, 0xf2, 0xc0, 0x2d, 0x39, 0x36, 0x5d, + 0xd4, 0xb6, 0xc2, 0x79, 0x73, 0x3e, 0xc2, 0x6e, + 0x54, 0xec, 0x78, 0x2b, 0x5d, 0xf1, 0xd1, 0xb4, + 0xb3, 0xcd, 0xf3, 0x89, 0xf5, 0x81, 0x3e, 0x2c, + 0x65, 0xd6, 0x73, 0xd3, 0x1b, 0x20, 0x68, 0x0c, + 0x93, 0xd4, 0xfc, 0x9f, 0xf8, 0xa7, 0xd4, 0xfa, + 0x3a, 0xb1, 0x13, 0x93, 0x4b, 0xec, 0x78, 0x7d, + 0x5c, 0x81, 0x80, 0xe5, 0x14, 0x78, 0xfe, 0x7e, + 0xde, 0xf7, 0xad, 0x9e, 0x84, 0xba, 0xf1, 0x00, + 0xe9, 0xbd, 0x2c, 0xf4, 0x70, 0x7d, 0xbe, 0x29, + 0xb9, 0xf0, 0x10, 0xb9, 0x01, 0xf1, 0x76, 0x8a, + 0x5a, 0xad, 0x02, 0xa1, 0x32, 0xc8, 0x53, 0x59, + 0x11, 0x4c, 0xe2, 0x98, 0x34, 0xd9, 0x23, 0x51, + 0x4a, 0x40, 0x2b, 0x87, 0x41, 0xdd, 0x50, 0xcd, + 0x98, 0x1e, 0x29, 0x86, 0x23, 0x93, 0x3e, 0x9b, + 0x6b, 0x16, 0xa1, 0x40, 0xac, 0xe7, 0x40, 0xfe, + 0xa9, 0x87, 0x48, 0x25, 0x52, 0x02, 0x8b, 0xc4, + 0x68, 0x08, 0x5a, 0x62, 0xc1, 0xb2, 0x07, 0x3b, + 0x26, 0x1e, 0x59, 0x5c, 0x47, 0x24, 0xae, 0x8e, + 0xe5, 0xf7, 0xe6, 0x4b, 0x13, 0xb4, 0x6d, 0x46, + 0x65, 0x4f, 0xd0, 0x48, 0xcc, 0x51, 0x4b, 0x80, + 0xcb, 0xf1, 0xd4, 0x6c, 0x45, 0x98, 0x92, 0x47, + 0xeb, 0x60, 0x00, 0x00, 0x00, 0x01, 0xd7, 0x02, + 0xbe, 0x03, 0x00, 0x00, 0xda, 0x2c, 0x45, 0x49, + 0xa8, 0x00, 0x0a, 0xfc, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x59, 0x5a +#elif defined(TEST_XZ2) + 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x04, + 0xe6, 0xd6, 0xb4, 0x46, 0x02, 0x00, 0x21, 0x01, + 0x16, 0x00, 0x00, 0x00, 0x74, 0x2f, 0xe5, 0xa3, + 0xe0, 0x00, 0xdc, 0x00, 0xb3, 0x5d, 0x00, 0x26, + 0x1b, 0xca, 0x46, 0x67, 0x5a, 0xf2, 0x77, 0xb8, + 0x7d, 0x86, 0xd8, 0x41, 0xdb, 0x05, 0x35, 0xcd, + 0x83, 0xa5, 0x7c, 0x12, 0xa5, 0x05, 0xdb, 0x90, + 0xbd, 0x2f, 0x14, 0xd3, 0x71, 0x72, 0x96, 0xa8, + 0x8a, 0x7d, 0x84, 0x56, 0x71, 0x8d, 0x6a, 0x22, + 0x98, 0xab, 0x9e, 0x3d, 0xc3, 0x55, 0xef, 0xcc, + 0xa5, 0xc3, 0xdd, 0x5b, 0x8e, 0xbf, 0x03, 0x81, + 0x21, 0x40, 0xd6, 0x26, 0x91, 0x02, 0x45, 0x4e, + 0x20, 0x91, 0xcf, 0x8c, 0x51, 0x22, 0x02, 0x70, + 0xba, 0x05, 0x6b, 0x83, 0xef, 0x3f, 0x8e, 0x09, + 0xef, 0x88, 0xf5, 0x37, 0x1b, 0x89, 0x8d, 0xff, + 0x1e, 0xee, 0xe8, 0xb0, 0xac, 0xf2, 0x6e, 0xd4, + 0x3e, 0x25, 0xaf, 0xa0, 0x6d, 0x2e, 0xc0, 0x7f, + 0xb5, 0xa0, 0xcb, 0x90, 0x1f, 0x08, 0x1a, 0xe2, + 0x90, 0x20, 0x19, 0x71, 0x0c, 0xe8, 0x3f, 0xe5, + 0x39, 0xeb, 0x9a, 0x62, 0x4f, 0x06, 0xda, 0x3c, + 0x32, 0x59, 0xcc, 0x83, 0xe3, 0x83, 0x0f, 0x38, + 0x7d, 0x43, 0x37, 0x6c, 0x0b, 0x05, 0x65, 0x98, + 0x25, 0xdb, 0xf2, 0xc0, 0x2d, 0x39, 0x36, 0x5d, + 0xd4, 0xb6, 0xc2, 0x79, 0x73, 0x3e, 0xc2, 0x6e, + 0x54, 0xec, 0x78, 0x2b, 0x5d, 0xf1, 0xd1, 0xb4, + 0xb3, 0xcd, 0xf3, 0x89, 0xf5, 0x80, 0x79, 0x46, + 0xc0, 0x00, 0x00, 0x00, 0xc4, 0xf5, 0x1d, 0x08, + 0xf0, 0x34, 0x3a, 0x59, 0x00, 0x01, 0xcf, 0x01, + 0xdd, 0x01, 0x00, 0x00, 0x7f, 0x5a, 0x77, 0xcb, + 0xb1, 0xc4, 0x67, 0xfb, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x59, 0x5a, + 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x04, + 0xe6, 0xd6, 0xb4, 0x46, 0x02, 0x00, 0x21, 0x01, + 0x16, 0x00, 0x00, 0x00, 0x74, 0x2f, 0xe5, 0xa3, + 0xe0, 0x00, 0xe0, 0x00, 0xb7, 0x5d, 0x00, 0x31, + 0x9b, 0xca, 0x19, 0xc5, 0x54, 0xec, 0xb6, 0x54, + 0xe7, 0xb1, 0x7d, 0xc4, 0x57, 0x9e, 0x6c, 0x89, + 0xad, 0x4a, 0x6d, 0x16, 0xd8, 0x3c, 0x05, 0x94, + 0x10, 0x16, 0x99, 0x38, 0x21, 0xa3, 0xb9, 0xc5, + 0x80, 0xff, 0xfc, 0xee, 0xd4, 0xd5, 0x3f, 0xdd, + 0x8c, 0xd7, 0x3d, 0x8f, 0x76, 0xec, 0x96, 0x9d, + 0x20, 0xac, 0xcb, 0x18, 0xf5, 0xb2, 0x9c, 0x12, + 0xf6, 0x7c, 0x33, 0xdc, 0x4f, 0x9a, 0xe5, 0x2d, + 0x63, 0x68, 0xa4, 0x2b, 0x1d, 0x0a, 0x1e, 0xf0, + 0xfe, 0x73, 0xf2, 0x5f, 0x7b, 0xb4, 0xea, 0x54, + 0xad, 0x27, 0xd1, 0xff, 0xb6, 0x50, 0x06, 0x7b, + 0x51, 0x3f, 0x25, 0x8a, 0xcf, 0x4c, 0x03, 0x3e, + 0xc3, 0xad, 0x47, 0x34, 0xcf, 0xba, 0x45, 0x79, + 0xd0, 0x7b, 0xf6, 0x66, 0x63, 0xc0, 0xc6, 0x69, + 0xa7, 0x51, 0x84, 0xa8, 0xa0, 0x0b, 0xbc, 0x6f, + 0x13, 0x89, 0xd6, 0x5e, 0xac, 0xca, 0x2f, 0xd2, + 0xe7, 0xe1, 0x1e, 0x78, 0x22, 0x3a, 0x59, 0x6c, + 0x9c, 0x8c, 0x65, 0xf1, 0x5b, 0xf4, 0xbf, 0xd5, + 0xdc, 0x05, 0xeb, 0x70, 0x10, 0xb8, 0x6c, 0xf2, + 0x13, 0x20, 0xb0, 0xdd, 0x3e, 0xb2, 0x92, 0x5b, + 0xa3, 0xf7, 0x94, 0xa1, 0xa1, 0x74, 0x36, 0x9a, + 0xf1, 0xd8, 0xc2, 0xf0, 0xc6, 0x29, 0x7e, 0x85, + 0x28, 0xf5, 0xf2, 0x21, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x80, 0x67, 0x40, 0xc3, 0xaa, 0x17, 0x57, + 0x00, 0x01, 0xd3, 0x01, 0xe1, 0x01, 0x00, 0x00, + 0x86, 0xdf, 0x9e, 0x05, 0xb1, 0xc4, 0x67, 0xfb, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5a +#elif defined(TEST_GZIP) + 0x1f, 0x8b, 0x08, 0x08, 0x82, 0xd4, 0x97, 0x60, + 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, + 0x78, 0x74, 0x00, 0x35, 0x90, 0xc1, 0x71, 0x43, + 0x31, 0x08, 0x44, 0xef, 0xbf, 0x8a, 0x2d, 0x20, + 0xf3, 0xab, 0x48, 0x6e, 0xb9, 0xa6, 0x00, 0x82, + 0xb0, 0xc3, 0x8c, 0x24, 0x64, 0x09, 0x3c, 0x2e, + 0x3f, 0xc8, 0x4e, 0x6e, 0x42, 0xc0, 0xb2, 0xfb, + 0x3e, 0x6d, 0x4a, 0x83, 0x8e, 0x15, 0x0d, 0xc5, + 0xaa, 0x4d, 0x2c, 0x75, 0x50, 0x13, 0x7f, 0x03, + 0x5b, 0x5f, 0xc2, 0x2e, 0x1e, 0x13, 0x54, 0x74, + 0xe8, 0x62, 0xed, 0x57, 0x48, 0xd5, 0x6c, 0x2e, + 0x29, 0xb9, 0x00, 0xd1, 0x58, 0xcd, 0xca, 0xe1, + 0xd2, 0x46, 0x2e, 0x6b, 0x67, 0x2d, 0x5a, 0xa2, + 0x3b, 0xc2, 0x51, 0xe9, 0x3b, 0xe5, 0x21, 0xfe, + 0x92, 0x16, 0x34, 0xba, 0x76, 0x02, 0x55, 0xbd, + 0x05, 0x9d, 0xf8, 0x72, 0x48, 0xd7, 0x96, 0xda, + 0x68, 0xba, 0x1f, 0xf7, 0x2c, 0xa9, 0xbd, 0x1d, + 0xb7, 0xd0, 0x85, 0x6e, 0xcb, 0x67, 0x14, 0xc8, + 0x43, 0x26, 0xab, 0x93, 0xab, 0x75, 0x44, 0xad, + 0xd4, 0xd8, 0x5e, 0xca, 0x7b, 0x48, 0x97, 0xee, + 0x4b, 0x4f, 0x49, 0x1d, 0x39, 0x0c, 0xa1, 0x34, + 0xde, 0xd2, 0x93, 0x1d, 0xcf, 0x00, 0x79, 0xca, + 0x4f, 0xbc, 0x6f, 0x49, 0x0a, 0x17, 0xe8, 0x8c, + 0x74, 0xf2, 0xca, 0xaa, 0x1d, 0x53, 0xc6, 0x94, + 0x1f, 0xe9, 0x45, 0x66, 0x06, 0xcf, 0x8f, 0xbb, + 0xd5, 0x18, 0x79, 0x4e, 0xd2, 0x4e, 0x26, 0x85, + 0xac, 0x25, 0x07, 0x6b, 0xad, 0xff, 0x84, 0x32, + 0x50, 0xe0, 0x12, 0x57, 0x25, 0x47, 0xdf, 0x86, + 0x30, 0x68, 0x66, 0x11, 0xf3, 0xc4, 0xc7, 0x83, + 0x65, 0xb8, 0xc4, 0xc6, 0x98, 0x0c, 0x8c, 0x99, + 0x84, 0x73, 0x8e, 0x63, 0x68, 0x21, 0xdf, 0x1b, + 0xd6, 0x8f, 0x31, 0x4d, 0x8b, 0xf4, 0x4d, 0x71, + 0x93, 0xca, 0xa3, 0x1c, 0x75, 0x10, 0x32, 0x02, + 0xec, 0x72, 0x51, 0x56, 0x42, 0x91, 0x25, 0x73, + 0x77, 0x9b, 0xd5, 0x6d, 0x83, 0x36, 0x20, 0x4d, + 0x1c, 0xeb, 0x8f, 0x6b, 0xb4, 0xf3, 0xf8, 0x05, + 0x6b, 0x8b, 0x8b, 0x20, 0xbe, 0x01, 0x00, 0x00 +#elif defined(TEST_ZSTD) + 0x28, 0xb5, 0x2f, 0xfd, 0x04, 0x88, 0xa5, 0x08, + 0x00, 0x46, 0x97, 0x3a, 0x1a, 0x80, 0x37, 0xcd, + 0x01, 0xc0, 0x8a, 0xec, 0xfe, 0x2d, 0xf2, 0xb9, + 0x44, 0x6b, 0xb9, 0x24, 0x77, 0x56, 0x5a, 0x33, + 0x17, 0x0b, 0x67, 0x83, 0x2e, 0x47, 0x07, 0x31, + 0x00, 0x32, 0x00, 0x33, 0x00, 0xc5, 0x2c, 0x5a, + 0x92, 0x93, 0x0f, 0x7b, 0xd1, 0x1d, 0x63, 0x2c, + 0xc8, 0x99, 0x94, 0x77, 0x8f, 0x94, 0x38, 0x75, + 0x80, 0x2f, 0xae, 0xc1, 0x3e, 0xd2, 0xcf, 0x49, + 0x15, 0x25, 0x1a, 0x87, 0x93, 0xdd, 0xe8, 0x00, + 0x6d, 0xaa, 0xf8, 0x54, 0x74, 0xe5, 0x48, 0x4d, + 0xa6, 0xf3, 0x1a, 0xa3, 0x13, 0x08, 0xe5, 0x26, + 0xdc, 0x73, 0xcc, 0x3e, 0xfd, 0x86, 0xa9, 0x52, + 0xb2, 0x76, 0xc7, 0xc2, 0x0f, 0xe4, 0x84, 0x4b, + 0x12, 0x61, 0x3a, 0x6b, 0x7a, 0x1e, 0x8a, 0x81, + 0xa9, 0x9b, 0x11, 0x37, 0x25, 0x55, 0x73, 0x73, + 0x71, 0xa0, 0x84, 0xca, 0xc3, 0x4b, 0xb5, 0xcc, + 0x50, 0xa6, 0x46, 0xd7, 0xe8, 0x08, 0xaa, 0x04, + 0x28, 0xb1, 0x8e, 0xea, 0xb4, 0x4a, 0x49, 0x2b, + 0xd6, 0x0d, 0x59, 0x68, 0xda, 0x64, 0x29, 0x1f, + 0x85, 0x53, 0x72, 0xf1, 0xc5, 0x88, 0x1a, 0x0b, + 0x4f, 0x96, 0x43, 0xe0, 0x91, 0x89, 0xb9, 0xc0, + 0xe8, 0x18, 0xd5, 0x6e, 0x94, 0xe8, 0x35, 0x66, + 0x01, 0x94, 0x80, 0x95, 0x87, 0xe2, 0xc8, 0x19, + 0x73, 0xa3, 0x01, 0x05, 0xc1, 0x64, 0x72, 0xc9, + 0x6b, 0x6e, 0x55, 0x7c, 0x29, 0x67, 0x90, 0x93, + 0x49, 0xeb, 0xe3, 0x85, 0xc2, 0xf5, 0x79, 0x68, + 0x9d, 0x92, 0xc3, 0x32, 0x75, 0x80, 0x66, 0xf2, + 0x43, 0xa7, 0xb0, 0xc3, 0x22, 0x3f, 0x39, 0x8a, + 0x35, 0x5c, 0x63, 0x5c, 0xd1, 0x9e, 0x8a, 0xd2, + 0x78, 0x3c, 0x12, 0x01, 0x25, 0x04, 0x0e, 0x08, + 0x10, 0x88, 0xb6, 0x1b, 0xb7, 0x96, 0x35, 0xa8, + 0x0d, 0x1e, 0xae, 0xac, 0x4a, 0x70, 0xa5, 0x31, + 0xd0, 0x0c, 0x78, 0xbf, 0xdd, 0xc5, 0x24, 0x3e, + 0xcb, 0x0a, 0x0a, 0x69, 0x40, 0xba, 0xb0, 0xc4, + 0x2a, 0x9b, 0x1e, 0x0a, 0x51, 0xa6, 0x16, 0x98, + 0x76 +#elif defined(TEST_ZSTD2) + 0x28, 0xb5, 0x2f, 0xfd, 0x04, 0x58, 0x75, 0x04, + 0x00, 0xb2, 0x4c, 0x20, 0x17, 0xa0, 0x25, 0x69, + 0x03, 0xf0, 0xb2, 0x37, 0xb1, 0x5e, 0xb9, 0x24, + 0x56, 0x5b, 0x52, 0x22, 0x39, 0x01, 0x44, 0x2b, + 0x03, 0x55, 0xe3, 0x47, 0x03, 0x12, 0x9a, 0xe1, + 0xf0, 0x94, 0x0b, 0xe5, 0xe2, 0xba, 0x7e, 0xfe, + 0x9c, 0xc7, 0x61, 0x43, 0xc8, 0xfa, 0xf0, 0x3a, + 0xfa, 0x51, 0xaa, 0x50, 0xa6, 0x2d, 0x9a, 0x78, + 0xce, 0x2f, 0x61, 0x20, 0x6c, 0x7e, 0x35, 0x60, + 0xfb, 0xdd, 0x4c, 0x63, 0xfb, 0x95, 0x35, 0xc0, + 0x82, 0x59, 0xc2, 0xc9, 0x78, 0x6e, 0x30, 0xe6, + 0xd2, 0x72, 0x15, 0x14, 0x18, 0x62, 0x5d, 0xeb, + 0x2d, 0x9d, 0x3e, 0xee, 0x2e, 0x58, 0x58, 0xe9, + 0x40, 0x68, 0xb9, 0x2f, 0x23, 0x99, 0x2a, 0x4d, + 0xe8, 0x49, 0x79, 0x70, 0x1f, 0xf9, 0xe2, 0x34, + 0x2e, 0xab, 0xa5, 0xa3, 0xf2, 0x70, 0x98, 0xd0, + 0xb2, 0xb1, 0x3e, 0x5d, 0x90, 0x20, 0xd9, 0x36, + 0x8b, 0xdb, 0xaa, 0x20, 0x40, 0x03, 0x14, 0x06, + 0x03, 0x16, 0x2a, 0x9d, 0x31, 0xbd, 0x28, 0x3b, + 0x0c, 0xac, 0x41, + 0x28, 0xb5, 0x2f, 0xfd, 0x04, 0x58, 0xbd, 0x04, + 0x00, 0x62, 0xcd, 0x22, 0x19, 0xa0, 0x25, 0x69, + 0x03, 0x60, 0x72, 0xc9, 0x36, 0xda, 0xd2, 0x8b, + 0xfc, 0xbf, 0x25, 0x42, 0xa9, 0x82, 0x38, 0x70, + 0x1a, 0x2e, 0x54, 0x95, 0x33, 0x02, 0x03, 0x51, + 0x36, 0x51, 0x80, 0xcc, 0x7a, 0x6e, 0x52, 0x2e, + 0x75, 0x64, 0x2d, 0x33, 0x2c, 0xd6, 0xdb, 0xfc, + 0x39, 0x31, 0xd5, 0xa8, 0xa2, 0x40, 0xd7, 0x12, + 0x4c, 0xc6, 0x76, 0xdc, 0x1e, 0x0f, 0xf4, 0x4e, + 0x0a, 0xd3, 0x0c, 0x87, 0x67, 0x25, 0x25, 0x52, + 0x66, 0x87, 0x95, 0xc6, 0x69, 0x0c, 0xb4, 0x5e, + 0x1d, 0xe7, 0x5e, 0xcd, 0x47, 0x41, 0x80, 0x89, + 0x5c, 0xa5, 0x4a, 0x32, 0x26, 0xb3, 0x3d, 0x2b, + 0xd5, 0xc0, 0x16, 0xde, 0xfb, 0x65, 0xcd, 0x6a, + 0x0c, 0x3f, 0xe7, 0xd6, 0xb2, 0x17, 0x7c, 0x25, + 0x35, 0x6b, 0x58, 0xf0, 0x95, 0xb5, 0xf2, 0xe4, + 0x4e, 0xf0, 0x34, 0x4f, 0x5f, 0x39, 0xd1, 0x90, + 0xf8, 0xb9, 0x59, 0xbe, 0x2e, 0xf9, 0xd4, 0x02, + 0x98, 0x50, 0x5a, 0xc2, 0xcf, 0xe1, 0x08, 0x02, + 0x00, 0x0f, 0x1e, 0x44, 0x40, 0x79, 0x50, 0x67, + 0x3d, 0xd3, 0x35, 0x8f +#endif +}; + +static const char orig[] = +"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod\n" +"tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\n" +"quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n" +"consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\n" +"cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\n" +"proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n"; + +#if defined(TEST_BZIP2) || defined(TEST_BZIP22) +#define COMP_NAME "bzip2" +#define COMP_ID IO_COMPRESSOR_BZIP2 +#elif defined(TEST_XZ) || defined(TEST_XZ2) +#define COMP_NAME "xz" +#define COMP_ID IO_COMPRESSOR_XZ +#elif defined(TEST_GZIP) +#define COMP_NAME "gzip" +#define COMP_ID IO_COMPRESSOR_GZIP +#elif defined(TEST_ZSTD) || defined(TEST_ZSTD2) +#define COMP_NAME "zstd" +#define COMP_ID IO_COMPRESSOR_ZSTD +#endif + +static void destroy_noop(sqfs_object_t *obj) +{ + (void)obj; +} + +static int precache_noop(istream_t *strm) +{ + (void)strm; + return 0; +} + +static const char *get_filename(istream_t *strm) +{ + (void)strm; + return "memstream"; +} + +static istream_t memstream = { + .base = { + .destroy = destroy_noop, + }, + + .buffer_used = sizeof(data_in) / sizeof(data_in[0]), + .buffer_offset = 0, + .eof = true, + .buffer = data_in, + + .precache = precache_noop, + .get_filename = get_filename, +}; + +int main(int argc, char **argv) +{ + char buffer[2 * (sizeof(orig) / sizeof(orig[0]))]; + const char *name; + istream_t *xfrm; + size_t orig_sz; + int ret; + (void)argc; (void)argv; + + /* XXX: null terminator not included in the compressed blob */ + orig_sz = (sizeof(orig) / sizeof(orig[0])) - 1; + + /* generic API test */ + TEST_ASSERT(io_compressor_exists(COMP_ID)); + + name = io_compressor_name_from_id(COMP_ID); + TEST_STR_EQUAL(name, COMP_NAME); + + ret = io_compressor_id_from_name(name); + TEST_EQUAL_I(ret, COMP_ID); + + ret = istream_detect_compressor(&memstream, NULL); + TEST_EQUAL_I(ret, COMP_ID); + + /* decoder test */ + xfrm = istream_compressor_create(&memstream, COMP_ID); + TEST_NOT_NULL(xfrm); + + name = istream_get_filename(xfrm); + TEST_STR_EQUAL(name, "memstream"); + + ret = istream_read(xfrm, buffer, sizeof(buffer)); + TEST_ASSERT(ret > 0); + TEST_EQUAL_UI((size_t)ret, orig_sz); + + ret = memcmp(buffer, orig, ret); + TEST_EQUAL_I(ret, 0); + + ret = istream_read(xfrm, buffer, sizeof(buffer)); + TEST_EQUAL_I(ret, 0); + + /* cleanup */ + sqfs_destroy(xfrm); + return EXIT_SUCCESS; +} diff --git a/tests/libtar/Makemodule.am b/tests/libtar/Makemodule.am index bc829fb..b042f74 100644 --- a/tests/libtar/Makemodule.am +++ b/tests/libtar/Makemodule.am @@ -1,160 +1,160 @@ TARDATADIR=$(top_srcdir)/tests/libtar/data test_tar_gnu0_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_gnu0_LDADD = libtar.a libfstream.a libcompat.a +test_tar_gnu0_LDADD = libtar.a libio.a libcompat.a test_tar_gnu0_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_gnu0_CPPFLAGS += -DTESTFILE=format-acceptance/gnu.tar test_tar_gnu1_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_gnu1_LDADD = libtar.a libfstream.a libcompat.a +test_tar_gnu1_LDADD = libtar.a libio.a libcompat.a test_tar_gnu1_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_gnu1_CPPFLAGS += -DTESTFILE=format-acceptance/gnu-g.tar test_tar_gnu2_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_gnu2_LDADD = libtar.a libfstream.a libcompat.a +test_tar_gnu2_LDADD = libtar.a libio.a libcompat.a test_tar_gnu2_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_gnu2_CPPFLAGS += -DTESTFILE=user-group-largenum/gnu.tar test_tar_gnu2_CPPFLAGS += -DTESTUID=0x80000000 -DTESTGID=0x80000000 test_tar_gnu2_CPPFLAGS += -DTESTTS=1542995392 test_tar_gnu3_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_gnu3_LDADD = libtar.a libfstream.a libcompat.a +test_tar_gnu3_LDADD = libtar.a libio.a libcompat.a test_tar_gnu3_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_gnu3_CPPFLAGS += -DTESTFILE=negative-mtime/gnu.tar -DTESTTS=-315622800 test_tar_gnu4_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_gnu4_LDADD = libtar.a libfstream.a libcompat.a +test_tar_gnu4_LDADD = libtar.a libio.a libcompat.a test_tar_gnu4_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_gnu4_CPPFLAGS += -DTESTFILE=long-paths/gnu.tar -DLONG_NAME_TEST test_tar_gnu4_CPPFLAGS += -DTESTTS=1542909670 test_tar_gnu5_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_gnu5_LDADD = libtar.a libfstream.a libcompat.a +test_tar_gnu5_LDADD = libtar.a libio.a libcompat.a test_tar_gnu5_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_gnu5_CPPFLAGS += -DTESTFILE=large-mtime/gnu.tar -DTESTTS=8589934592L test_tar_gnu6_SOURCES = tests/libtar/tar_big_file.c tests/test.h -test_tar_gnu6_LDADD = libtar.a libfstream.a libcompat.a +test_tar_gnu6_LDADD = libtar.a libio.a libcompat.a test_tar_gnu6_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_gnu6_CPPFLAGS += -DTESTFILE=file-size/gnu.tar test_tar_pax0_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_pax0_LDADD = libtar.a libfstream.a libcompat.a +test_tar_pax0_LDADD = libtar.a libio.a libcompat.a test_tar_pax0_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_pax0_CPPFLAGS += -DTESTFILE=format-acceptance/pax.tar test_tar_pax1_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_pax1_LDADD = libtar.a libfstream.a libcompat.a +test_tar_pax1_LDADD = libtar.a libio.a libcompat.a test_tar_pax1_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_pax1_CPPFLAGS += -DTESTFILE=user-group-largenum/pax.tar test_tar_pax1_CPPFLAGS += -DTESTUID=2147483648UL -DTESTGID=2147483648UL test_tar_pax1_CPPFLAGS += -DTESTTS=1542995392 test_tar_pax2_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_pax2_LDADD = libtar.a libfstream.a libcompat.a +test_tar_pax2_LDADD = libtar.a libio.a libcompat.a test_tar_pax2_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_pax2_CPPFLAGS += -DTESTFILE=large-mtime/pax.tar -DTESTTS=8589934592L test_tar_pax3_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_pax3_LDADD = libtar.a libfstream.a libcompat.a +test_tar_pax3_LDADD = libtar.a libio.a libcompat.a test_tar_pax3_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_pax3_CPPFLAGS += -DTESTFILE=negative-mtime/pax.tar -DTESTTS=-315622800 test_tar_pax4_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_pax4_LDADD = libtar.a libfstream.a libcompat.a +test_tar_pax4_LDADD = libtar.a libio.a libcompat.a test_tar_pax4_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_pax4_CPPFLAGS += -DTESTFILE=long-paths/pax.tar test_tar_pax4_CPPFLAGS += -DLONG_NAME_TEST -DTESTTS=1542909670 test_tar_pax5_SOURCES = tests/libtar/tar_big_file.c tests/test.h -test_tar_pax5_LDADD = libtar.a libfstream.a libcompat.a +test_tar_pax5_LDADD = libtar.a libio.a libcompat.a test_tar_pax5_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_pax5_CPPFLAGS += -DTESTFILE=file-size/pax.tar test_tar_ustar0_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_ustar0_LDADD = libtar.a libfstream.a libcompat.a +test_tar_ustar0_LDADD = libtar.a libio.a libcompat.a test_tar_ustar0_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_ustar0_CPPFLAGS += -DTESTFILE=format-acceptance/ustar.tar test_tar_ustar1_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_ustar1_LDADD = libtar.a libfstream.a libcompat.a +test_tar_ustar1_LDADD = libtar.a libio.a libcompat.a test_tar_ustar1_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_ustar1_CPPFLAGS += -DTESTFILE=format-acceptance/ustar-pre-posix.tar test_tar_ustar2_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_ustar2_LDADD = libtar.a libfstream.a libcompat.a +test_tar_ustar2_LDADD = libtar.a libio.a libcompat.a test_tar_ustar2_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_ustar2_CPPFLAGS += -DTESTFILE=format-acceptance/v7.tar test_tar_ustar3_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_ustar3_LDADD = libtar.a libfstream.a libcompat.a +test_tar_ustar3_LDADD = libtar.a libio.a libcompat.a test_tar_ustar3_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_ustar3_CPPFLAGS += -DTESTFILE=user-group-largenum/8-digit.tar test_tar_ustar3_CPPFLAGS += -DTESTUID=8388608 -DTESTGID=8388608 test_tar_ustar3_CPPFLAGS += -DTESTTS=1542995392 test_tar_ustar4_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_ustar4_LDADD = libtar.a libfstream.a libcompat.a +test_tar_ustar4_LDADD = libtar.a libio.a libcompat.a test_tar_ustar4_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_ustar4_CPPFLAGS += -DTESTFILE=large-mtime/12-digit.tar test_tar_ustar4_CPPFLAGS += -DTESTTS=8589934592L test_tar_ustar5_SOURCES = tests/libtar/tar_simple.c tests/test.h -test_tar_ustar5_LDADD = libtar.a libfstream.a libcompat.a +test_tar_ustar5_LDADD = libtar.a libio.a libcompat.a test_tar_ustar5_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_ustar5_CPPFLAGS += -DTESTFILE=long-paths/ustar.tar test_tar_ustar5_CPPFLAGS += -DLONG_NAME_TEST -DTESTTS=1542909670 test_tar_ustar6_SOURCES = tests/libtar/tar_big_file.c tests/test.h -test_tar_ustar6_LDADD = libtar.a libfstream.a libcompat.a +test_tar_ustar6_LDADD = libtar.a libio.a libcompat.a test_tar_ustar6_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_ustar6_CPPFLAGS += -DTESTFILE=file-size/12-digit.tar test_tar_target_filled_SOURCES = tests/libtar/tar_target_filled.c tests/test.h -test_tar_target_filled_LDADD = libtar.a libfstream.a libcompat.a +test_tar_target_filled_LDADD = libtar.a libio.a libcompat.a test_tar_target_filled_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_sparse_gnu_SOURCES = tests/libtar/tar_sparse_gnu.c tests/test.h -test_tar_sparse_gnu_LDADD = libtar.a libfstream.a libcompat.a +test_tar_sparse_gnu_LDADD = libtar.a libio.a libcompat.a test_tar_sparse_gnu_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_sparse_gnu0_SOURCES = tests/libtar/tar_sparse.c tests/test.h -test_tar_sparse_gnu0_LDADD = libtar.a libfstream.a libcompat.a +test_tar_sparse_gnu0_LDADD = libtar.a libio.a libcompat.a test_tar_sparse_gnu0_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_sparse_gnu0_CPPFLAGS += -DTESTFILE=sparse-files/pax-gnu0-0.tar test_tar_sparse_gnu1_SOURCES = tests/libtar/tar_sparse.c tests/test.h -test_tar_sparse_gnu1_LDADD = libtar.a libfstream.a libcompat.a +test_tar_sparse_gnu1_LDADD = libtar.a libio.a libcompat.a test_tar_sparse_gnu1_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_sparse_gnu1_CPPFLAGS += -DTESTFILE=sparse-files/pax-gnu0-1.tar test_tar_sparse_gnu2_SOURCES = tests/libtar/tar_sparse.c tests/test.h -test_tar_sparse_gnu2_LDADD = libtar.a libfstream.a libcompat.a +test_tar_sparse_gnu2_LDADD = libtar.a libio.a libcompat.a test_tar_sparse_gnu2_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_sparse_gnu2_CPPFLAGS += -DTESTFILE=sparse-files/pax-gnu1-0.tar test_tar_sparse_gnu3_SOURCES = tests/libtar/tar_sparse.c tests/test.h -test_tar_sparse_gnu3_LDADD = libtar.a libfstream.a libcompat.a +test_tar_sparse_gnu3_LDADD = libtar.a libio.a libcompat.a test_tar_sparse_gnu3_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_sparse_gnu3_CPPFLAGS += -DTESTFILE=sparse-files/gnu.tar test_tar_xattr_bsd_SOURCES = tests/libtar/tar_xattr.c tests/test.h -test_tar_xattr_bsd_LDADD = libtar.a libfstream.a libcompat.a +test_tar_xattr_bsd_LDADD = libtar.a libio.a libcompat.a test_tar_xattr_bsd_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_xattr_bsd_CPPFLAGS += -DTESTFILE=xattr/xattr-libarchive.tar test_tar_xattr_schily_SOURCES = tests/libtar/tar_xattr.c tests/test.h -test_tar_xattr_schily_LDADD = libtar.a libfstream.a libcompat.a +test_tar_xattr_schily_LDADD = libtar.a libio.a libcompat.a test_tar_xattr_schily_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_xattr_schily_CPPFLAGS += -DTESTFILE=xattr/xattr-schily.tar test_tar_xattr_schily_bin_SOURCES = tests/libtar/tar_xattr_bin.c tests/test.h -test_tar_xattr_schily_bin_LDADD = libtar.a libfstream.a libcompat.a +test_tar_xattr_schily_bin_LDADD = libtar.a libio.a libcompat.a test_tar_xattr_schily_bin_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(TARDATADIR) test_tar_xattr_schily_bin_CPPFLAGS += -DTESTFILE=xattr/xattr-schily-binary.tar tar_fuzz_SOURCES = tests/libtar/tar_fuzz.c -tar_fuzz_LDADD = libtar.a libfstream.a libcompat.a +tar_fuzz_LDADD = libtar.a libio.a libcompat.a LIBTAR_TESTS = \ test_tar_ustar0 test_tar_ustar1 test_tar_ustar2 test_tar_ustar3 \ diff --git a/tests/libtar/tar_big_file.c b/tests/libtar/tar_big_file.c index 499805f..6e5af50 100644 --- a/tests/libtar/tar_big_file.c +++ b/tests/libtar/tar_big_file.c @@ -6,6 +6,7 @@ */ #include "config.h" #include "tar.h" +#include "io/file.h" #include "../test.h" int main(int argc, char **argv) diff --git a/tests/libtar/tar_fuzz.c b/tests/libtar/tar_fuzz.c index d5728b5..e7ab2b4 100644 --- a/tests/libtar/tar_fuzz.c +++ b/tests/libtar/tar_fuzz.c @@ -6,6 +6,7 @@ */ #include "config.h" +#include "io/file.h" #include "tar.h" #include diff --git a/tests/libtar/tar_simple.c b/tests/libtar/tar_simple.c index e5f0137..4fc1b8b 100644 --- a/tests/libtar/tar_simple.c +++ b/tests/libtar/tar_simple.c @@ -5,6 +5,7 @@ * Copyright (C) 2019 David Oberhollenzer */ #include "config.h" +#include "io/file.h" #include "tar.h" #include "../test.h" diff --git a/tests/libtar/tar_sparse.c b/tests/libtar/tar_sparse.c index 24f7a57..d868c80 100644 --- a/tests/libtar/tar_sparse.c +++ b/tests/libtar/tar_sparse.c @@ -5,6 +5,7 @@ * Copyright (C) 2019 David Oberhollenzer */ #include "config.h" +#include "io/file.h" #include "tar.h" #include "../test.h" diff --git a/tests/libtar/tar_sparse_gnu.c b/tests/libtar/tar_sparse_gnu.c index 5d12478..c55f175 100644 --- a/tests/libtar/tar_sparse_gnu.c +++ b/tests/libtar/tar_sparse_gnu.c @@ -5,6 +5,7 @@ * Copyright (C) 2019 David Oberhollenzer */ #include "config.h" +#include "io/file.h" #include "tar.h" #include "../test.h" diff --git a/tests/libtar/tar_target_filled.c b/tests/libtar/tar_target_filled.c index 57c6af9..34bf20f 100644 --- a/tests/libtar/tar_target_filled.c +++ b/tests/libtar/tar_target_filled.c @@ -5,6 +5,7 @@ * Copyright (C) 2019 David Oberhollenzer */ #include "config.h" +#include "io/file.h" #include "tar.h" #include "../test.h" diff --git a/tests/libtar/tar_xattr.c b/tests/libtar/tar_xattr.c index 877bfba..7dde243 100644 --- a/tests/libtar/tar_xattr.c +++ b/tests/libtar/tar_xattr.c @@ -5,6 +5,7 @@ * Copyright (C) 2019 David Oberhollenzer */ #include "config.h" +#include "io/file.h" #include "tar.h" #include "../test.h" diff --git a/tests/libtar/tar_xattr_bin.c b/tests/libtar/tar_xattr_bin.c index 51ca0b0..ea2bc28 100644 --- a/tests/libtar/tar_xattr_bin.c +++ b/tests/libtar/tar_xattr_bin.c @@ -5,6 +5,7 @@ * Copyright (C) 2019 David Oberhollenzer */ #include "config.h" +#include "io/file.h" #include "tar.h" #include "../test.h" diff --git a/tests/libutil/Makemodule.am b/tests/libutil/Makemodule.am index 27d6341..557a65c 100644 --- a/tests/libutil/Makemodule.am +++ b/tests/libutil/Makemodule.am @@ -1,5 +1,5 @@ test_str_table_SOURCES = tests/libutil/str_table.c tests/test.h -test_str_table_LDADD = libutil.a libfstream.a libcompat.a +test_str_table_LDADD = libutil.a libio.a libcompat.a test_str_table_CPPFLAGS = $(AM_CPPFLAGS) -DTESTPATH=$(top_srcdir)/tests/libutil test_rbtree_SOURCES = tests/libutil/rbtree.c tests/test.h diff --git a/tests/libutil/str_table.c b/tests/libutil/str_table.c index a69a9c4..509594c 100644 --- a/tests/libutil/str_table.c +++ b/tests/libutil/str_table.c @@ -7,7 +7,7 @@ #include "config.h" #include "util/str_table.h" -#include "fstream.h" +#include "io/file.h" #include "compat.h" #include "../test.h" -- cgit v1.2.3