istream.h revision 8cb72c59d5ea4e9e5f638d7ec840bb853f5a188e
cd42ecd5cbd64e407587501c05dd61b5b1bc9312henning mueller#ifndef ISTREAM_H
cd42ecd5cbd64e407587501c05dd61b5b1bc9312henning mueller#define ISTREAM_H
cd42ecd5cbd64e407587501c05dd61b5b1bc9312henning mueller
de160fb36970379c8f040ade8e6632ca523568fcTim Reddehase/* Note that some systems (Solaris) may use a macro to redefine struct stat */
d95c0de1fbdb66e2aa8d2dc223ad554413f1dc87Julian Kornberger#include <sys/stat.h>
cd42ecd5cbd64e407587501c05dd61b5b1bc9312henning mueller
1fbac1c9a1dc459fd48aad78517f7e86b926ed12henning muellerstruct istream {
129482c3c1de71f942d53c8984308ed027ef45a6Tim Reddehase uoff_t v_offset;
129482c3c1de71f942d53c8984308ed027ef45a6Tim Reddehase
0d60d98adc26547b1ea641f3647b5015a083b449Sascha Graef int stream_errno;
d95c0de1fbdb66e2aa8d2dc223ad554413f1dc87Julian Kornberger unsigned int mmaped:1; /* be careful when copying data */
d95c0de1fbdb66e2aa8d2dc223ad554413f1dc87Julian Kornberger unsigned int blocking:1; /* read() shouldn't return 0 */
fec6c065c3b54a321f1170fc10fd12f248987ecdTim Reddehase unsigned int closed:1;
3e7a51349781a4cf69b876a1488db647bb62a63dTill Mossakowski unsigned int readable_fd:1; /* fd can be read directly if necessary
d95c0de1fbdb66e2aa8d2dc223ad554413f1dc87Julian Kornberger (for sendfile()) */
129482c3c1de71f942d53c8984308ed027ef45a6Tim Reddehase unsigned int seekable:1; /* we can seek() backwards */
129482c3c1de71f942d53c8984308ed027ef45a6Tim Reddehase unsigned int eof:1; /* read() has reached to end of file
129482c3c1de71f942d53c8984308ed027ef45a6Tim Reddehase (but may still be data available in buffer) */
842258c569e730af9f84f71f41c9351e51ce2bf4Tim Reddehase
842258c569e730af9f84f71f41c9351e51ce2bf4Tim Reddehase struct istream_private *real_stream;
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase};
cf778c11532841285b0b40421eaea8874eaa933aSascha Graef
cd42ecd5cbd64e407587501c05dd61b5b1bc9312henning muellertypedef void istream_callback_t(void *context);
d95c0de1fbdb66e2aa8d2dc223ad554413f1dc87Julian Kornberger
d95c0de1fbdb66e2aa8d2dc223ad554413f1dc87Julian Kornbergerstruct istream *i_stream_create_fd(int fd, size_t max_buffer_size,
129482c3c1de71f942d53c8984308ed027ef45a6Tim Reddehase bool autoclose_fd);
d95c0de1fbdb66e2aa8d2dc223ad554413f1dc87Julian Kornbergerstruct istream *i_stream_create_mmap(int fd, size_t block_size,
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase uoff_t start_offset, uoff_t v_size,
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase bool autoclose_fd);
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehasestruct istream *i_stream_create_from_data(const void *data, size_t size);
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehasestruct istream *i_stream_create_limit(struct istream *input, uoff_t v_size);
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase/* Set name (e.g. path) for input stream. */
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehasevoid i_stream_set_name(struct istream *stream, const char *name);
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase/* Get input stream's name. If stream itself doesn't have a name,
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase it looks up further into stream's parents until one of them has a name.
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase Returns "" if stream has no name. */
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehaseconst char *i_stream_get_name(struct istream *stream);
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase/* i_stream_close() + i_stream_unref() */
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehasevoid i_stream_destroy(struct istream **stream);
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase/* Reference counting. References start from 1, so calling i_stream_unref()
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehase destroys the stream if i_stream_ref() is never used. */
f5f3752159348b4a4db39c6273f365c62940c1eaTim Reddehasevoid i_stream_ref(struct istream *stream);
d95c0de1fbdb66e2aa8d2dc223ad554413f1dc87Julian Kornberger/* Unreferences the stream and sets stream pointer to NULL. */
cf778c11532841285b0b40421eaea8874eaa933aSascha Graefvoid i_stream_unref(struct istream **stream);
46903e570300d4e6366e24f144c5239ece5794ecTim Reddehase/* Call the given callback function when stream is destroyed. */
129482c3c1de71f942d53c8984308ed027ef45a6Tim Reddehasevoid i_stream_set_destroy_callback(struct istream *stream,
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase istream_callback_t *callback, void *context);
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase#define i_stream_set_destroy_callback(stream, callback, context) \
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase CONTEXT_CALLBACK(i_stream_set_destroy_callback, istream_callback_t, \
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase callback, context, stream)
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase/* Return file descriptor for stream, or -1 if none is available. */
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehaseint i_stream_get_fd(struct istream *stream);
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase/* Mark the stream closed. Any reads after this will return -1. The data
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase already read can still be used. */
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehasevoid i_stream_close(struct istream *stream);
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase/* Sync the stream with the underlying backend, ie. if a file has been
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase modified, flush any cached data. */
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehasevoid i_stream_sync(struct istream *stream);
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase/* Change the initial size for stream's input buffer. This basically just
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase grows the read buffer size from the default. This function has no effect
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase unless it's called before reading anything. */
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehasevoid i_stream_set_init_buffer_size(struct istream *stream, size_t size);
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase/* Change the maximum size for stream's input buffer to grow. Useful only
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase for buffered streams (currently only file). */
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehasevoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size);
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase/* Enable/disable i_stream[_read]_next_line() returning the last line if it
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase doesn't end with LF. */
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehasevoid i_stream_set_return_partial_line(struct istream *stream, bool set);
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehase/* Returns number of bytes read if read was ok, -1 if EOF or error, -2 if the
842258c569e730af9f84f71f41c9351e51ce2bf4Tim Reddehase input buffer is full. */
0ad1f8df5ba7a67621a28416c2975ae1e9a65444Tim Reddehasessize_t i_stream_read(struct istream *stream);
cf778c11532841285b0b40421eaea8874eaa933aSascha Graef/* Skip forward a number of bytes. Never fails, the next read tells if it
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase was successful. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehasevoid i_stream_skip(struct istream *stream, uoff_t count);
0bf050fdca945107aecec84010098337432b64b2Daniel Couto Vale/* Seek to specified position from beginning of file. Never fails, the next
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase read tells if it was successful. This works only for files. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehasevoid i_stream_seek(struct istream *stream, uoff_t v_offset);
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase/* Like i_stream_seek(), but also giving a hint that after reading some data
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase we could be seeking back to this mark or somewhere after it. If input
d4976f5637741d0a065b4b362b84c93d2d29bbcfTim Reddehase stream's implementation is slow in seeking backwards, it can use this hint
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase to cache some of the data in memory. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehasevoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset);
0bf050fdca945107aecec84010098337432b64b2Daniel Couto Vale/* Returns struct stat, or NULL if error. As the underlying stream may not be
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase a file, only some of the fields might be set, others would be zero.
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase st_size is always set, and if it's not known, it's -1.
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase
a4bb89242d1588533a569bebac88adab9fe72268Eugen Kuksa If exact=FALSE, the stream may not return exactly correct values, but the
a4bb89242d1588533a569bebac88adab9fe72268Eugen Kuksa returned values can be compared to see if anything had changed (eg. in
a4bb89242d1588533a569bebac88adab9fe72268Eugen Kuksa compressed stream st_size could be compressed size) */
a4bb89242d1588533a569bebac88adab9fe72268Eugen Kuksaconst struct stat *i_stream_stat(struct istream *stream, bool exact);
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase/* Similar to i_stream_stat() call. Returns 1 if size was successfully
cf778c11532841285b0b40421eaea8874eaa933aSascha Graef set, 0 if size is unknown, -1 if error. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehaseint i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r);
de160fb36970379c8f040ade8e6632ca523568fcTim Reddehase/* Returns TRUE if there are any bytes left to be read or in buffer. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehasebool i_stream_have_bytes_left(const struct istream *stream) ATTR_PURE;
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase/* Returns TRUE if there are no bytes buffered and read() returns EOF. */
cf778c11532841285b0b40421eaea8874eaa933aSascha Graefbool i_stream_is_eof(struct istream *stream);
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase/* Gets the next line from stream and returns it, or NULL if more data is
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase needed to make a full line. i_stream_set_return_partial_line() specifies
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase if the last line should be returned if it doesn't end with LF. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehasechar *i_stream_next_line(struct istream *stream);
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase/* Like i_stream_next_line(), but reads for more data if needed. Returns NULL
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase if more data is needed or error occurred. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehasechar *i_stream_read_next_line(struct istream *stream);
cf778c11532841285b0b40421eaea8874eaa933aSascha Graef
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase/* Returns pointer to beginning of read data, or NULL if there's no data
cf778c11532841285b0b40421eaea8874eaa933aSascha Graef buffered. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehaseconst unsigned char *
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehasei_stream_get_data(const struct istream *stream, size_t *size_r);
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase/* Like i_stream_get_data(), but returns non-const data. This only works with
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase buffered streams (currently only file), others return NULL. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehaseunsigned char *i_stream_get_modifiable_data(const struct istream *stream,
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase size_t *size_r);
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase/* Like i_stream_get_data(), but read more when needed. Returns 1 if more
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase than threshold bytes are available, 0 if as much or less, -1 if error or
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase EOF with no bytes read that weren't already in buffer, or -2 if stream's
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase input buffer is full. */
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehaseint i_stream_read_data(struct istream *stream, const unsigned char **data_r,
f7c74520d710d8c20173819be1c678b9c9e7b3d0Tim Reddehase size_t *size_r, size_t threshold);
cf778c11532841285b0b40421eaea8874eaa933aSascha Graef
d95c0de1fbdb66e2aa8d2dc223ad554413f1dc87Julian Kornberger/* Append external data to input stream. Returns TRUE if successful, FALSE if
6ef37875f247fe11ed2d07014ad74711ee17321cEugen Kuksa there is not enough space in the stream. */
ea7054230471b826b94a8e665304c2af5d0cba16Daniel Couto Valebool i_stream_add_data(struct istream *stream, const unsigned char *data,
cca5fd1a61122bce84d08e3bd52e99c9a9363944Ingo Becker size_t size);
cca5fd1a61122bce84d08e3bd52e99c9a9363944Ingo Becker
ea7054230471b826b94a8e665304c2af5d0cba16Daniel Couto Vale#endif
a4bb89242d1588533a569bebac88adab9fe72268Eugen Kuksa