diff options
Diffstat (limited to 'lib/comp/compressor.c')
-rw-r--r-- | lib/comp/compressor.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/lib/comp/compressor.c b/lib/comp/compressor.c index 42ebd8b..3b473a3 100644 --- a/lib/comp/compressor.c +++ b/lib/comp/compressor.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-3.0-or-later */ #include <string.h> +#include <stdio.h> #include "internal.h" +#include "util.h" typedef compressor_t *(*compressor_fun_t)(bool compress, size_t block_size); @@ -15,8 +17,62 @@ static compressor_fun_t compressors[SQFS_COMP_MAX + 1] = { #ifdef WITH_LZO [SQFS_COMP_LZO] = create_lzo_compressor, #endif +#ifdef WITH_LZ4 + [SQFS_COMP_LZ4] = create_lz4_compressor, +#endif }; +int generic_write_options(int fd, const void *data, size_t size) +{ + uint8_t buffer[size + 2]; + ssize_t ret; + + *((uint16_t *)buffer) = htole16(0x8000 | size); + memcpy(buffer + 2, data, size); + + ret = write_retry(fd, buffer, sizeof(buffer)); + + if (ret < 0) { + perror("writing compressor options"); + return -1; + } + + if ((size_t)ret < sizeof(buffer)) { + fputs("writing compressor options: truncated write\n", stderr); + return -1; + } + + return ret; +} + +int generic_read_options(int fd, void *data, size_t size) +{ + uint8_t buffer[size + 2]; + ssize_t ret; + + ret = read_retry(fd, buffer, sizeof(buffer)); + + if (ret < 0) { + perror("reading compressor options"); + return -1; + } + + if ((size_t)ret < sizeof(buffer)) { + fputs("reading compressor options: unexpected end of file\n", + stderr); + return -1; + } + + if (le16toh(*((uint16_t *)buffer)) != (0x8000 | size)) { + fputs("reading compressor options: invalid meta data header\n", + stderr); + return -1; + } + + memcpy(data, buffer + 2, size); + return 0; +} + bool compressor_exists(E_SQFS_COMPRESSOR id) { if (id < SQFS_COMP_MIN || id > SQFS_COMP_MAX) |