changeset 9522:85912a6031a0 HEAD

istreams: Added a default seek() implementation for non-seekable streams.
author Timo Sirainen <tss@iki.fi>
date Tue, 23 Jun 2009 21:15:21 -0400
parents 7ba2c40ed078
children 3f9dcaf102d1
files src/lib-mail/istream-dot.c src/lib/istream-crlf.c src/lib/istream-tee.c src/lib/istream.c
diffstat 4 files changed, 29 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-mail/istream-dot.c	Tue Jun 23 20:09:35 2009 -0400
+++ b/src/lib-mail/istream-dot.c	Tue Jun 23 21:15:21 2009 -0400
@@ -199,13 +199,6 @@
 	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 @@
 	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;
--- a/src/lib/istream-crlf.c	Tue Jun 23 20:09:35 2009 -0400
+++ b/src/lib/istream-crlf.c	Tue Jun 23 21:15:21 2009 -0400
@@ -133,32 +133,6 @@
 	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 @@
 
 	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;
--- a/src/lib/istream-tee.c	Tue Jun 23 20:09:35 2009 -0400
+++ b/src/lib/istream-tee.c	Tue Jun 23 21:15:21 2009 -0400
@@ -155,13 +155,6 @@
 	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 @@
 		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;
 
--- a/src/lib/istream.c	Tue Jun 23 20:09:35 2009 -0400
+++ b/src/lib/istream.c	Tue Jun 23 21:15:21 2009 -0400
@@ -496,6 +496,31 @@
 	}
 }
 
+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 @@
 
 	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)