From: Michael Tremer Date: Thu, 30 Jan 2025 11:43:55 +0000 (+0000) Subject: compress: Implement passing the compression level to XZ & Zstd X-Git-Tag: 0.9.30~262 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=881ef75aed3bfd14f290d8342335bb773ece1131;p=pakfire.git compress: Implement passing the compression level to XZ & Zstd Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/compress.c b/src/pakfire/compress.c index afabe206..021f8377 100644 --- a/src/pakfire/compress.c +++ b/src/pakfire/compress.c @@ -124,6 +124,41 @@ FILE* pakfire_xfopen(FILE* f, const char* mode) { return f; } +static int parse_level(int* level, const char* mode) { + unsigned long value = 0; + char* p = NULL; + + // We must have mode + if (!mode || *mode != 'w') { + errno = EINVAL; + return -1; + } + + // Skip the w + mode++; + + // Do nothing if we have reached the end of the string + if (!*mode) + return 0; + + // Try parsing a number + value = strtoul(mode, &p, 10); + + // Break on error + if (value == ULONG_MAX) + return -1; + + // Check if we have parsed the entire string + if (p && *p) { + errno = EINVAL; + return -1; + } + + // Otherwise we return the value and return + *level = value; + return 0; +} + /* gzip */ @@ -327,7 +362,9 @@ static cookie_io_functions_t xz_functions = { }; FILE* pakfire_xzfopen(FILE* f, const char* mode) { + int level = XZ_COMPRESSION_LEVEL; lzma_ret ret; + int r; if (!f) { errno = EBADFD; @@ -352,7 +389,12 @@ FILE* pakfire_xzfopen(FILE* f, const char* mode) { break; case 'w': - ret = lzma_easy_encoder(&cookie->stream, XZ_COMPRESSION_LEVEL, LZMA_CHECK_SHA256); + // Try parsing the level + r = parse_level(&level, mode); + if (r < 0) + return NULL; + + ret = lzma_easy_encoder(&cookie->stream, level, LZMA_CHECK_SHA256); break; default: @@ -543,6 +585,7 @@ static cookie_io_functions_t zstd_functions = { FILE* pakfire_zstdfopen(FILE* f, const char* mode) { struct zstd_cookie* cookie = NULL; + int level = ZSTD_COMPRESSION_LEVEL; int r; // Check for a valid file handle @@ -586,13 +629,18 @@ FILE* pakfire_zstdfopen(FILE* f, const char* mode) { break; case 'w': + // Try parsing the level + r = parse_level(&level, mode); + if (r < 0) + return NULL; + // Allocate stream cookie->cstream = ZSTD_createCStream(); if (!cookie->cstream) goto ERROR; // Initialize stream - r = ZSTD_initCStream(cookie->cstream, ZSTD_COMPRESSION_LEVEL); + r = ZSTD_initCStream(cookie->cstream, level); if (ZSTD_isError(r)) goto ERROR;