]> git.ipfire.org Git - pakfire.git/commitdiff
compress: Implement passing the compression level to XZ & Zstd
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Jan 2025 11:43:55 +0000 (11:43 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Jan 2025 11:43:55 +0000 (11:43 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/compress.c

index afabe206396590956a537910052eadb6efad16f6..021f8377cf2ad90cc72d004e144044346f660d92 100644 (file)
@@ -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;