]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
istreams: Added a default seek() implementation for non-seekable streams.
authorTimo Sirainen <tss@iki.fi>
Wed, 24 Jun 2009 01:15:21 +0000 (21:15 -0400)
committerTimo Sirainen <tss@iki.fi>
Wed, 24 Jun 2009 01:15:21 +0000 (21:15 -0400)
--HG--
branch : HEAD

src/lib-mail/istream-dot.c
src/lib/istream-crlf.c
src/lib/istream-tee.c
src/lib/istream.c

index 0e26f166a346042d1ead097bb03a58310a4ea1b6..a080b2c2efd3f1ff17bdd068a5157335a30be18a 100644 (file)
@@ -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;
index 97baac0818b44ca464d3158c06f538c316045beb..28d98d342fe4fa051a3f5f0f0beb189bb44d1743 100644 (file)
@@ -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;
index 40871cb1e1abbd57aa4ba6201b3895fbea9754b3..41dc68b63e8310752b3f2c090df01d1dd4682783 100644 (file)
@@ -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;
 
index def9acbe8e70da3fee8fabb26cf7a88812f26119..c6e7979b823fcaa38530b06979c7cfb84a97250d 100644 (file)
@@ -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)