]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-compression: Use i_stream_default_stat() instead of reimplementing it
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 5 Jun 2018 10:53:51 +0000 (13:53 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 6 Jun 2018 13:25:09 +0000 (16:25 +0300)
src/lib-compression/istream-bzlib.c
src/lib-compression/istream-lz4.c
src/lib-compression/istream-lzma.c
src/lib-compression/istream-zlib.c
src/lib-compression/test-compression.c

index cb3b298c3a280cac2f81e56030adaf9e30ed5598..092fcb5c5bbe5255734d42c9ee40f7401de5196a 100644 (file)
@@ -14,7 +14,7 @@ struct bzlib_istream {
        struct istream_private istream;
 
        bz_stream zs;
-       uoff_t eof_offset, stream_size;
+       uoff_t eof_offset;
        size_t high_pos;
        struct stat last_parent_statbuf;
 
@@ -136,7 +136,7 @@ static ssize_t i_stream_bzlib_read(struct istream_private *stream)
        case BZ_STREAM_END:
                zstream->eof_offset = stream->istream.v_offset +
                        (stream->pos - stream->skip);
-               zstream->stream_size = zstream->eof_offset;
+               stream->cached_stream_size = zstream->eof_offset;
                if (out_size == 0) {
                        stream->istream.eof = TRUE;
                        return -1;
@@ -248,44 +248,6 @@ i_stream_bzlib_seek(struct istream_private *stream, uoff_t v_offset, bool mark)
                zstream->marked = TRUE;
 }
 
-static int
-i_stream_bzlib_stat(struct istream_private *stream, bool exact)
-{
-       struct bzlib_istream *zstream = (struct bzlib_istream *) stream;
-       const struct stat *st;
-       size_t size;
-
-       if (i_stream_stat(stream->parent, exact, &st) < 0) {
-               stream->istream.stream_errno = stream->parent->stream_errno;
-               return -1;
-       }
-       stream->statbuf = *st;
-
-       /* when exact=FALSE always return the parent stat's size, even if we
-          know the exact value. this is necessary because otherwise e.g. mbox
-          code can see two different values and think that a compressed mbox
-          file keeps changing. */
-       if (!exact)
-               return 0;
-
-       if (zstream->stream_size == (uoff_t)-1) {
-               uoff_t old_offset = stream->istream.v_offset;
-               ssize_t ret;
-
-               do {
-                       size = i_stream_get_data_size(&stream->istream);
-                       i_stream_skip(&stream->istream, size);
-               } while ((ret = i_stream_read(&stream->istream)) > 0);
-               i_assert(ret == -1);
-
-               i_stream_seek(&stream->istream, old_offset);
-               if (zstream->stream_size == (uoff_t)-1)
-                       return -1;
-       }
-       stream->statbuf.st_size = zstream->stream_size;
-       return 0;
-}
-
 static void i_stream_bzlib_sync(struct istream_private *stream)
 {
        struct bzlib_istream *zstream = (struct bzlib_istream *) stream;
@@ -309,7 +271,6 @@ struct istream *i_stream_create_bz2(struct istream *input, bool log_errors)
 
        zstream = i_new(struct bzlib_istream, 1);
        zstream->eof_offset = (uoff_t)-1;
-       zstream->stream_size = (uoff_t)-1;
        zstream->log_errors = log_errors;
 
        i_stream_bzlib_init(zstream);
@@ -318,7 +279,6 @@ struct istream *i_stream_create_bz2(struct istream *input, bool log_errors)
        zstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
        zstream->istream.read = i_stream_bzlib_read;
        zstream->istream.seek = i_stream_bzlib_seek;
-       zstream->istream.stat = i_stream_bzlib_stat;
        zstream->istream.sync = i_stream_bzlib_sync;
 
        zstream->istream.istream.readable_fd = FALSE;
index fb63723adede3450912218a53f171a6b03d34be7..2a7551b47523e4723599fc72d607a5ecb7f4a636 100644 (file)
@@ -13,7 +13,6 @@
 struct lz4_istream {
        struct istream_private istream;
 
-       uoff_t stream_size;
        struct stat last_parent_statbuf;
 
        buffer_t *chunk_buf;
@@ -102,7 +101,8 @@ static ssize_t i_stream_lz4_read(struct istream_private *stream)
                                stream->parent->stream_errno;
                        if (stream->istream.stream_errno == 0) {
                                stream->istream.eof = TRUE;
-                               zstream->stream_size = stream->istream.v_offset +
+                               stream->cached_stream_size =
+                                       stream->istream.v_offset +
                                        stream->pos - stream->skip;
                        }
                        return ret;
@@ -231,44 +231,6 @@ i_stream_lz4_seek(struct istream_private *stream, uoff_t v_offset, bool mark)
                zstream->marked = TRUE;
 }
 
-static int
-i_stream_lz4_stat(struct istream_private *stream, bool exact)
-{
-       struct lz4_istream *zstream = (struct lz4_istream *) stream;
-       const struct stat *st;
-       size_t size;
-
-       if (i_stream_stat(stream->parent, exact, &st) < 0) {
-               stream->istream.stream_errno = stream->parent->stream_errno;
-               return -1;
-       }
-       stream->statbuf = *st;
-
-       /* when exact=FALSE always return the parent stat's size, even if we
-          know the exact value. this is necessary because otherwise e.g. mbox
-          code can see two different values and think that a compressed mbox
-          file keeps changing. */
-       if (!exact)
-               return 0;
-
-       if (zstream->stream_size == (uoff_t)-1) {
-               uoff_t old_offset = stream->istream.v_offset;
-               ssize_t ret;
-
-               do {
-                       size = i_stream_get_data_size(&stream->istream);
-                       i_stream_skip(&stream->istream, size);
-               } while ((ret = i_stream_read(&stream->istream)) > 0);
-               i_assert(ret == -1);
-
-               i_stream_seek(&stream->istream, old_offset);
-               if (zstream->stream_size == (uoff_t)-1)
-                       return -1;
-       }
-       stream->statbuf.st_size = zstream->stream_size;
-       return 0;
-}
-
 static void i_stream_lz4_sync(struct istream_private *stream)
 {
        struct lz4_istream *zstream = (struct lz4_istream *) stream;
@@ -291,14 +253,12 @@ struct istream *i_stream_create_lz4(struct istream *input, bool log_errors)
        struct lz4_istream *zstream;
 
        zstream = i_new(struct lz4_istream, 1);
-       zstream->stream_size = (uoff_t)-1;
        zstream->log_errors = log_errors;
 
        zstream->istream.iostream.close = i_stream_lz4_close;
        zstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
        zstream->istream.read = i_stream_lz4_read;
        zstream->istream.seek = i_stream_lz4_seek;
-       zstream->istream.stat = i_stream_lz4_stat;
        zstream->istream.sync = i_stream_lz4_sync;
 
        zstream->istream.istream.readable_fd = FALSE;
index c35495888029c5fe944e7ba2ef3ed41af5d81166..a47f7b0c7dfb4d15ab49668284fa2429e4b2f503 100644 (file)
@@ -16,7 +16,7 @@ struct lzma_istream {
        struct istream_private istream;
 
        lzma_stream strm;
-       uoff_t eof_offset, stream_size;
+       uoff_t eof_offset;
        size_t high_pos;
        struct stat last_parent_statbuf;
 
@@ -52,7 +52,7 @@ static void lzma_stream_end(struct lzma_istream *zstream)
 {
        zstream->eof_offset = zstream->istream.istream.v_offset +
                (zstream->istream.pos - zstream->istream.skip);
-       zstream->stream_size = zstream->eof_offset;
+       zstream->istream.cached_stream_size = zstream->eof_offset;
 }
 
 static ssize_t i_stream_lzma_read(struct istream_private *stream)
@@ -257,44 +257,6 @@ i_stream_lzma_seek(struct istream_private *stream, uoff_t v_offset, bool mark)
                zstream->marked = TRUE;
 }
 
-static int
-i_stream_lzma_stat(struct istream_private *stream, bool exact)
-{
-       struct lzma_istream *zstream = (struct lzma_istream *) stream;
-       const struct stat *st;
-       size_t size;
-
-       if (i_stream_stat(stream->parent, exact, &st) < 0) {
-               stream->istream.stream_errno = stream->parent->stream_errno;
-               return -1;
-       }
-       stream->statbuf = *st;
-
-       /* when exact=FALSE always return the parent stat's size, even if we
-          know the exact value. this is necessary because otherwise e.g. mbox
-          code can see two different values and think that a compressed mbox
-          file keeps changing. */
-       if (!exact)
-               return 0;
-
-       if (zstream->stream_size == (uoff_t)-1) {
-               uoff_t old_offset = stream->istream.v_offset;
-               ssize_t ret;
-
-               do {
-                       size = i_stream_get_data_size(&stream->istream);
-                       i_stream_skip(&stream->istream, size);
-               } while ((ret = i_stream_read(&stream->istream)) > 0);
-               i_assert(ret == -1);
-
-               i_stream_seek(&stream->istream, old_offset);
-               if (zstream->stream_size == (uoff_t)-1)
-                       return -1;
-       }
-       stream->statbuf.st_size = zstream->stream_size;
-       return 0;
-}
-
 static void i_stream_lzma_sync(struct istream_private *stream)
 {
        struct lzma_istream *zstream = (struct lzma_istream *) stream;
@@ -318,7 +280,6 @@ struct istream *i_stream_create_lzma(struct istream *input, bool log_errors)
 
        zstream = i_new(struct lzma_istream, 1);
        zstream->eof_offset = (uoff_t)-1;
-       zstream->stream_size = (uoff_t)-1;
        zstream->log_errors = log_errors;
 
        i_stream_lzma_init(zstream);
@@ -327,7 +288,6 @@ struct istream *i_stream_create_lzma(struct istream *input, bool log_errors)
        zstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
        zstream->istream.read = i_stream_lzma_read;
        zstream->istream.seek = i_stream_lzma_seek;
-       zstream->istream.stat = i_stream_lzma_stat;
        zstream->istream.sync = i_stream_lzma_sync;
 
        zstream->istream.istream.readable_fd = FALSE;
index 0480ce9bdbb8a2ddb81795d9994464fb9857475e..8adf57e22ad7fe1b412b88dc62167c00030c80f4 100644 (file)
@@ -25,7 +25,7 @@ struct zlib_istream {
        struct istream_private istream;
 
        z_stream zs;
-       uoff_t eof_offset, stream_size;
+       uoff_t eof_offset;
        size_t prev_size, high_pos;
        uint32_t crc32;
        struct stat last_parent_statbuf;
@@ -206,8 +206,8 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream)
                }
 
                /* gzip file with concatenated content */
+               stream->cached_stream_size = (uoff_t)-1;
                zstream->eof_offset = (uoff_t)-1;
-               zstream->stream_size = (uoff_t)-1;
                zstream->header_read = FALSE;
                zstream->trailer_read = FALSE;
                zstream->crc32 = 0;
@@ -299,7 +299,7 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream)
        case Z_STREAM_END:
                zstream->eof_offset = stream->istream.v_offset +
                        (stream->pos - stream->skip);
-               zstream->stream_size = zstream->eof_offset;
+               stream->cached_stream_size = zstream->eof_offset;
                zstream->zs.avail_in = 0;
 
                if (!zstream->trailer_read) {
@@ -420,44 +420,6 @@ i_stream_zlib_seek(struct istream_private *stream, uoff_t v_offset, bool mark)
                zstream->marked = TRUE;
 }
 
-static int
-i_stream_zlib_stat(struct istream_private *stream, bool exact)
-{
-       struct zlib_istream *zstream = (struct zlib_istream *) stream;
-       const struct stat *st;
-       size_t size;
-
-       if (i_stream_stat(stream->parent, exact, &st) < 0) {
-               stream->istream.stream_errno = stream->parent->stream_errno;
-               return -1;
-       }
-       stream->statbuf = *st;
-
-       /* when exact=FALSE always return the parent stat's size, even if we
-          know the exact value. this is necessary because otherwise e.g. mbox
-          code can see two different values and think that a compressed mbox
-          file keeps changing. */
-       if (!exact)
-               return 0;
-
-       if (zstream->stream_size == (uoff_t)-1) {
-               uoff_t old_offset = stream->istream.v_offset;
-               ssize_t ret;
-
-               do {
-                       size = i_stream_get_data_size(&stream->istream);
-                       i_stream_skip(&stream->istream, size);
-               } while ((ret = i_stream_read(&stream->istream)) > 0);
-               i_assert(ret == -1);
-
-               i_stream_seek(&stream->istream, old_offset);
-               if (zstream->stream_size == (uoff_t)-1)
-                       return -1;
-       }
-       stream->statbuf.st_size = zstream->stream_size;
-       return 0;
-}
-
 static void i_stream_zlib_sync(struct istream_private *stream)
 {
        struct zlib_istream *zstream = (struct zlib_istream *) stream;
@@ -482,7 +444,6 @@ i_stream_create_zlib(struct istream *input, bool gz, bool log_errors)
 
        zstream = i_new(struct zlib_istream, 1);
        zstream->eof_offset = (uoff_t)-1;
-       zstream->stream_size = (uoff_t)-1;
        zstream->gz = gz;
        zstream->log_errors = log_errors;
 
@@ -492,7 +453,6 @@ i_stream_create_zlib(struct istream *input, bool gz, bool log_errors)
        zstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
        zstream->istream.read = i_stream_zlib_read;
        zstream->istream.seek = i_stream_zlib_seek;
-       zstream->istream.stat = i_stream_zlib_stat;
        zstream->istream.sync = i_stream_zlib_sync;
 
        zstream->istream.istream.readable_fd = FALSE;
index 2996e49e925b31b3066d543a07202fd43e983e05..718d05b81754c09736bbb4af8adcb6a544c52b11 100644 (file)
@@ -63,7 +63,9 @@ static void test_compression_handler(const struct compression_handler *handler)
        }
 
        test_assert(o_stream_finish(output) > 0);
+       uoff_t uncompressed_size = output->offset;
        o_stream_destroy(&output);
+       uoff_t compressed_size = file_output->offset;
        o_stream_destroy(&file_output);
        sha1_result(&sha1, output_sha1);
 
@@ -71,6 +73,13 @@ static void test_compression_handler(const struct compression_handler *handler)
        sha1_init(&sha1);
        file_input = i_stream_create_fd(fd, IO_BLOCK_SIZE);
        input = handler->create_istream(file_input, FALSE);
+
+       test_assert(i_stream_get_size(input, FALSE, &size) == 1);
+       test_assert(size == compressed_size);
+
+       test_assert(i_stream_get_size(input, TRUE, &size) == 1);
+       test_assert(size == uncompressed_size);
+
        while ((ret = i_stream_read_more(input, &data, &size)) > 0) {
                sha1_loop(&sha1, data, size);
                i_stream_skip(input, size);