[dovecot-cvs] dovecot/src/lib istream-internal.h, 1.5, 1.6 istream.c, 1.26, 1.27 istream.h, 1.15, 1.16

cras at dovecot.org cras at dovecot.org
Tue Mar 29 01:35:14 EEST 2005


Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv15246

Modified Files:
	istream-internal.h istream.c istream.h 
Log Message:
i_stream_next_line() works now even if the stream buffer can't be directly
modified.



Index: istream-internal.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream-internal.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- istream-internal.h	9 Nov 2003 18:26:25 -0000	1.5
+++ istream-internal.h	28 Mar 2005 22:35:12 -0000	1.6
@@ -19,6 +19,7 @@
 	int fd;
 	const unsigned char *buffer;
 	unsigned char *w_buffer; /* may be NULL */
+	string_t *line_str; /* for i_stream_next_line() if w_buffer == NULL */
 	size_t buffer_size;
 	uoff_t abs_start_offset;
 

Index: istream.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- istream.c	20 Oct 2004 17:03:23 -0000	1.26
+++ istream.c	28 Mar 2005 22:35:12 -0000	1.27
@@ -1,6 +1,7 @@
 /* Copyright (c) 2002-2003 Timo Sirainen */
 
 #include "lib.h"
+#include "str.h"
 #include "istream-internal.h"
 
 void i_stream_ref(struct istream *stream)
@@ -10,6 +11,12 @@
 
 void i_stream_unref(struct istream *stream)
 {
+	struct _istream *_stream = stream->real_stream;
+
+	if (_stream->iostream.refcount == 1) {
+		if (_stream->line_str != NULL)
+			str_free(_stream->line_str);
+	}
 	_io_stream_unref(&stream->real_stream->iostream);
 }
 
@@ -97,6 +104,36 @@
 	return !stream->eof || _stream->skip != _stream->pos;
 }
 
+static char *i_stream_next_line_finish(struct _istream *stream, size_t i)
+{
+	char *ret;
+	size_t end;
+
+	if (i > 0 && stream->buffer[i-1] == '\r')
+		end = i - 1;
+	else
+		end = i;
+
+	if (stream->w_buffer != NULL) {
+		/* modify the buffer directly */
+		stream->w_buffer[end] = '\0';
+		ret = (char *)stream->w_buffer + stream->skip;
+	} else {
+		/* use a temporary string to return it */
+		if (stream->line_str == NULL)
+			stream->line_str = str_new(default_pool, 256);
+		str_truncate(stream->line_str, 0);
+		str_append_n(stream->line_str, stream->buffer + stream->skip,
+			     end - stream->skip);
+		ret = str_c_modifyable(stream->line_str);
+	}
+
+	i++;
+	stream->istream.v_offset += i - stream->skip;
+	stream->skip = i;
+	return ret;
+}
+
 char *i_stream_next_line(struct istream *stream)
 {
 	struct _istream *_stream = stream->real_stream;
@@ -120,15 +157,7 @@
 	for (i = _stream->skip; i < _stream->pos; i++) {
 		if (_stream->buffer[i] == 10) {
 			/* got it */
-			if (i > 0 && _stream->buffer[i-1] == '\r')
-				_stream->w_buffer[i-1] = '\0';
-			else
-				_stream->w_buffer[i] = '\0';
-			ret_buf = (char *) _stream->w_buffer + _stream->skip;
-
-			i++;
-			stream->v_offset += i - _stream->skip;
-			_stream->skip = i;
+			ret_buf = i_stream_next_line_finish(_stream, i);
                         break;
 		}
 	}

Index: istream.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- istream.h	28 Mar 2005 13:06:43 -0000	1.15
+++ istream.h	28 Mar 2005 22:35:12 -0000	1.16
@@ -55,8 +55,7 @@
 int i_stream_have_bytes_left(struct istream *stream);
 
 /* Gets the next line from stream and returns it, or NULL if more data is
-   needed to make a full line. NOTE: modifies the data in buffer for the \0,
-   so it works only with buffered streams (currently only file). */
+   needed to make a full line. */
 char *i_stream_next_line(struct istream *stream);
 /* Like i_stream_next_line(), but reads for more data if needed. Returns NULL
    if more data is needed or error occured. */



More information about the dovecot-cvs mailing list