istream.h revision f4735bf7ec2019fdc730e9ebdb39e5a4ea580405
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch#ifndef ISTREAM_H
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#define ISTREAM_H
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Note that some systems (Solaris) may use a macro to redefine struct stat */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#include <sys/stat.h>
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct istream {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uoff_t v_offset;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen int stream_errno;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int mmaped:1; /* be careful when copying data */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int blocking:1; /* read() shouldn't return 0 */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int closed:1;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int readable_fd:1; /* fd can be read directly if necessary
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (for sendfile()) */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int seekable:1; /* we can seek() backwards */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int eof:1; /* read() has reached to end of file
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen (but may still be data available in buffer) */
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen struct istream_private *real_stream;
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen};
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainen
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainentypedef void istream_callback_t(void *context);
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi
0a7b04ec6441fdcf083392888b2e30844fc3e86dTimo Sirainenstruct istream *i_stream_create_fd(int fd, size_t max_buffer_size,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen bool autoclose_fd);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Open the given path only when something is actually tried to be read from
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen the stream. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct istream *i_stream_create_file(const char *path, size_t max_buffer_size);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct istream *i_stream_create_mmap(int fd, size_t block_size,
df3963075d67f76ade66b6a74764f4eae31d9c87Josef 'Jeff' Sipek uoff_t start_offset, uoff_t v_size,
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainen bool autoclose_fd);
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainenstruct istream *i_stream_create_from_data(const void *data, size_t size);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct istream *i_stream_create_limit(struct istream *input, uoff_t v_size);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct istream *i_stream_create_range(struct istream *input,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uoff_t v_offset, uoff_t v_size);
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainenstruct istream *i_stream_create_error(int stream_errno);
fc40a9a002458e372ff4b9f6f4e15239520c0bcdTimo Sirainenstruct istream *
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Siraineni_stream_create_error_str(int stream_errno, const char *fmt, ...)
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen ATTR_FORMAT(2, 3);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Set name (e.g. path) for input stream. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid i_stream_set_name(struct istream *stream, const char *name);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Get input stream's name. If stream itself doesn't have a name,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen it looks up further into stream's parents until one of them has a name.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen Returns "" if stream has no name. */
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainenconst char *i_stream_get_name(struct istream *stream);
d665e2948cb6fe8016706752a9e4940d64f4a61dTimo Sirainen
4ca83616715c3bd417e34ced2c1d61852513e427Timo Sirainen/* Close this stream (but not its parents) and unreference it. */
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainenvoid i_stream_destroy(struct istream **stream);
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi/* Reference counting. References start from 1, so calling i_stream_unref()
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen destroys the stream if i_stream_ref() is never used. */
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainenvoid i_stream_ref(struct istream *stream);
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen/* Unreferences the stream and sets stream pointer to NULL. */
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainenvoid i_stream_unref(struct istream **stream);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Call the given callback function when stream is destroyed. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid i_stream_add_destroy_callback(struct istream *stream,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen istream_callback_t *callback, void *context)
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen ATTR_NULL(3);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen#define i_stream_add_destroy_callback(stream, callback, context) \
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen i_stream_add_destroy_callback(stream + \
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
df3963075d67f76ade66b6a74764f4eae31d9c87Josef 'Jeff' Sipek (istream_callback_t *)callback, context)
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek/* Remove the destroy callback. */
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainenvoid i_stream_remove_destroy_callback(struct istream *stream,
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen void (*callback)());
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen/* Return file descriptor for stream, or -1 if none is available. */
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainenint i_stream_get_fd(struct istream *stream);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen/* Returns error string for the last error. */
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainenconst char *i_stream_get_error(struct istream *stream);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen/* Mark the stream and all of its parent streams closed. Any reads after this
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen will return -1. The data already read can still be used. */
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainenvoid i_stream_close(struct istream *stream);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen/* Sync the stream with the underlying backend, ie. if a file has been
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen modified, flush any cached data. */
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainenvoid i_stream_sync(struct istream *stream);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen/* Change the initial size for stream's input buffer. This basically just
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen grows the read buffer size from the default. This function has no effect
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen unless it's called before reading anything. */
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainenvoid i_stream_set_init_buffer_size(struct istream *stream, size_t size);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen/* Change the maximum size for stream's input buffer to grow. Useful only
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen for buffered streams (currently only file). */
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen/* Returns the current max. buffer size. */
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainensize_t i_stream_get_max_buffer_size(struct istream *stream);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen/* Enable/disable i_stream[_read]_next_line() returning the last line if it
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen doesn't end with LF. */
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainenvoid i_stream_set_return_partial_line(struct istream *stream, bool set);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen/* Returns number of bytes read if read was ok, -1 if EOF or error, -2 if the
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen input buffer is full. */
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainenssize_t i_stream_read(struct istream *stream);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen/* Skip forward a number of bytes. Never fails, the next read tells if it
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen was successful. */
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen/* Seek to specified position from beginning of file. Never fails, the next
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen read tells if it was successful. This works only for files. */
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset);
03de962febfc2ac572f9e4029463c16d29c1ed55Timo Sirainen/* Like i_stream_seek(), but also giving a hint that after reading some data
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen we could be seeking back to this mark or somewhere after it. If input
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen stream's implementation is slow in seeking backwards, it can use this hint
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen to cache some of the data in memory. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Returns 0 if ok, -1 if error. As the underlying stream may not be
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen a file, only some of the fields might be set, others would be zero.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen st_size is always set, and if it's not known, it's -1.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen If exact=FALSE, the stream may not return exactly correct values, but the
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen returned values can be compared to see if anything had changed (eg. in
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen compressed stream st_size could be compressed size) */
7204b8112e005ff81dcf628f7880ef1feed1effeTimo Sirainenint i_stream_stat(struct istream *stream, bool exact, const struct stat **st_r);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Similar to i_stream_stat() call. Returns 1 if size was successfully
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen set, 0 if size is unknown, -1 if error. */
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainenint i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r);
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainen/* Returns TRUE if there are any bytes left to be read or in buffer. */
0fcfa7698e7beb78019ac89a869eef1b41e56a62Timo Sirainenbool i_stream_have_bytes_left(const struct istream *stream) ATTR_PURE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Returns TRUE if there are no bytes buffered and read() returns EOF. */
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainenbool i_stream_is_eof(struct istream *stream);
4ca83616715c3bd417e34ced2c1d61852513e427Timo Sirainen/* Returns the absolute offset of the stream. This is the stream's current
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen v_offset + the parent's absolute offset when the stream was created. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenuoff_t i_stream_get_absolute_offset(struct istream *stream);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Gets the next line from stream and returns it, or NULL if more data is
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen needed to make a full line. i_stream_set_return_partial_line() specifies
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if the last line should be returned if it doesn't end with LF. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenchar *i_stream_next_line(struct istream *stream);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Like i_stream_next_line(), but reads for more data if needed. Returns NULL
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if more data is needed or error occurred. If the input buffer gets full,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen stream_errno is set to ENOBUFS. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenchar *i_stream_read_next_line(struct istream *stream);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Returns TRUE if the last line read with i_stream_next_line() ended with
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen CRLF (instead of LF). */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenbool i_stream_last_line_crlf(struct istream *stream);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Returns pointer to beginning of read data, or NULL if there's no data
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen buffered. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenconst unsigned char *
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Siraineni_stream_get_data(const struct istream *stream, size_t *size_r);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainensize_t i_stream_get_data_size(const struct istream *stream);
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen/* Like i_stream_get_data(), but returns non-const data. This only works with
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen buffered streams (currently only file), others return NULL. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenunsigned char *i_stream_get_modifiable_data(const struct istream *stream,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen size_t *size_r);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Like i_stream_get_data(), but read more when needed. Returns 1 if more
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen than threshold bytes are available, 0 if as much or less, -1 if error or
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen EOF with no bytes read that weren't already in buffer, or -2 if stream's
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen input buffer is full. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data_r,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen size_t *size_r, size_t threshold);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Append external data to input stream. Returns TRUE if successful, FALSE if
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen there is not enough space in the stream. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenbool i_stream_add_data(struct istream *stream, const unsigned char *data,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen size_t size);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen#endif
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen