From de517631db5471a71c3ac38c7032e7fd3177697e Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Fri, 12 Aug 2016 01:24:16 +0200 Subject: [PATCH] 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. --- src/lib/istream-data.c | 24 ++++++++++++++++++++++++ src/lib/istream.h | 11 +++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/lib/istream-data.c b/src/lib/istream-data.c index 3eb611a0e6..08d7f73552 100644 --- a/src/lib/istream-data.c +++ b/src/lib/istream-data.c @@ -36,3 +36,27 @@ struct istream *i_stream_create_from_data(const void *data, size_t size) 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; +} diff --git a/src/lib/istream.h b/src/lib/istream.h index c8c3d57d9d..caaf8d8947 100644 --- a/src/lib/istream.h +++ b/src/lib/istream.h @@ -43,11 +43,22 @@ struct istream *i_stream_create_file(const char *path, size_t max_buffer_size); 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);