# HG changeset patch # User Timo Sirainen # Date 1241203808 14400 # Node ID 06bd1266f0c78d63d38d53fd630eb67447557469 # Parent e87431fb8c9091adf175c720d3a4af141bf12335 istreams: Fixed some parent stream seeking issues. diff -r e87431fb8c90 -r 06bd1266f0c7 src/lib-mail/istream-header-filter.c --- a/src/lib-mail/istream-header-filter.c Fri May 01 14:49:08 2009 -0400 +++ b/src/lib-mail/istream-header-filter.c Fri May 01 14:50:08 2009 -0400 @@ -295,7 +295,6 @@ struct header_filter_istream *mstream = (struct header_filter_istream *)stream; ssize_t ret; - size_t pos; if (!mstream->header_read || stream->istream.v_offset < mstream->header_size.virtual_size) { @@ -313,27 +312,7 @@ stream->istream.v_offset - mstream->header_size.virtual_size + mstream->header_size.physical_size); - - stream->pos -= stream->skip; - stream->skip = 0; - - stream->buffer = i_stream_get_data(stream->parent, &pos); - if (pos <= stream->pos) { - if ((ret = i_stream_read(stream->parent)) == -2) { - i_assert(stream->skip != stream->pos); - return -2; - } - stream->istream.stream_errno = stream->parent->stream_errno; - stream->istream.eof = stream->parent->eof; - stream->buffer = i_stream_get_data(stream->parent, &pos); - } else { - ret = 0; - } - - ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : - (ret == 0 ? 0 : -1); - stream->pos = pos; - return ret; + return i_stream_read_copy_from_parent(&stream->istream); } static void parse_header(struct header_filter_istream *mstream) diff -r e87431fb8c90 -r 06bd1266f0c7 src/lib-storage/index/istream-mail-stats.c --- a/src/lib-storage/index/istream-mail-stats.c Fri May 01 14:49:08 2009 -0400 +++ b/src/lib-storage/index/istream-mail-stats.c Fri May 01 14:50:08 2009 -0400 @@ -36,7 +36,6 @@ { struct mail_stats_istream *mstream = (struct mail_stats_istream *)stream; - size_t pos; ssize_t ret; if (stream->parent->v_offset != @@ -45,34 +44,14 @@ stream->istream.v_offset); } - stream->buffer = i_stream_get_data(stream->parent, &pos); - if (pos <= stream->pos) { - if ((ret = i_stream_read(stream->parent)) == -2) - return -2; - - if (ret > 0) { - mstream->mail->stats_files_read_bytes+= ret; - if (!mstream->files_read_increased) { - mstream->files_read_increased = TRUE; - mstream->mail->stats_files_read_count++; - } + ret = i_stream_read_copy_from_parent(&stream->istream); + if (ret > 0) { + mstream->mail->stats_files_read_bytes += ret; + if (!mstream->files_read_increased) { + mstream->files_read_increased = TRUE; + mstream->mail->stats_files_read_count++; } - - stream->istream.stream_errno = stream->parent->stream_errno; - stream->istream.eof = stream->parent->eof; - stream->buffer = i_stream_get_data(stream->parent, &pos); - } else { - ret = 0; } - - stream->pos -= stream->skip; - stream->skip = 0; - - ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : - (ret == 0 ? 0 : -1); - stream->pos = pos; - i_assert(ret != -1 || stream->istream.eof || - stream->istream.stream_errno != 0); return ret; } diff -r e87431fb8c90 -r 06bd1266f0c7 src/lib/istream-internal.h --- a/src/lib/istream-internal.h Fri May 01 14:49:08 2009 -0400 +++ b/src/lib/istream-internal.h Fri May 01 14:50:08 2009 -0400 @@ -44,5 +44,6 @@ void i_stream_grow_buffer(struct istream_private *stream, size_t bytes); bool i_stream_get_buffer_space(struct istream_private *stream, size_t wanted_size, size_t *size_r); +ssize_t i_stream_read_copy_from_parent(struct istream *istream); #endif diff -r e87431fb8c90 -r 06bd1266f0c7 src/lib/istream-limit.c --- a/src/lib/istream-limit.c Fri May 01 14:49:08 2009 -0400 +++ b/src/lib/istream-limit.c Fri May 01 14:50:08 2009 -0400 @@ -54,20 +54,20 @@ stream->istream.v_offset); } + stream->pos -= stream->skip; + stream->skip = 0; + stream->buffer = i_stream_get_data(stream->parent, &pos); - if (pos <= stream->pos) { + if (pos > stream->pos) + ret = 0; + else do { if ((ret = i_stream_read(stream->parent)) == -2) return -2; stream->istream.stream_errno = stream->parent->stream_errno; stream->istream.eof = stream->parent->eof; stream->buffer = i_stream_get_data(stream->parent, &pos); - } else { - ret = 0; - } - - stream->pos -= stream->skip; - stream->skip = 0; + } while (pos <= stream->pos && ret > 0); if (lstream->v_size != (uoff_t)-1) { left = lstream->v_size - stream->istream.v_offset; diff -r e87431fb8c90 -r 06bd1266f0c7 src/lib/istream.c --- a/src/lib/istream.c Fri May 01 14:49:08 2009 -0400 +++ b/src/lib/istream.c Fri May 01 14:50:08 2009 -0400 @@ -102,6 +102,38 @@ return ret; } +ssize_t i_stream_read_copy_from_parent(struct istream *istream) +{ + struct istream_private *stream = istream->real_stream; + size_t pos; + ssize_t ret; + + stream->pos -= stream->skip; + stream->skip = 0; + + stream->buffer = i_stream_get_data(stream->parent, &pos); + if (pos > stream->pos) + ret = 0; + else do { + if ((ret = i_stream_read(stream->parent)) == -2) + return -2; + + stream->istream.stream_errno = stream->parent->stream_errno; + stream->istream.eof = stream->parent->eof; + stream->buffer = i_stream_get_data(stream->parent, &pos); + /* check again, in case the parent stream had been seeked + backwards and the previous read() didn't get us far + enough. */ + } while (pos <= stream->pos && ret > 0); + + ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) : + (ret == 0 ? 0 : -1); + stream->pos = pos; + i_assert(ret != -1 || stream->istream.eof || + stream->istream.stream_errno != 0); + return ret; +} + void i_stream_skip(struct istream *stream, uoff_t count) { struct istream_private *_stream = stream->real_stream;