diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2022-06-26 22:51:27 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2022-07-08 19:17:35 +0200 |
commit | 359d71e90050a8b83f7bc7d2ecd4ff29c477cc22 (patch) | |
tree | df2b7a585b78e6776446d4ca9be62a22db27f0a7 /lib/io/uncompress/autodetect.c | |
parent | 2087cc237cd0fe1ed29ebf891648bacb46f4833b (diff) |
Cleanup: rename libfstream to libio, split headers
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/io/uncompress/autodetect.c')
-rw-r--r-- | lib/io/uncompress/autodetect.c | 55 |
1 files changed, 55 insertions, 0 deletions
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 <goliath@infraroot.at> + */ +#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; +} |