c00c7161dbec6be950ca3596969d0a3019bb281bTimo Sirainen#ifndef ISTREAM_SIZED_H
c00c7161dbec6be950ca3596969d0a3019bb281bTimo Sirainen#define ISTREAM_SIZED_H
c00c7161dbec6be950ca3596969d0a3019bb281bTimo Sirainen
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainenstruct istream_sized_error_data {
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen /* Stream's current v_offset */
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen uoff_t v_offset;
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen /* How many more bytes are being added within this read() */
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen size_t new_bytes;
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen /* What's the original wanted size. */
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen uoff_t wanted_size;
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen /* TRUE if we're at EOF now */
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen bool eof;
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen};
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainentypedef const char *
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainenistream_sized_callback_t(const struct istream_sized_error_data *data,
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen void *context);
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen
574d36db88f15662529fb65da6fc8c5e4c8f12faTimo Sirainen/* Assume that input stream is exactly the given size. If the stream is too
574d36db88f15662529fb65da6fc8c5e4c8f12faTimo Sirainen small, fail with stream_errno=EPIPE. If stream is too large, fail with
574d36db88f15662529fb65da6fc8c5e4c8f12faTimo Sirainen stream_errno=EINVAL. */
c00c7161dbec6be950ca3596969d0a3019bb281bTimo Sirainenstruct istream *i_stream_create_sized(struct istream *input, uoff_t size);
c3c423426093ffc01fa9967573a9b9e39f42c461Timo Sirainenstruct istream *i_stream_create_sized_range(struct istream *input,
c3c423426093ffc01fa9967573a9b9e39f42c461Timo Sirainen uoff_t offset, uoff_t size);
422df9158f9e3a2d21060f0fee2a9588e925f20eTimo Sirainen/* Like i_stream_create_sized*(), but allow input stream's size to be larger. */
422df9158f9e3a2d21060f0fee2a9588e925f20eTimo Sirainenstruct istream *i_stream_create_min_sized(struct istream *input, uoff_t min_size);
422df9158f9e3a2d21060f0fee2a9588e925f20eTimo Sirainenstruct istream *i_stream_create_min_sized_range(struct istream *input,
422df9158f9e3a2d21060f0fee2a9588e925f20eTimo Sirainen uoff_t offset, uoff_t min_size);
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen/* Same as i_stream_create_sized(), but set the error message via the
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen callback. */
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainenstruct istream *
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Siraineni_stream_create_sized_with_callback(struct istream *input, uoff_t size,
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen istream_sized_callback_t *error_callback,
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen void *context);
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen#define i_stream_create_sized_with_callback(input, size, error_callback, context) \
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen i_stream_create_sized_with_callback(input, size + \
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen CALLBACK_TYPECHECK(error_callback, \
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen const char *(*)(const struct istream_sized_error_data *, typeof(context))), \
8e7ea029100177d5f4077d4062f18998ca5a1e27Timo Sirainen (istream_sized_callback_t *)error_callback, context)
c00c7161dbec6be950ca3596969d0a3019bb281bTimo Sirainen
c00c7161dbec6be950ca3596969d0a3019bb281bTimo Sirainen#endif