]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added o_stream_create_buffer() for having output stream write to a buffer.
authorTimo Sirainen <tss@iki.fi>
Tue, 30 Jun 2009 01:57:54 +0000 (21:57 -0400)
committerTimo Sirainen <tss@iki.fi>
Tue, 30 Jun 2009 01:57:54 +0000 (21:57 -0400)
--HG--
branch : HEAD

src/lib/Makefile.am
src/lib/ostream-buffer.c [new file with mode: 0644]
src/lib/ostream.h

index 9e0655d084c2a6cfd24be9381d1ce21c48283b84..239b13e2c2249e55fdd00af76ee656e12749b105 100644 (file)
@@ -80,6 +80,7 @@ liblib_la_SOURCES = \
        nfs-workarounds.c \
        ostream.c \
        ostream-file.c \
+       ostream-buffer.c \
        primes.c \
        printf-format-fix.c \
        process-title.c \
diff --git a/src/lib/ostream-buffer.c b/src/lib/ostream-buffer.c
new file mode 100644 (file)
index 0000000..17572b6
--- /dev/null
@@ -0,0 +1,108 @@
+/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "buffer.h"
+#include "ostream-internal.h"
+
+struct buffer_ostream {
+       struct ostream_private ostream;
+       buffer_t *buf;
+       size_t max_buffer_size;
+};
+
+static void
+o_stream_buffer_set_max_buffer_size(struct iostream_private *stream,
+                                size_t max_size)
+{
+       struct buffer_ostream *bstream = (struct buffer_ostream *)stream;
+
+       bstream->max_buffer_size = max_size;
+}
+
+static void o_stream_buffer_cork(struct ostream_private *stream ATTR_UNUSED,
+                                bool set ATTR_UNUSED)
+{
+}
+
+static int o_stream_buffer_flush(struct ostream_private *stream ATTR_UNUSED)
+{
+       return 1;
+}
+
+static void
+o_stream_buffer_flush_pending(struct ostream_private *stream ATTR_UNUSED,
+                             bool set ATTR_UNUSED)
+{
+}
+
+static size_t
+o_stream_buffer_get_used_size(const struct ostream_private *stream ATTR_UNUSED)
+{
+       return 0;
+}
+
+static int o_stream_buffer_seek(struct ostream_private *stream, uoff_t offset)
+{
+       stream->ostream.offset = offset;
+       return 1;
+}
+
+static int
+o_stream_buffer_write_at(struct ostream_private *stream,
+                        const void *data, size_t size, uoff_t offset)
+{
+       struct buffer_ostream *bstream = (struct buffer_ostream *)stream;
+
+       buffer_write(bstream->buf, offset, data, size);
+       return 0;
+}
+
+static ssize_t
+o_stream_buffer_sendv(struct ostream_private *stream,
+                     const struct const_iovec *iov, unsigned int iov_count)
+{
+       struct buffer_ostream *bstream = (struct buffer_ostream *)stream;
+       size_t left, n;
+       ssize_t ret = 0;
+       unsigned int i;
+
+       for (i = 0; i < iov_count; i++) {
+               left = bstream->max_buffer_size - stream->ostream.offset;
+               n = I_MIN(left, iov[i].iov_len);
+               buffer_write(bstream->buf, stream->ostream.offset,
+                            iov[i].iov_base, iov[i].iov_len);
+               ret += n;
+               if (n != iov[i].iov_len)
+                       break;
+       }
+       stream->ostream.offset += ret;
+       return ret;
+}
+
+static off_t o_stream_buffer_send_istream(struct ostream_private *outstream,
+                                         struct istream *instream)
+{
+       return io_stream_copy(&outstream->ostream, instream, 1024);
+}
+
+struct ostream *o_stream_create_buffer(buffer_t *buf)
+{
+       struct buffer_ostream *bstream;
+
+       bstream = i_new(struct buffer_ostream, 1);
+       bstream->ostream.iostream.set_max_buffer_size =
+               o_stream_buffer_set_max_buffer_size;
+
+       bstream->ostream.cork = o_stream_buffer_cork;
+       bstream->ostream.flush = o_stream_buffer_flush;
+       bstream->ostream.flush_pending = o_stream_buffer_flush_pending;
+       bstream->ostream.get_used_size = o_stream_buffer_get_used_size;
+       bstream->ostream.seek = o_stream_buffer_seek;
+       bstream->ostream.sendv = o_stream_buffer_sendv;
+       bstream->ostream.write_at = o_stream_buffer_write_at;
+       bstream->ostream.send_istream = o_stream_buffer_send_istream;
+
+       bstream->buf = buf;
+       bstream->max_buffer_size = (size_t)-1;
+       return o_stream_create(&bstream->ostream);
+}
index 93de8f64bd1efb2a524c442c60ab8d67c17f3001..92b18c87c6619bc22f467f1176f9a9c49b98e578 100644 (file)
@@ -34,6 +34,8 @@ o_stream_create_fd(int fd, size_t max_buffer_size, bool autoclose_fd);
    If offset==(uoff_t)-1, the current offset isn't known. */
 struct ostream *
 o_stream_create_fd_file(int fd, uoff_t offset, bool autoclose_fd);
+/* Create an output stream to a buffer. */
+struct ostream *o_stream_create_buffer(buffer_t *buf);
 
 /* o_stream_close() + o_stream_unref() */
 void o_stream_destroy(struct ostream **stream);