istream.h revision 6a170d6d781094bdc75f027b6456dde160fbde39
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#ifndef ISTREAM_H
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#define ISTREAM_H
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Note that some systems (Solaris) may use a macro to redefine struct stat */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#include <sys/stat.h>
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct istream {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen uoff_t v_offset;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* Commonly used errors:
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ENOENT - File/object doesn't exist.
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen EPIPE - Stream ended unexpectedly (or i_stream_close() was called).
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen ESPIPE - i_stream_seek() was used on a stream that can't be seeked.
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ENOBUFS - i_stream_read_next_line() was used for a too long line.
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen EIO - Internal error. Retrying may work, but it may also be
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen because of a misconfiguration.
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen EINVAL - Stream is corrupted.
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen If stream_errno != 0, eof==TRUE as well.
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen int stream_errno;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen bool mmaped:1; /* be careful when copying data */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen bool blocking:1; /* read() shouldn't return 0 */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen bool closed:1;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen bool readable_fd:1; /* fd can be read directly if necessary
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen (for sendfile()) */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen bool seekable:1; /* we can seek() backwards */
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen /* read() has reached to end of file (but there may still be data
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen available in buffer) or stream_errno != 0 */
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen bool eof:1;
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen struct istream_private *real_stream;
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen};
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainentypedef void istream_callback_t(void *context);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct istream *i_stream_create_fd(int fd, size_t max_buffer_size);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* The fd is set to -1 immediately to avoid accidentally closing it twice. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct istream *i_stream_create_fd_autoclose(int *fd, size_t max_buffer_size);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Open the given path only when something is actually tried to be read from
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen the stream. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct istream *i_stream_create_file(const char *path, size_t max_buffer_size);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct istream *i_stream_create_mmap(int fd, size_t block_size,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen uoff_t start_offset, uoff_t v_size,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen bool autoclose_fd);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Create an input stream using the provided data block. That data block must
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenremain allocated during the full lifetime of the stream. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct istream *i_stream_create_from_data(const void *data, size_t size);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#define i_stream_create_from_buffer(buf) \
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_stream_create_from_data((buf)->data, (buf)->used)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#define i_stream_create_from_string(str) \
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_stream_create_from_data(str_data(str), str_len(str))
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Create an input stream using a copy of the provided data block. The
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen provided data block may be freed at any time. The copy is freed when the
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen stream is destroyed. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstruct istream *
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Siraineni_stream_create_copy_from_data(const void *data, size_t size);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#define i_stream_create_copy_from_buffer(buf) \
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_stream_create_copy_from_data((buf)->data, (buf)->used)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#define i_stream_create_copy_from_string(str) \
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_stream_create_copy_from_data(str_data(str), str_len(str))
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstruct istream *i_stream_create_limit(struct istream *input, uoff_t v_size);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstruct istream *i_stream_create_range(struct istream *input,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen uoff_t v_offset, uoff_t v_size);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstruct istream *i_stream_create_error(int stream_errno);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstruct istream *
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Siraineni_stream_create_error_str(int stream_errno, const char *fmt, ...)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen ATTR_FORMAT(2, 3);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Set name (e.g. path) for input stream. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid i_stream_set_name(struct istream *stream, const char *name);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Get input stream's name. If stream itself doesn't have a name,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen it looks up further into stream's parents until one of them has a name.
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen Returns "" if stream has no name. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenconst char *i_stream_get_name(struct istream *stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Close this stream (but not its parents) and unreference it. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid i_stream_destroy(struct istream **stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Reference counting. References start from 1, so calling i_stream_unref()
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen destroys the stream if i_stream_ref() is never used. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid i_stream_ref(struct istream *stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Unreferences the stream and sets stream pointer to NULL. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid i_stream_unref(struct istream **stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Call the given callback function when stream is destroyed. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid i_stream_add_destroy_callback(struct istream *stream,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen istream_callback_t *callback, void *context)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ATTR_NULL(3);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen#define i_stream_add_destroy_callback(stream, callback, context) \
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen i_stream_add_destroy_callback(stream + \
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen (istream_callback_t *)callback, context)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Remove the destroy callback. */
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainenvoid i_stream_remove_destroy_callback(struct istream *stream,
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen void (*callback)());
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen/* Return file descriptor for stream, or -1 if none is available. */
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainenint i_stream_get_fd(struct istream *stream);
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen/* Returns error string for the last error. It also returns "EOF" in case there
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen is no error, but eof is set. Otherwise it returns "<no error>". */
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainenconst char *i_stream_get_error(struct istream *stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Returns human-readable reason for why istream was disconnected. This can be
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen called to log the error when i_stream_read() returns -1. If there's an error
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen the output is identical to i_stream_get_error(). */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenconst char *i_stream_get_disconnect_reason(struct istream *stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Mark the stream and all of its parent streams closed. Any reads after this
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen will return -1. The data already read can still be used. */
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainenvoid i_stream_close(struct istream *stream);
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen/* Sync the stream with the underlying backend, ie. if a file has been
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen modified, flush any cached data. */
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainenvoid i_stream_sync(struct istream *stream);
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen/* Change the initial size for stream's input buffer. This basically just
dce5a2719df4fc64a8762d2aa94ba98dcf9cd6feTimo Sirainen grows the read buffer size from the default. This function has no effect
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen unless it's called before reading anything. */
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainenvoid i_stream_set_init_buffer_size(struct istream *stream, size_t size);
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen/* Change the maximum size for stream's input buffer to grow. Useful only
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen for buffered streams (currently only file). This changes also all the
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen parent streams' max buffer size. */
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size);
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen/* Returns the current max. buffer size for the stream. This function also
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen goesthrough all of the parent streams and returns the highest seen max
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen buffer size. This is needed because some streams (e.g. istream-chain) change
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen their max buffer size dynamically. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainensize_t i_stream_get_max_buffer_size(struct istream *stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Enable/disable i_stream[_read]_next_line() returning the last line if it
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen doesn't end with LF. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid i_stream_set_return_partial_line(struct istream *stream, bool set);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Change whether buffers are allocated persistently (default=TRUE). When not,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen the memory usage is minimized by freeing the stream's buffers whenever they
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen become empty. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid i_stream_set_persistent_buffers(struct istream *stream, bool set);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Set the istream blocking or nonblocking, including its parent streams.
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen If any of the istreams have an fd, its O_NONBLOCK flag is changed. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid i_stream_set_blocking(struct istream *stream, bool blocking);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Returns number of bytes read if read was ok, -1 if EOF or error, -2 if the
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen input buffer is full. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenssize_t i_stream_read(struct istream *stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Skip forward a number of bytes. Never fails, the next read tells if it
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen was successful. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen/* Seek to specified position from beginning of file. Never fails, the next
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen read tells if it was successful. This works only for files, others will
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen set stream_errno=ESPIPE. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Like i_stream_seek(), but also giving a hint that after reading some data
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen we could be seeking back to this mark or somewhere after it. If input
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen stream's implementation is slow in seeking backwards, it can use this hint
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen to cache some of the data in memory. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Returns 0 if ok, -1 if error. As the underlying stream may not be
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen a file, only some of the fields might be set, others would be zero.
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen st_size is always set, and if it's not known, it's -1.
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen If exact=FALSE, the stream may not return exactly correct values, but the
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen returned values can be compared to see if anything had changed (eg. in
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen compressed stream st_size could be compressed size) */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenint i_stream_stat(struct istream *stream, bool exact, const struct stat **st_r);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Similar to i_stream_stat() call. Returns 1 if size was successfully
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen set, 0 if size is unknown, -1 if error. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenint i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Returns TRUE if there are any bytes left to be read or in buffer. */
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainenbool i_stream_have_bytes_left(struct istream *stream);
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen/* Returns TRUE if there are no bytes currently buffered and i_stream_read()
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen returns EOF/error. Usually it's enough to check for stream->eof instead of
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen calling this function. Note that if the stream isn't at EOF, this function
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen has now read data into the stream buffer. */
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainenbool i_stream_is_eof(struct istream *stream);
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen/* Returns the absolute offset of the stream. This is the stream's current
v_offset + the parent's absolute offset when the stream was created. */
uoff_t i_stream_get_absolute_offset(struct istream *stream);
/* Gets the next line from stream and returns it, or NULL if more data is
needed to make a full line. i_stream_set_return_partial_line() specifies
if the last line should be returned if it doesn't end with LF. */
char *i_stream_next_line(struct istream *stream);
/* Like i_stream_next_line(), but reads for more data if needed. Returns NULL
if more data is needed or error occurred. If the input buffer gets full,
stream_errno is set to ENOBUFS. */
char *i_stream_read_next_line(struct istream *stream);
/* Returns TRUE if the last line read with i_stream_next_line() ended with
CRLF (instead of LF). */
bool i_stream_last_line_crlf(struct istream *stream);
/* Returns pointer to beginning of read data. */
const unsigned char *i_stream_get_data(struct istream *stream, size_t *size_r);
size_t i_stream_get_data_size(struct istream *stream);
/* Like i_stream_get_data(), but returns non-const data. This only works with
buffered streams (currently only file), others return NULL. */
unsigned char *i_stream_get_modifiable_data(struct istream *stream,
size_t *size_r);
/* Like i_stream_get_data(), but read more when needed. Returns 1 if more
than threshold bytes are available, 0 if as much or less, -1 if error or
EOF with no bytes read that weren't already in buffer, or -2 if stream's
input buffer is full. */
int i_stream_read_data(struct istream *stream, const unsigned char **data_r,
size_t *size_r, size_t threshold);
/* Like i_stream_get_data(), but read more when needed. Returns 1 if at least
the wanted number of bytes are available, 0 if less, -1 if error or
EOF with no bytes read that weren't already in buffer, or -2 if stream's
input buffer is full. */
static inline int
i_stream_read_bytes(struct istream *stream, const unsigned char **data_r,
size_t *size_r, size_t wanted)
{
i_assert(wanted > 0);
return i_stream_read_data(stream, data_r, size_r, wanted - 1);
}
/* Short-hand for just requesting more data (i.e. even one byte) */
static inline int
i_stream_read_more(struct istream *stream, const unsigned char **data_r,
size_t *size_r)
{
return i_stream_read_bytes(stream, data_r, size_r, 1);
}
/* Append external data to input stream. Returns TRUE if successful, FALSE if
there is not enough space in the stream. */
bool i_stream_add_data(struct istream *stream, const unsigned char *data,
size_t size);
void i_stream_set_input_pending(struct istream *stream, bool pending);
/* If there are any I/O loop items associated with the stream, move all of
them to current_ioloop. */
void i_stream_switch_ioloop(struct istream *stream);
#endif