changeset 22608:3cdf8b140c3c

fs-compress: Support reading uncompressed input by prefixing compression format with "maybe-"
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 06 Oct 2017 18:33:24 +0300
parents 708b4dda62dc
children b7e049f3aa16
files src/plugins/fs-compress/fs-compress.c
diffstat 1 files changed, 33 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/fs-compress/fs-compress.c	Fri Oct 06 18:31:12 2017 +0300
+++ b/src/plugins/fs-compress/fs-compress.c	Fri Oct 06 18:33:24 2017 +0300
@@ -3,6 +3,8 @@
 #include "lib.h"
 #include "array.h"
 #include "istream.h"
+#include "istream-tee.h"
+#include "istream-try.h"
 #include "ostream.h"
 #include "iostream-temp.h"
 #include "compression.h"
@@ -12,6 +14,7 @@
 	struct fs fs;
 	const struct compression_handler *handler;
 	unsigned int compress_level;
+	bool try_plain;
 };
 
 struct compress_fs_file {
@@ -45,6 +48,11 @@
 	const char *parent_name, *parent_args;
 
 	/* get compression handler name */
+	if (strncmp(args, "maybe-", 6) == 0) {
+		fs->try_plain = TRUE;
+		args += 6;
+	}
+
 	p = strchr(args, ':');
 	if (p == NULL) {
 		fs_set_error(_fs, "Compression method not given as parameter");
@@ -151,6 +159,29 @@
 }
 
 static struct istream *
+fs_compress_try_create_stream(struct compress_fs_file *file,
+			      struct istream *plain_input)
+{
+	struct tee_istream *tee_input;
+	struct istream *child_input, *ret_input, *try_inputs[3];
+
+	if (!file->fs->try_plain)
+		return file->fs->handler->create_istream(plain_input, FALSE);
+
+	tee_input = tee_i_stream_create(plain_input);
+	child_input = tee_i_stream_create_child(tee_input);
+	try_inputs[0] = file->fs->handler->create_istream(child_input, FALSE);
+	try_inputs[1] = tee_i_stream_create_child(tee_input);
+	try_inputs[2] = NULL;
+	i_stream_unref(&child_input);
+
+	ret_input = istream_try_create(try_inputs);
+	i_stream_unref(&try_inputs[0]);
+	i_stream_unref(&try_inputs[1]);
+	return ret_input;
+}
+
+static struct istream *
 fs_compress_read_stream(struct fs_file *_file, size_t max_buffer_size)
 {
 	struct compress_fs_file *file = (struct compress_fs_file *)_file;
@@ -163,7 +194,8 @@
 	}
 
 	input = fs_read_stream(file->super_read, max_buffer_size);
-	file->input = file->fs->handler->create_istream(input, FALSE);
+	file->input = fs_compress_try_create_stream(file, input);
+
 	i_stream_unref(&input);
 	i_stream_ref(file->input);
 	return file->input;