From: Timo Sirainen Date: Wed, 24 Jun 2009 01:15:21 +0000 (-0400) Subject: istreams: Added a default seek() implementation for non-seekable streams. X-Git-Tag: 2.0.alpha1~530 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=12a3540693ab69ec622e04d1b3b66962b8b2a3d9;p=thirdparty%2Fdovecot%2Fcore.git istreams: Added a default seek() implementation for non-seekable streams. --HG-- branch : HEAD --- diff --git a/src/lib-mail/istream-dot.c b/src/lib-mail/istream-dot.c index 0e26f166a3..a080b2c2ef 100644 --- a/src/lib-mail/istream-dot.c +++ b/src/lib-mail/istream-dot.c @@ -199,13 +199,6 @@ end: return ret; } -static void -i_stream_dot_seek(struct istream_private *stream ATTR_UNUSED, - uoff_t v_offset ATTR_UNUSED, bool mark ATTR_UNUSED) -{ - i_panic("dot-istream: seeking unsupported currently"); -} - static const struct stat * i_stream_dot_stat(struct istream_private *stream, bool exact) { @@ -220,7 +213,6 @@ struct istream *i_stream_create_dot(struct istream *input, bool send_last_lf) dstream->istream.max_buffer_size = input->real_stream->max_buffer_size; dstream->istream.read = i_stream_dot_read; - dstream->istream.seek = i_stream_dot_seek; dstream->istream.stat = i_stream_dot_stat; dstream->istream.istream.blocking = input->blocking; diff --git a/src/lib/istream-crlf.c b/src/lib/istream-crlf.c index 97baac0818..28d98d342f 100644 --- a/src/lib/istream-crlf.c +++ b/src/lib/istream-crlf.c @@ -133,32 +133,6 @@ static ssize_t i_stream_crlf_read_lf(struct istream_private *stream) return ret; } -static void -i_stream_crlf_seek(struct istream_private *stream, - uoff_t v_offset, bool mark ATTR_UNUSED) -{ - size_t available; - - if (stream->istream.v_offset > v_offset) - i_panic("crlf-istream: seeking unsupported currently"); - - while (stream->istream.v_offset < v_offset) { - (void)i_stream_crlf_read_crlf(stream); - - available = stream->pos - stream->skip; - if (available == 0) { - stream->istream.stream_errno = ESPIPE; - return; - } - if (available <= v_offset - stream->istream.v_offset) - i_stream_skip(&stream->istream, available); - else { - i_stream_skip(&stream->istream, - v_offset - stream->istream.v_offset); - } - } -} - static const struct stat * i_stream_crlf_stat(struct istream_private *stream, bool exact) { @@ -175,7 +149,6 @@ i_stream_create_crlf_full(struct istream *input, bool crlf) cstream->istream.read = crlf ? i_stream_crlf_read_crlf : i_stream_crlf_read_lf; - cstream->istream.seek = i_stream_crlf_seek; cstream->istream.stat = i_stream_crlf_stat; cstream->istream.istream.blocking = input->blocking; diff --git a/src/lib/istream-tee.c b/src/lib/istream-tee.c index 40871cb1e1..41dc68b63e 100644 --- a/src/lib/istream-tee.c +++ b/src/lib/istream-tee.c @@ -155,13 +155,6 @@ static ssize_t i_stream_tee_read(struct istream_private *stream) return ret; } -static void ATTR_NORETURN -i_stream_tee_seek(struct istream_private *stream ATTR_UNUSED, - uoff_t v_offset ATTR_UNUSED, bool mark ATTR_UNUSED) -{ - i_panic("tee-istream: seeking unsupported currently"); -} - static const struct stat * i_stream_tee_stat(struct istream_private *stream, bool exact) { @@ -210,7 +203,6 @@ struct istream *tee_i_stream_create_child(struct tee_istream *tee) i_stream_tee_set_max_buffer_size; tstream->istream.read = i_stream_tee_read; - tstream->istream.seek = i_stream_tee_seek; tstream->istream.stat = i_stream_tee_stat; tstream->istream.sync = i_stream_tee_sync; diff --git a/src/lib/istream.c b/src/lib/istream.c index def9acbe8e..c6e7979b82 100644 --- a/src/lib/istream.c +++ b/src/lib/istream.c @@ -496,6 +496,31 @@ static void i_stream_default_destroy(struct iostream_private *stream) } } +static void +i_stream_default_seek(struct istream_private *stream, + uoff_t v_offset, bool mark ATTR_UNUSED) +{ + size_t available; + + if (stream->istream.v_offset > v_offset) + i_panic("stream doesn't support seeking backwards"); + + while (stream->istream.v_offset < v_offset) { + (void)i_stream_read(&stream->istream); + + available = stream->pos - stream->skip; + if (available == 0) { + stream->istream.stream_errno = ESPIPE; + return; + } + if (available <= v_offset - stream->istream.v_offset) + i_stream_skip(&stream->istream, available); + else { + i_stream_skip(&stream->istream, + v_offset - stream->istream.v_offset); + } + } +} static const struct stat * i_stream_default_stat(struct istream_private *stream, bool exact ATTR_UNUSED) { @@ -533,6 +558,10 @@ i_stream_create(struct istream_private *_stream, struct istream *parent, int fd) if (_stream->iostream.destroy == NULL) _stream->iostream.destroy = i_stream_default_destroy; + if (_stream->seek == NULL) { + i_assert(!_stream->istream.seekable); + _stream->seek = i_stream_default_seek; + } if (_stream->stat == NULL) _stream->stat = i_stream_default_stat; if (_stream->get_size == NULL)