changeset 20640:9f7806638fa3

lib: Implemented i_stream_create_copy_from_data(). Unlike i_stream_create_from_data(), this function makes a copy of the provided data block. This way, the application does not need to worry about keeping it allocated for the lifetime of the stream. The copied data is allocated durably on the system pool and freed once the stream is destroyed.
author Stephan Bosch <stephan@rename-it.nl>
date Fri, 12 Aug 2016 01:24:16 +0200
parents d6124d30333c
children 5c0470a8b5a7
files src/lib/istream-data.c src/lib/istream.h
diffstat 2 files changed, 35 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/istream-data.c	Mon Jul 25 10:24:44 2016 +0300
+++ b/src/lib/istream-data.c	Fri Aug 12 01:24:16 2016 +0200
@@ -36,3 +36,27 @@
 	i_stream_set_name(&stream->istream, "(buffer)");
 	return &stream->istream;
 }
+
+static void i_stream_copied_data_free(void *data)
+{
+	i_free(data);
+}
+struct istream *
+i_stream_create_copy_from_data(const void *data, size_t size)
+{
+	struct istream *stream;
+	void *buffer;
+
+	if (size == 0) {
+		buffer = "";
+	} else {
+		buffer = i_malloc(size);
+		memcpy(buffer, data, size);
+	}
+	stream = i_stream_create_from_data(buffer, size);
+	if (size > 0) {
+		i_stream_add_destroy_callback
+			(stream, i_stream_copied_data_free, buffer);
+	}
+	return stream;
+}
--- a/src/lib/istream.h	Mon Jul 25 10:24:44 2016 +0300
+++ b/src/lib/istream.h	Fri Aug 12 01:24:16 2016 +0200
@@ -43,11 +43,22 @@
 struct istream *i_stream_create_mmap(int fd, size_t block_size,
 				     uoff_t start_offset, uoff_t v_size,
 				     bool autoclose_fd);
+/* Create an input stream using the provided data block. That data block must
+remain allocated during the full lifetime of the stream. */
 struct istream *i_stream_create_from_data(const void *data, size_t size);
 #define i_stream_create_from_buffer(buf) \
 	i_stream_create_from_data((buf)->data, (buf)->used)
 #define i_stream_create_from_string(str) \
 	i_stream_create_from_data(str_data(str), str_len(str))
+/* Create an input stream using a copy of the provided data block. The
+   provided data block may be freed at any time. The copy is freed when the
+   stream is destroyed. */
+struct istream *
+i_stream_create_copy_from_data(const void *data, size_t size);
+#define i_stream_create_copy_from_buffer(buf) \
+	i_stream_create_copy_from_data((buf)->data, (buf)->used)
+#define i_stream_create_copy_from_string(str) \
+	i_stream_create_copy_from_data(str_data(str), str_len(str))
 struct istream *i_stream_create_limit(struct istream *input, uoff_t v_size);
 struct istream *i_stream_create_range(struct istream *input,
 				      uoff_t v_offset, uoff_t v_size);