]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added i_stream_set_return_partial_line().
authorTimo Sirainen <tss@iki.fi>
Wed, 19 Nov 2008 14:28:22 +0000 (16:28 +0200)
committerTimo Sirainen <tss@iki.fi>
Wed, 19 Nov 2008 14:28:22 +0000 (16:28 +0200)
--HG--
branch : HEAD

src/lib/istream-internal.h
src/lib/istream.c
src/lib/istream.h

index f6b702a0105a51f7f0939c139f5b287eb794a30a..e075debc81d0354852bfc0539b2f311883a41b4a 100644 (file)
@@ -34,6 +34,7 @@ struct istream_private {
        uoff_t parent_start_offset;
 
        string_t *line_str; /* for i_stream_next_line() if w_buffer == NULL */
+       unsigned int return_nolf_line:1;
 };
 
 struct istream *
index fc88c9515b9c7c0593eed34e050422e866eaf94d..88f18161734ec5d5b31ec91b04808ad56bfc78b0 100644 (file)
@@ -59,6 +59,11 @@ void i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
        io_stream_set_max_buffer_size(&stream->real_stream->iostream, max_size);
 }
 
+void i_stream_set_return_partial_line(struct istream *stream, bool set)
+{
+       stream->real_stream->return_nolf_line = set;
+}
+
 ssize_t i_stream_read(struct istream *stream)
 {
        struct istream_private *_stream = stream->real_stream;
@@ -213,12 +218,23 @@ static char *i_stream_next_line_finish(struct istream_private *stream, size_t i)
                ret = str_c_modifiable(stream->line_str);
        }
 
-       i++;
+       if (i < stream->pos)
+               i++;
        stream->istream.v_offset += i - stream->skip;
        stream->skip = i;
        return ret;
 }
 
+static char *i_stream_last_line(struct istream_private *_stream)
+{
+       if (_stream->istream.eof && _stream->skip != _stream->pos &&
+           _stream->return_nolf_line) {
+               /* the last line is missing LF and we want to return it. */
+               return i_stream_next_line_finish(_stream, _stream->pos);
+       }
+       return NULL;
+}
+
 char *i_stream_next_line(struct istream *stream)
 {
        struct istream_private *_stream = stream->real_stream;
@@ -244,7 +260,8 @@ char *i_stream_next_line(struct istream *stream)
                         break;
                }
        }
-
+       if (ret_buf == NULL)
+               return i_stream_last_line(_stream);
         return ret_buf;
 }
 
@@ -258,7 +275,7 @@ char *i_stream_read_next_line(struct istream *stream)
                        break;
 
                if (i_stream_read(stream) <= 0)
-                       return NULL;
+                       return i_stream_last_line(stream->real_stream);
        }
        return line;
 }
index ad24d717937669ec625c1f7a9f0a3e73e34df6d9..a48de15fbaa5f315fbb02262f7b284b728403683 100644 (file)
@@ -56,6 +56,9 @@ void i_stream_sync(struct istream *stream);
 /* Change the maximum size for stream's input buffer to grow. Useful only
    for buffered streams (currently only file). */
 void i_stream_set_max_buffer_size(struct istream *stream, size_t max_size);
+/* Enable/disable i_stream[_read]_next_line() returning the last line if it
+   doesn't end with LF. */
+void i_stream_set_return_partial_line(struct istream *stream, bool set);
 
 /* Returns number of bytes read if read was ok, -1 if EOF or error, -2 if the
    input buffer is full. */
@@ -83,8 +86,8 @@ const struct stat *i_stream_stat(struct istream *stream, bool exact);
 bool i_stream_have_bytes_left(const struct istream *stream) ATTR_PURE;
 
 /* Gets the next line from stream and returns it, or NULL if more data is
-   needed to make a full line. Note that if the stream ends with LF not being
-   the last character, this function doesn't return the last line. */
+   needed to make a full line. i_stream_set_return_partial_line() specifies
+   if the last line should be returned if it doesn't end with LF. */
 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 occurred. */