# HG changeset patch # User Stephan Bosch # Date 1470957856 -7200 # Node ID 9f7806638fa33c96ac9837aeb134d3f6409498ea # Parent d6124d30333cd5c37bc557e55d62b7eb29f5822d 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. diff -r d6124d30333c -r 9f7806638fa3 src/lib/istream-data.c --- 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; +} diff -r d6124d30333c -r 9f7806638fa3 src/lib/istream.h --- 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);