From: Timo Sirainen Date: Tue, 5 Jun 2018 10:53:51 +0000 (+0300) Subject: lib-compression: Use i_stream_default_stat() instead of reimplementing it X-Git-Tag: 2.3.2.rc1~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=70aaf84c388af38a659ffe8cf41f74b766d57d82;p=thirdparty%2Fdovecot%2Fcore.git lib-compression: Use i_stream_default_stat() instead of reimplementing it --- diff --git a/src/lib-compression/istream-bzlib.c b/src/lib-compression/istream-bzlib.c index cb3b298c3a..092fcb5c5b 100644 --- a/src/lib-compression/istream-bzlib.c +++ b/src/lib-compression/istream-bzlib.c @@ -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; diff --git a/src/lib-compression/istream-lz4.c b/src/lib-compression/istream-lz4.c index fb63723ade..2a7551b475 100644 --- a/src/lib-compression/istream-lz4.c +++ b/src/lib-compression/istream-lz4.c @@ -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; diff --git a/src/lib-compression/istream-lzma.c b/src/lib-compression/istream-lzma.c index c354958880..a47f7b0c7d 100644 --- a/src/lib-compression/istream-lzma.c +++ b/src/lib-compression/istream-lzma.c @@ -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; diff --git a/src/lib-compression/istream-zlib.c b/src/lib-compression/istream-zlib.c index 0480ce9bdb..8adf57e22a 100644 --- a/src/lib-compression/istream-zlib.c +++ b/src/lib-compression/istream-zlib.c @@ -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; diff --git a/src/lib-compression/test-compression.c b/src/lib-compression/test-compression.c index 2996e49e92..718d05b817 100644 --- a/src/lib-compression/test-compression.c +++ b/src/lib-compression/test-compression.c @@ -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);