istream.h revision a3c197999dfe2b0c8ea38cb77cfa5e95026005c0
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch#ifndef ISTREAM_H
42826d96c8d0bba9eddc85b01bf70d7db571ae7fPhil Carmody#define ISTREAM_H
42826d96c8d0bba9eddc85b01bf70d7db571ae7fPhil Carmody
42826d96c8d0bba9eddc85b01bf70d7db571ae7fPhil Carmody/* Note that some systems (Solaris) may use a macro to redefine struct stat */
42826d96c8d0bba9eddc85b01bf70d7db571ae7fPhil Carmody#include <sys/stat.h>
42826d96c8d0bba9eddc85b01bf70d7db571ae7fPhil Carmody
42826d96c8d0bba9eddc85b01bf70d7db571ae7fPhil Carmodystruct istream {
42826d96c8d0bba9eddc85b01bf70d7db571ae7fPhil Carmody uoff_t v_offset;
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody int stream_errno;
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody unsigned int mmaped:1; /* be careful when copying data */
87b4215acbf020aa5b8dea686b23fc664140cda0Stephan Bosch unsigned int blocking:1; /* read() shouldn't return 0 */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody unsigned int closed:1;
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody unsigned int seekable:1; /* we can seek() backwards */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody unsigned int eof:1; /* read() has reached to end of file
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody (but may still be data available in buffer) */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody struct istream_private *real_stream;
87b4215acbf020aa5b8dea686b23fc664140cda0Stephan Bosch};
87b4215acbf020aa5b8dea686b23fc664140cda0Stephan Bosch
87b4215acbf020aa5b8dea686b23fc664140cda0Stephan Boschtypedef void istream_callback_t(void *context);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodystruct istream *i_stream_create_fd(int fd, size_t max_buffer_size,
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody bool autoclose_fd);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodystruct istream *i_stream_create_mmap(int fd, size_t block_size,
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody uoff_t start_offset, uoff_t v_size,
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody bool autoclose_fd);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodystruct istream *i_stream_create_from_data(const void *data, size_t size);
191153d1a5b0eb0c129139570e3aa5212f28d2acJosef 'Jeff' Sipekstruct istream *i_stream_create_limit(struct istream *input, uoff_t v_size);
62461eb609e1d852e027cf4e07d30d51288678a2Aki Tuomi
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* i_stream_close() + i_stream_unref() */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_destroy(struct istream **stream);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Reference counting. References start from 1, so calling i_stream_unref()
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody destroys the stream if i_stream_ref() is never used. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_ref(struct istream *stream);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Unreferences the stream and sets stream pointer to NULL. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_unref(struct istream **stream);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Call the given callback function when stream is destroyed. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_set_destroy_callback(struct istream *stream,
191153d1a5b0eb0c129139570e3aa5212f28d2acJosef 'Jeff' Sipek istream_callback_t *callback, void *context);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody#define i_stream_set_destroy_callback(stream, callback, context) \
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody CONTEXT_CALLBACK(i_stream_set_destroy_callback, istream_callback_t, \
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody callback, context, stream)
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Return file descriptor for stream, or -1 if none is available. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyint i_stream_get_fd(struct istream *stream);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Mark the stream closed. Any reads after this will return -1. The data
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody already read can still be used. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_close(struct istream *stream);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Sync the stream with the underlying backend, ie. if a file has been
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody modified, flush any cached data. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_sync(struct istream *stream);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Change the maximum size for stream's input buffer to grow. Useful only
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody for buffered streams (currently only file). */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Enable/disable i_stream[_read]_next_line() returning the last line if it
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody doesn't end with LF. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_set_return_partial_line(struct istream *stream, bool set);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Returns number of bytes read if read was ok, -1 if EOF or error, -2 if the
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody input buffer is full. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyssize_t i_stream_read(struct istream *stream);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Skip forward a number of bytes. Never fails, the next read tells if it
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody was successful. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_skip(struct istream *stream, uoff_t count);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Seek to specified position from beginning of file. Never fails, the next
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody read tells if it was successful. This works only for files. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_seek(struct istream *stream, uoff_t v_offset);
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody/* Like i_stream_seek(), but also giving a hint that after reading some data
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody we could be seeking back to this mark or somewhere after it. If input
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody stream's implementation is slow in seeking backwards, it can use this hint
d6bbf85809664a810726b5c711c7213874d8df57Phil Carmody to cache some of the data in memory. */
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmodyvoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset);
d6bbf85809664a810726b5c711c7213874d8df57Phil Carmody/* Returns struct stat, or NULL if error. As the underlying stream may not be
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody a file, only some of the fields might be set, others would be zero.
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody st_size is always set, and if it's not known, it's -1.
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody
629e96c5e2d4724b713ca7d62e59ed033107edcdPhil Carmody If exact=FALSE, the stream may not return exactly correct values, but the
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch returned values can be compared to see if anything had changed (eg. in
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch compressed stream st_size could be compressed size) */
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschconst struct stat *i_stream_stat(struct istream *stream, bool exact);
87b4215acbf020aa5b8dea686b23fc664140cda0Stephan Bosch/* Similar to i_stream_stat() call. Returns 1 if size was successfully
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch set, 0 if size is unknown, -1 if error. */
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschint i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r);
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch/* Returns TRUE if there are any bytes left to be read or in buffer. */
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschbool i_stream_have_bytes_left(const struct istream *stream) ATTR_PURE;
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch/* Returns TRUE if there are no bytes buffered and read() returns EOF. */
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschbool i_stream_is_eof(struct istream *stream);
87b4215acbf020aa5b8dea686b23fc664140cda0Stephan Bosch
87b4215acbf020aa5b8dea686b23fc664140cda0Stephan Bosch/* Gets the next line from stream and returns it, or NULL if more data is
87b4215acbf020aa5b8dea686b23fc664140cda0Stephan Bosch needed to make a full line. i_stream_set_return_partial_line() specifies
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch if the last line should be returned if it doesn't end with LF. */
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschchar *i_stream_next_line(struct istream *stream);
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch/* Like i_stream_next_line(), but reads for more data if needed. Returns NULL
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch if more data is needed or error occurred. */
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschchar *i_stream_read_next_line(struct istream *stream);
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch/* Returns pointer to beginning of read data, or NULL if there's no data
191153d1a5b0eb0c129139570e3aa5212f28d2acJosef 'Jeff' Sipek buffered. */
62461eb609e1d852e027cf4e07d30d51288678a2Aki Tuomiconst unsigned char *
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschi_stream_get_data(const struct istream *stream, size_t *size_r);
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch/* Like i_stream_get_data(), but returns non-const data. This only works with
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch buffered streams (currently only file), others return NULL. */
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschunsigned char *i_stream_get_modifiable_data(const struct istream *stream,
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch size_t *size_r);
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch/* Like i_stream_get_data(), but read more when needed. Returns 1 if more
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch than threshold bytes are available, 0 if as much or less, -1 if error or
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch EOF with no bytes read that weren't already in buffer, or -2 if stream's
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch input buffer is full. */
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschint i_stream_read_data(struct istream *stream, const unsigned char **data_r,
191153d1a5b0eb0c129139570e3aa5212f28d2acJosef 'Jeff' Sipek size_t *size_r, size_t threshold);
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch/* Append external data to input stream. Returns TRUE if successful, FALSE if
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch there is not enough space in the stream. */
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Boschbool i_stream_add_data(struct istream *stream, const unsigned char *data,
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch size_t size);
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch#endif
4a272f5b8bacf2852c2e53f3aa8e899e0d5c604fStephan Bosch