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;
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;
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;
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);
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;
struct lz4_istream {
struct istream_private istream;
- uoff_t stream_size;
struct stat last_parent_statbuf;
buffer_t *chunk_buf;
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;
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;
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;
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;
{
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)
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;
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);
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;
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;
}
/* 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;
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) {
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;
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;
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;
}
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);
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);