dovecot-2.0: zlib: Several fixes to zlib/bzlib istreams.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Mar 8 15:41:06 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/681e1c702899
changeset: 10855:681e1c702899
user: Timo Sirainen <tss at iki.fi>
date: Mon Mar 08 15:41:02 2010 +0200
description:
zlib: Several fixes to zlib/bzlib istreams.
diffstat:
src/plugins/zlib/istream-bzlib.c | 30 +++++++++++++++++++++++++++---
src/plugins/zlib/istream-zlib.c | 28 ++++++++++++++++++++++++++--
2 files changed, 53 insertions(+), 5 deletions(-)
diffs (170 lines):
diff -r d49913d2d75a -r 681e1c702899 src/plugins/zlib/istream-bzlib.c
--- a/src/plugins/zlib/istream-bzlib.c Mon Mar 08 15:29:41 2010 +0200
+++ b/src/plugins/zlib/istream-bzlib.c Mon Mar 08 15:41:02 2010 +0200
@@ -15,7 +15,7 @@
bz_stream zs;
uoff_t eof_offset;
- size_t prev_size;
+ size_t prev_size, high_pos;
unsigned int log_errors:1;
unsigned int marked:1;
@@ -50,10 +50,27 @@
high_offset = stream->istream.v_offset + (stream->pos - stream->skip);
if (zstream->eof_offset == high_offset) {
+ i_assert(zstream->high_pos == 0);
stream->istream.eof = TRUE;
return -1;
}
+ if (stream->pos < zstream->high_pos) {
+ /* we're here because we seeked back within the read buffer. */
+ ret = zstream->high_pos - stream->pos;
+ stream->pos = zstream->high_pos;
+ zstream->high_pos = 0;
+
+ if (zstream->eof_offset != (uoff_t)-1) {
+ high_offset = stream->istream.v_offset +
+ (stream->pos - stream->skip);
+ i_assert(zstream->eof_offset == high_offset);
+ stream->istream.eof = TRUE;
+ }
+ return ret;
+ }
+ zstream->high_pos = 0;
+
if (stream->pos + CHUNK_SIZE > stream->buffer_size) {
/* try to keep at least CHUNK_SIZE available */
if (!zstream->marked && stream->skip > 0) {
@@ -110,7 +127,7 @@
zstream->zs.avail_out = size;
ret = BZ2_bzDecompress(&zstream->zs);
- size -= zstream->zs.avail_in;
+ size -= zstream->zs.avail_out;
stream->pos += size;
switch (ret) {
@@ -173,13 +190,15 @@
{
struct istream_private *stream = &zstream->istream;
- i_stream_seek(stream->parent, 0);
+ i_stream_seek(stream->parent, stream->parent_start_offset);
zstream->eof_offset = (uoff_t)-1;
zstream->zs.next_in = NULL;
zstream->zs.avail_in = 0;
stream->skip = stream->pos = 0;
stream->istream.v_offset = 0;
+ zstream->high_pos = 0;
+ zstream->prev_size = 0;
(void)BZ2_bzDecompressEnd(&zstream->zs);
i_stream_bzlib_init(zstream);
@@ -195,12 +214,17 @@
/* have to seek backwards */
i_stream_bzlib_reset(zstream);
start_offset = 0;
+ } else if (zstream->high_pos != 0) {
+ stream->pos = zstream->high_pos;
+ zstream->high_pos = 0;
}
if (v_offset <= start_offset + stream->pos) {
/* seeking backwards within what's already cached */
stream->skip = v_offset - start_offset;
stream->istream.v_offset = v_offset;
+ zstream->high_pos = stream->pos;
+ stream->pos = stream->skip;
} else {
/* read and cache forward */
do {
diff -r d49913d2d75a -r 681e1c702899 src/plugins/zlib/istream-zlib.c
--- a/src/plugins/zlib/istream-zlib.c Mon Mar 08 15:29:41 2010 +0200
+++ b/src/plugins/zlib/istream-zlib.c Mon Mar 08 15:41:02 2010 +0200
@@ -26,7 +26,7 @@
z_stream zs;
uoff_t eof_offset;
- size_t prev_size;
+ size_t prev_size, high_pos;
uint32_t crc32;
unsigned int gz:1;
@@ -170,6 +170,7 @@
high_offset = stream->istream.v_offset + (stream->pos - stream->skip);
if (zstream->eof_offset == high_offset) {
+ i_assert(zstream->high_pos == 0);
if (!zstream->trailer_read) {
do {
ret = i_stream_zlib_read_trailer(zstream);
@@ -182,6 +183,7 @@
}
if (!zstream->header_read) {
+ i_assert(zstream->high_pos == 0);
do {
ret = i_stream_zlib_read_header(stream);
} while (ret == 0 && stream->istream.blocking);
@@ -191,6 +193,21 @@
zstream->prev_size = 0;
}
+ if (stream->pos < zstream->high_pos) {
+ /* we're here because we seeked back within the read buffer. */
+ ret = zstream->high_pos - stream->pos;
+ stream->pos = zstream->high_pos;
+ zstream->high_pos = 0;
+ if (zstream->trailer_read) {
+ high_offset = stream->istream.v_offset +
+ (stream->pos - stream->skip);
+ i_assert(zstream->eof_offset == high_offset);
+ stream->istream.eof = TRUE;
+ }
+ return ret;
+ }
+ zstream->high_pos = 0;
+
if (stream->pos + CHUNK_SIZE > stream->buffer_size) {
/* try to keep at least CHUNK_SIZE available */
if (!zstream->marked && stream->skip > 0) {
@@ -317,7 +334,7 @@
{
struct istream_private *stream = &zstream->istream;
- i_stream_seek(stream->parent, 0);
+ i_stream_seek(stream->parent, stream->parent_start_offset);
zstream->eof_offset = (uoff_t)-1;
zstream->crc32 = 0;
@@ -326,6 +343,8 @@
stream->skip = stream->pos = 0;
stream->istream.v_offset = 0;
+ zstream->high_pos = 0;
+ zstream->prev_size = 0;
(void)inflateEnd(&zstream->zs);
i_stream_zlib_init(zstream);
@@ -341,12 +360,17 @@
/* have to seek backwards */
i_stream_zlib_reset(zstream);
start_offset = 0;
+ } else if (zstream->high_pos != 0) {
+ stream->pos = zstream->high_pos;
+ zstream->high_pos = 0;
}
if (v_offset <= start_offset + stream->pos) {
/* seeking backwards within what's already cached */
stream->skip = v_offset - start_offset;
stream->istream.v_offset = v_offset;
+ zstream->high_pos = stream->pos;
+ stream->pos = stream->skip;
} else {
/* read and cache forward */
do {
More information about the dovecot-cvs
mailing list