c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef ISTREAM_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define ISTREAM_H
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
49e358eebea107aad9919dcc4bd88cee8519ba2eTimo Sirainen/* Note that some systems (Solaris) may use a macro to redefine struct stat */
49e358eebea107aad9919dcc4bd88cee8519ba2eTimo Sirainen#include <sys/stat.h>
49e358eebea107aad9919dcc4bd88cee8519ba2eTimo Sirainen
038c2831447440bf0bef89b43dd0968afc298abcStephan Boschstruct ioloop;
038c2831447440bf0bef89b43dd0968afc298abcStephan Bosch
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenstruct istream {
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen uoff_t v_offset;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen /* Commonly used errors:
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen ENOENT - File/object doesn't exist.
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen EPIPE - Stream ended unexpectedly (or i_stream_close() was called).
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen ESPIPE - i_stream_seek() was used on a stream that can't be seeked.
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen ENOBUFS - i_stream_read_next_line() was used for a too long line.
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen EIO - Internal error. Retrying may work, but it may also be
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen because of a misconfiguration.
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen EINVAL - Stream is corrupted.
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen If stream_errno != 0, eof==TRUE as well.
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int stream_errno;
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool mmaped:1; /* be careful when copying data */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool blocking:1; /* read() shouldn't return 0 */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool closed:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool readable_fd:1; /* fd can be read directly if necessary
da2aa032ccfa8e7e4a4380ef738014549f4d2c2dTimo Sirainen (for sendfile()) */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool seekable:1; /* we can seek() backwards */
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen /* read() has reached to end of file (but there may still be data
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen available in buffer) or stream_errno != 0 */
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen bool eof:1;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct istream_private *real_stream;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainentypedef void istream_callback_t(void *context);
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvistruct istream *i_stream_create_fd(int fd, size_t max_buffer_size);
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainen/* The fd is set to -1 immediately to avoid accidentally closing it twice. */
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainenstruct istream *i_stream_create_fd_autoclose(int *fd, size_t max_buffer_size);
09801f106cd531a28b4e03ec665e44c421264560Timo Sirainen/* Open the given path only when something is actually tried to be read from
09801f106cd531a28b4e03ec665e44c421264560Timo Sirainen the stream. */
09801f106cd531a28b4e03ec665e44c421264560Timo Sirainenstruct istream *i_stream_create_file(const char *path, size_t max_buffer_size);
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainenstruct istream *i_stream_create_mmap(int fd, size_t block_size,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen uoff_t start_offset, uoff_t v_size,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen bool autoclose_fd);
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch/* Create an input stream using the provided data block. That data block must
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Boschremain allocated during the full lifetime of the stream. */
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainenstruct istream *i_stream_create_from_data(const void *data, size_t size);
212a34c06ff45952c008ae9eec387ced783de6cfPhil Carmody#define i_stream_create_from_buffer(buf) \
212a34c06ff45952c008ae9eec387ced783de6cfPhil Carmody i_stream_create_from_data((buf)->data, (buf)->used)
212a34c06ff45952c008ae9eec387ced783de6cfPhil Carmody#define i_stream_create_from_string(str) \
212a34c06ff45952c008ae9eec387ced783de6cfPhil Carmody i_stream_create_from_data(str_data(str), str_len(str))
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch/* Create an input stream using a copy of the provided data block. The
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch provided data block may be freed at any time. The copy is freed when the
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch stream is destroyed. */
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Boschstruct istream *
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Boschi_stream_create_copy_from_data(const void *data, size_t size);
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch#define i_stream_create_copy_from_buffer(buf) \
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch i_stream_create_copy_from_data((buf)->data, (buf)->used)
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch#define i_stream_create_copy_from_string(str) \
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch i_stream_create_copy_from_data(str_data(str), str_len(str))
10c96a244935de4add8213ba0b894178dfb889a5Timo Sirainenstruct istream *i_stream_create_limit(struct istream *input, uoff_t v_size);
bdcb00145ad87765e3fd22d4ebc4d2c029a326b9Timo Sirainenstruct istream *i_stream_create_range(struct istream *input,
bdcb00145ad87765e3fd22d4ebc4d2c029a326b9Timo Sirainen uoff_t v_offset, uoff_t v_size);
0c1835a90dd1dcedaeaedd1cd91672299cbeb5beTimo Sirainenstruct istream *i_stream_create_error(int stream_errno);
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Sirainenstruct istream *
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Siraineni_stream_create_error_str(int stream_errno, const char *fmt, ...)
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Sirainen ATTR_FORMAT(2, 3);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen/* Set name (e.g. path) for input stream. */
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenvoid i_stream_set_name(struct istream *stream, const char *name);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen/* Get input stream's name. If stream itself doesn't have a name,
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen it looks up further into stream's parents until one of them has a name.
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen Returns "" if stream has no name. */
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenconst char *i_stream_get_name(struct istream *stream);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen/* Close this stream (but not its parents) and unreference it. */
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainenvoid i_stream_destroy(struct istream **stream);
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Reference counting. References start from 1, so calling i_stream_unref()
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen destroys the stream if i_stream_ref() is never used. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid i_stream_ref(struct istream *stream);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen/* Unreferences the stream and sets stream pointer to NULL. */
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid i_stream_unref(struct istream **stream);
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen/* Call the given callback function when stream is destroyed. */
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainenvoid i_stream_add_destroy_callback(struct istream *stream,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen istream_callback_t *callback, void *context)
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen ATTR_NULL(3);
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen#define i_stream_add_destroy_callback(stream, callback, context) \
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen i_stream_add_destroy_callback(stream + \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen (istream_callback_t *)callback, context)
c28f6aa0b70af4811c9ace9114fe827c2f503455Timo Sirainen/* Remove the destroy callback. */
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainenvoid i_stream_remove_destroy_callback(struct istream *stream,
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen void (*callback)());
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Return file descriptor for stream, or -1 if none is available. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenint i_stream_get_fd(struct istream *stream);
46ce4d9273e6df12ef1912bbdb1c8b84b104f394Timo Sirainen/* Returns error string for the last error. It also returns "EOF" in case there
46ce4d9273e6df12ef1912bbdb1c8b84b104f394Timo Sirainen is no error, but eof is set. Otherwise it returns "<no error>". */
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainenconst char *i_stream_get_error(struct istream *stream);
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen/* Returns human-readable reason for why istream was disconnected. This can be
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen called to log the error when i_stream_read() returns -1. If there's an error
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen the output is identical to i_stream_get_error(). */
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainenconst char *i_stream_get_disconnect_reason(struct istream *stream);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen/* Mark the stream and all of its parent streams closed. Any reads after this
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen will return -1. The data already read can still be used. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid i_stream_close(struct istream *stream);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen/* Sync the stream with the underlying backend, ie. if a file has been
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen modified, flush any cached data. */
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainenvoid i_stream_sync(struct istream *stream);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen/* Change the initial size for stream's input buffer. This basically just
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen grows the read buffer size from the default. This function has no effect
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen unless it's called before reading anything. */
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainenvoid i_stream_set_init_buffer_size(struct istream *stream, size_t size);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Change the maximum size for stream's input buffer to grow. Useful only
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen for buffered streams (currently only file). This changes also all the
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen parent streams' max buffer size. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size);
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen/* Returns the current max. buffer size for the stream. This function also
19557f192d37cd54a1a090a8a26d9d47265e4413Aki Tuomi goes through all of the parent streams and returns the highest seen max
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen buffer size. This is needed because some streams (e.g. istream-chain) change
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen their max buffer size dynamically. */
0a49b316fc729e5d57268ffa63c7122ac73f994cTimo Sirainensize_t i_stream_get_max_buffer_size(struct istream *stream);
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen/* Enable/disable i_stream[_read]_next_line() returning the last line if it
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen doesn't end with LF. */
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainenvoid i_stream_set_return_partial_line(struct istream *stream, bool set);
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen/* Change whether buffers are allocated persistently (default=TRUE). When not,
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen the memory usage is minimized by freeing the stream's buffers whenever they
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen become empty. */
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainenvoid i_stream_set_persistent_buffers(struct istream *stream, bool set);
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen/* Set the istream blocking or nonblocking, including its parent streams.
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen If any of the istreams have an fd, its O_NONBLOCK flag is changed. */
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainenvoid i_stream_set_blocking(struct istream *stream, bool blocking);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen/* Returns number of bytes read if read was ok, 0 if stream is non-blocking and
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen no more data is available, -1 if EOF or error, -2 if the input buffer is
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen full. If <=0 is returned, pointers to existing data returned by the previous
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen i_stream_get_data() will stay valid, although calling it again may return
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen a different pointer. The pointers to old data are invalidated again when
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen return value is >0. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenssize_t i_stream_read(struct istream *stream);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Skip forward a number of bytes. Never fails, the next read tells if it
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen was successful. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Seek to specified position from beginning of file. Never fails, the next
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen read tells if it was successful. This works only for files, others will
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen set stream_errno=ESPIPE. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset);
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen/* Like i_stream_seek(), but also giving a hint that after reading some data
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen we could be seeking back to this mark or somewhere after it. If input
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen stream's implementation is slow in seeking backwards, it can use this hint
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen to cache some of the data in memory. */
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainenvoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset);
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen/* Returns 0 if ok, -1 if error. As the underlying stream may not be
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen a file, only some of the fields might be set, others would be zero.
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen st_size is always set, and if it's not known, it's -1.
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen If exact=FALSE, the stream may not return exactly correct values, but the
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen returned values can be compared to see if anything had changed (eg. in
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen compressed stream st_size could be compressed size) */
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainenint i_stream_stat(struct istream *stream, bool exact, const struct stat **st_r);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen/* Similar to i_stream_stat() call. Returns 1 if size was successfully
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen set, 0 if size is unknown, -1 if error. */
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainenint i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r);
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen/* Returns TRUE if there are any bytes left to be read or in buffer. */
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainenbool i_stream_have_bytes_left(struct istream *stream);
6a170d6d781094bdc75f027b6456dde160fbde39Timo Sirainen/* Returns TRUE if there are no bytes currently buffered and i_stream_read()
6a170d6d781094bdc75f027b6456dde160fbde39Timo Sirainen returns EOF/error. Usually it's enough to check for stream->eof instead of
6a170d6d781094bdc75f027b6456dde160fbde39Timo Sirainen calling this function. Note that if the stream isn't at EOF, this function
6a170d6d781094bdc75f027b6456dde160fbde39Timo Sirainen has now read data into the stream buffer. */
1bc075e2e4ed422f9590c95c3ae223422b97ce6aTimo Sirainenbool i_stream_read_eof(struct istream *stream);
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainen/* Returns the absolute offset of the stream. This is the stream's current
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainen v_offset + the parent's absolute offset when the stream was created. */
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainenuoff_t i_stream_get_absolute_offset(struct istream *stream);
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen/* Gets the next line from stream and returns it, or NULL if more data is
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen needed to make a full line. i_stream_set_return_partial_line() specifies
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen if the last line should be returned if it doesn't end with LF. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenchar *i_stream_next_line(struct istream *stream);
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen/* Like i_stream_next_line(), but reads for more data if needed. Returns NULL
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen if more data is needed or error occurred. If the input buffer gets full,
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen stream_errno is set to ENOBUFS. */
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainenchar *i_stream_read_next_line(struct istream *stream);
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen/* Returns TRUE if the last line read with i_stream_next_line() ended with
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen CRLF (instead of LF). */
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainenbool i_stream_last_line_crlf(struct istream *stream);
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen
6657aee0bb6c603b4ee5111388b93c1a8a9ad680Martti Rannanjärvi/* Returns pointer to beginning of read data. */
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainenconst unsigned char *i_stream_get_data(struct istream *stream, size_t *size_r);
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainensize_t i_stream_get_data_size(struct istream *stream);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Like i_stream_get_data(), but returns non-const data. This only works with
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen buffered streams (currently only file), others return NULL. */
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainenunsigned char *i_stream_get_modifiable_data(struct istream *stream,
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen size_t *size_r);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Like i_stream_get_data(), but read more when needed. Returns 1 if more
699fdc186f982f70d990820796eaa0f12133e27cTimo Sirainen than threshold bytes are available, 0 if as much or less, -1 if error or
699fdc186f982f70d990820796eaa0f12133e27cTimo Sirainen EOF with no bytes read that weren't already in buffer, or -2 if stream's
699fdc186f982f70d990820796eaa0f12133e27cTimo Sirainen input buffer is full. */
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data_r,
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen size_t *size_r, size_t threshold);
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody/* Like i_stream_get_data(), but read more when needed. Returns 1 if at least
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody the wanted number of bytes are available, 0 if less, -1 if error or
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody EOF with no bytes read that weren't already in buffer, or -2 if stream's
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody input buffer is full. */
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmodystatic inline int
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmodyi_stream_read_bytes(struct istream *stream, const unsigned char **data_r,
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody size_t *size_r, size_t wanted)
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody{
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody i_assert(wanted > 0);
573424407a2d3c1453638a643583a7cf10c129e1Phil Carmody return i_stream_read_data(stream, data_r, size_r, wanted - 1);
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody}
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody/* Short-hand for just requesting more data (i.e. even one byte) */
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmodystatic inline int
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmodyi_stream_read_more(struct istream *stream, const unsigned char **data_r,
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody size_t *size_r)
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody{
50977ed6891faabe013ffd1905667b91261c3eb9Timo Sirainen int ret = i_stream_read_bytes(stream, data_r, size_r, 1);
50977ed6891faabe013ffd1905667b91261c3eb9Timo Sirainen i_assert(ret != -2); /* stream must have space for at least 1 byte */
50977ed6891faabe013ffd1905667b91261c3eb9Timo Sirainen return ret;
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody}
a215abacb2d2d1e1bcd475756aab809038ae4277Timo Sirainen/* Return the timestamp when istream last successfully read something.
a215abacb2d2d1e1bcd475756aab809038ae4277Timo Sirainen The timestamp is 0 if nothing has ever been read. */
a215abacb2d2d1e1bcd475756aab809038ae4277Timo Sirainenvoid i_stream_get_last_read_time(struct istream *stream, struct timeval *tv_r);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen/* Append external data to input stream. Returns TRUE if successful, FALSE if
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen there is not enough space in the stream. */
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainenbool i_stream_add_data(struct istream *stream, const unsigned char *data,
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen size_t size);
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainenvoid i_stream_set_input_pending(struct istream *stream, bool pending);
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen/* If there are any I/O loop items associated with the stream, move all of
038c2831447440bf0bef89b43dd0968afc298abcStephan Bosch them to provided/current ioloop. */
038c2831447440bf0bef89b43dd0968afc298abcStephan Boschvoid i_stream_switch_ioloop_to(struct istream *stream, struct ioloop *ioloop);
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainenvoid i_stream_switch_ioloop(struct istream *stream);
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#endif