]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-compression: ostream-zlib - Add support for create_ostream_auto() API
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Sat, 29 Jul 2023 17:49:34 +0000 (20:49 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:10 +0000 (12:34 +0200)
src/lib-compression/compression.c
src/lib-compression/ostream-zlib.c
src/lib-compression/ostream-zlib.h

index 13f6191bff27946e998f4f543241760e9ee6a8f7..d48cebd0da7b4e8ee1bc98f7794028d5a0eeec49 100644 (file)
@@ -150,6 +150,7 @@ const struct compression_handler compression_handlers[] = {
                .is_compressed = is_compressed_zlib,
                .create_istream = i_stream_create_gz,
                .create_ostream = o_stream_create_gz,
+               .create_ostream_auto = o_stream_create_gz_auto,
                .get_min_level = compression_get_min_level_gz,
                .get_default_level = compression_get_default_level_gz,
                .get_max_level = compression_get_max_level_gz,
@@ -170,6 +171,7 @@ const struct compression_handler compression_handlers[] = {
                .is_compressed = NULL,
                .create_istream = i_stream_create_deflate,
                .create_ostream = o_stream_create_deflate,
+               .create_ostream_auto = o_stream_create_deflate_auto,
                .get_min_level = compression_get_min_level_gz,
                .get_default_level = compression_get_default_level_gz,
                .get_max_level = compression_get_max_level_gz,
index d429ad263c4f70391d4cacc1a8310705023673e4..32f8c125c35a8fc8f8d77bded1d6b3a272a94627 100644 (file)
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "crc32.h"
 #include "ostream-private.h"
+#include "settings.h"
 #include "ostream-zlib.h"
 #include <zlib.h>
 
@@ -24,6 +25,61 @@ struct zlib_ostream {
        bool flushed:1;
 };
 
+struct zlib_settings {
+       pool_t pool;
+       unsigned int compress_gz_level;
+       unsigned int compress_deflate_level;
+};
+
+static bool zlib_settings_check(void *_set, pool_t pool, const char **error_r);
+
+#undef DEF
+#define DEF(type, name) \
+       SETTING_DEFINE_STRUCT_##type(#name, name, struct zlib_settings)
+static const struct setting_define zlib_setting_defines[] = {
+       DEF(UINT, compress_gz_level),
+       DEF(UINT, compress_deflate_level),
+
+       SETTING_DEFINE_LIST_END
+};
+static const struct zlib_settings zlib_default_settings = {
+       .compress_gz_level = 6,
+       .compress_deflate_level = 6,
+};
+
+const struct setting_parser_info zlib_setting_parser_info = {
+       .name = "zlib",
+
+       .defines = zlib_setting_defines,
+       .defaults = &zlib_default_settings,
+
+       .struct_size = sizeof(struct zlib_settings),
+       .pool_offset1 = 1 + offsetof(struct zlib_settings, pool),
+#ifndef CONFIG_BINARY
+       .check_func = zlib_settings_check,
+#endif
+};
+
+static bool zlib_settings_check(void *_set, pool_t pool ATTR_UNUSED,
+                               const char **error_r)
+{
+       struct zlib_settings *set = _set;
+
+       if (set->compress_gz_level > Z_BEST_COMPRESSION) {
+               *error_r = t_strdup_printf(
+                       "compress_gz_level must be between %d..%d",
+                       Z_NO_COMPRESSION, Z_BEST_COMPRESSION);
+               return FALSE;
+       }
+       if (set->compress_deflate_level > Z_BEST_COMPRESSION) {
+               *error_r = t_strdup_printf(
+                       "compress_deflate_level must be between %d..%d",
+                       Z_NO_COMPRESSION, Z_BEST_COMPRESSION);
+               return FALSE;
+       }
+       return TRUE;
+}
+
 int compression_get_min_level_gz(void)
 {
        return Z_NO_COMPRESSION;
@@ -386,3 +442,27 @@ struct ostream *o_stream_create_deflate(struct ostream *output, int level)
 {
        return o_stream_create_zlib(output, level, FALSE);
 }
+
+static struct ostream *
+o_stream_create_zlib_auto(struct ostream *output, struct event *event, bool gz)
+{
+       const struct zlib_settings *set;
+       const char *error;
+
+       if (settings_get(event, &zlib_setting_parser_info, 0,
+                        &set, &error) < 0)
+               return o_stream_create_error_str(EIO, "%s", error);
+       int level = gz ? set->compress_gz_level : set->compress_deflate_level;
+       settings_free(set);
+       return o_stream_create_zlib(output, level, gz);
+}
+
+struct ostream *o_stream_create_gz_auto(struct ostream *output, struct event *event)
+{
+       return o_stream_create_zlib_auto(output, event, TRUE);
+}
+
+struct ostream *o_stream_create_deflate_auto(struct ostream *output, struct event *event)
+{
+       return o_stream_create_zlib_auto(output, event, FALSE);
+}
index ac038b559abfcc309994ed2c1604e1a1ab0532a5..183069f34ee48e656bb640e7ea26c973622aa647 100644 (file)
@@ -7,6 +7,9 @@ struct ostream *o_stream_create_bz2(struct ostream *output, int level);
 struct ostream *o_stream_create_lz4(struct ostream *output, int level);
 struct ostream *o_stream_create_zstd(struct ostream *output, int level);
 
+struct ostream *o_stream_create_gz_auto(struct ostream *output, struct event *event);
+struct ostream *o_stream_create_deflate_auto(struct ostream *output, struct event *event);
+
 int compression_get_min_level_gz(void);
 int compression_get_default_level_gz(void);
 int compression_get_max_level_gz(void);