Mercurial > dovecot > core-2.2
changeset 15717:30922a3668a9
lib-fs: istream-metawrap is a bit more flexible now, allowing stat()ing and reading from fd
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 03 Feb 2013 21:48:58 +0200 |
parents | f4d33f3c1ab9 |
children | 1aed8e57ea1c |
files | src/lib-fs/istream-metawrap.c |
diffstat | 1 files changed, 29 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-fs/istream-metawrap.c Sat Feb 02 22:21:36 2013 +0200 +++ b/src/lib-fs/istream-metawrap.c Sun Feb 03 21:48:58 2013 +0200 @@ -34,6 +34,7 @@ mstream->istream.istream.eof = TRUE; return -1; } + i_assert(!mstream->istream.parent->blocking); return 0; } @@ -51,12 +52,38 @@ mstream->start_offset = stream->parent->v_offset; if (ret <= 0) return ret; + /* this stream is kind of silently skipping over the metadata */ + stream->abs_start_offset += mstream->start_offset; mstream->in_metadata = FALSE; } /* after metadata header it's all just passthrough */ return i_stream_read_copy_from_parent(&stream->istream); } +static int i_stream_metawrap_stat(struct istream_private *stream, bool exact) +{ + struct metawrap_istream *mstream = (struct metawrap_istream *)stream; + const struct stat *st; + int ret; + + if (i_stream_stat(stream->parent, exact, &st) < 0) + return -1; + stream->statbuf = *st; + + if (mstream->in_metadata) { + ret = i_stream_read(&stream->istream); + if (ret < 0) + return -1; + if (ret == 0) { + stream->statbuf.st_size = -1; + return 0; + } + } + i_assert((uoff_t)stream->statbuf.st_size >= mstream->start_offset); + stream->statbuf.st_size -= mstream->start_offset; + return 0; +} + struct istream * i_stream_create_metawrap(struct istream *input, metawrap_callback_t *callback, void *context) @@ -67,8 +94,9 @@ mstream->istream.max_buffer_size = input->real_stream->max_buffer_size; mstream->istream.read = i_stream_metawrap_read; + mstream->istream.stat = i_stream_metawrap_stat; - mstream->istream.istream.readable_fd = FALSE; + mstream->istream.istream.readable_fd = input->readable_fd; mstream->istream.istream.blocking = input->blocking; mstream->istream.istream.seekable = FALSE; mstream->in_metadata = TRUE;