istream.c revision 6657aee0bb6c603b4ee5111388b93c1a8a9ad680
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* Copyright (c) 2002-2016 Dovecot authors, see the included COPYING file */
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainenstatic bool i_stream_is_buffer_invalid(const struct istream_private *stream);
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainenvoid i_stream_set_name(struct istream *stream, const char *name)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->real_stream->iostream.name = i_strdup(name);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenconst char *i_stream_get_name(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen while (stream->real_stream->iostream.name == NULL) {
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainenstatic void i_stream_close_full(struct istream *stream, bool close_parents)
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen io_stream_close(&stream->real_stream->iostream, close_parents);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen io_stream_ref(&stream->real_stream->iostream);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen struct istream_private *_stream = (*stream)->real_stream;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen if (!io_stream_unref(&(*stream)->real_stream->iostream)) {
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen i_stream_unref(&(*stream)->real_stream->parent);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen io_stream_free(&(*stream)->real_stream->iostream);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_add_destroy_callback(struct istream *stream,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen io_stream_add_destroy_callback(&stream->real_stream->iostream,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_remove_destroy_callback(struct istream *stream,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen io_stream_remove_destroy_callback(&stream->real_stream->iostream,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenconst char *i_stream_get_error(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* we'll only return errors for streams that have stream_errno set or
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen that have reached EOF. we might be returning unintended error
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen otherwise. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen for (s = stream; s != NULL; s = s->real_stream->parent) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenconst char *i_stream_get_disconnect_reason(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return io_stream_get_disconnect_reason(stream, NULL);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainenvoid i_stream_set_init_buffer_size(struct istream *stream, size_t size)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_set_max_buffer_size(struct istream *stream, size_t max_size)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen io_stream_set_max_buffer_size(&stream->real_stream->iostream, max_size);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainensize_t i_stream_get_max_buffer_size(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (max_size < stream->real_stream->max_buffer_size)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen max_size = stream->real_stream->max_buffer_size;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainenvoid i_stream_set_return_partial_line(struct istream *stream, bool set)
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainenvoid i_stream_set_persistent_buffers(struct istream *stream, bool set)
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen stream->real_stream->nonpersistent_buffers = !set;
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainenstatic void i_stream_update(struct istream_private *stream)
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen stream->parent_expected_offset = stream->parent->v_offset;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0)) {
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen i_stream_seek(_stream->parent, _stream->parent_expected_offset);
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen i_assert(old_size <= _stream->pos - _stream->skip);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* error handling should be easier if we now just
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen assume the stream is now at EOF */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen i_assert(old_size == _stream->pos - _stream->skip);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert((size_t)ret+old_size == _stream->pos - _stream->skip);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* error handling should be easier if we now just
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen assume the stream is now at EOF. Note that we could get here
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen even if read() didn't return -1, although that's a little
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen bit sloppy istream implementation. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* verify that parents' access_counters are valid. the parent's
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_stream_read() should guarantee this. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(!i_stream_is_buffer_invalid(_stream));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenssize_t i_stream_read_copy_from_parent(struct istream *istream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *stream = istream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->buffer = i_stream_get_data(stream->parent, &pos);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if ((ret = i_stream_read(stream->parent)) == -2) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->istream.stream_errno = stream->parent->stream_errno;
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen stream->buffer = i_stream_get_data(stream->parent, &pos);
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen /* check again, in case the parent stream had been seeked
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen backwards and the previous read() didn't get us far
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) :
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_skip(struct istream *stream, uoff_t count)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* within buffer */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* have to seek forward */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0))
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen _stream->seek(_stream, stream->v_offset + count, FALSE);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic bool i_stream_can_optimize_seek(struct istream_private *stream)
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen /* use the fast route only if the parent stream hasn't been changed */
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen return i_stream_can_optimize_seek(stream->parent->real_stream);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_seek(struct istream *stream, uoff_t v_offset)
47e9fdee55c2074425cf0316f4f64fbbb790301cTimo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_stream_skip(stream, v_offset - stream->v_offset);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid i_stream_seek_mark(struct istream *stream, uoff_t v_offset)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0))
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen struct istream_private *_stream = stream->real_stream;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint i_stream_stat(struct istream *stream, bool exact, const struct stat **st_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = stream->real_stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (unlikely(stream->closed || stream->stream_errno != 0))
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen return _stream->get_size(_stream, exact, size_r);
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainenbool i_stream_have_bytes_left(struct istream *stream)
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen return i_stream_get_data_size(stream) > 0 || !stream->eof;
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainenuoff_t i_stream_get_absolute_offset(struct istream *stream)
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen abs_offset += stream->real_stream->start_offset;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenstatic char *i_stream_next_line_finish(struct istream_private *stream, size_t i)
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen /* modify the buffer directly */
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen ret = (char *)stream->w_buffer + stream->skip;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen /* use a temporary string to return it */
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen stream->line_str = str_new(default_pool, 256);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen str_append_n(stream->line_str, stream->buffer + stream->skip,
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenstatic char *i_stream_last_line(struct istream_private *_stream)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (_stream->istream.eof && _stream->skip != _stream->pos &&
e0740628f6ca05f4bc79a9d8a90b650f4d38d4d0Timo Sirainen /* the last line is missing LF and we want to return it. */
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen return i_stream_next_line_finish(_stream, _stream->pos);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainenchar *i_stream_next_line(struct istream *stream)
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen struct istream_private *_stream = stream->real_stream;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen const unsigned char *pos;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen pos = memchr(_stream->buffer + _stream->skip, '\n',
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainenchar *i_stream_read_next_line(struct istream *stream)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen io_stream_set_error(&stream->real_stream->iostream,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen i_stream_get_data_size(stream), stream->v_offset);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return i_stream_last_line(stream->real_stream);
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainenbool i_stream_last_line_crlf(struct istream *stream)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstatic bool i_stream_is_buffer_invalid(const struct istream_private *stream)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* the buffer can't point to parent, because it doesn't exist */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* we can pretty safely assume that the stream is using its
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen own private buffer, so it can never become invalid. */
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen stream->parent->real_stream->access_counter) {
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen /* parent has been modified behind this stream, we can't trust
8f5b34c22e4c3bfb35ca13c4744867eb5ddbd3d6Timo Sirainen that our buffer is valid */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return i_stream_is_buffer_invalid(stream->parent->real_stream);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenconst unsigned char *
2eb0402a28bd0422e0170160808c67d6c7274689Timo Siraineni_stream_get_data(struct istream *stream, size_t *size_r)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct istream_private *_stream = stream->real_stream;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen /* This stream may be using parent's buffer directly as
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen _stream->buffer, but the parent stream has already been
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen modified indirectly. This means that the buffer might no
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen longer point to where we assume it points to. So we'll
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen just return the stream as empty until it's read again.
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen It's a bit ugly to suddenly drop data from the stream that
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen was already read, but since this happens only with shared
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen parent istreams the caller is hopefully aware enough that
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen something like this might happen. The other solutions would
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen be to a) try to automatically read the data back (but we
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen can't handle errors..) or b) always copy data to stream's
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen own buffer instead of pointing to parent's buffer (but this
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen causes data copying that is nearly always unnecessary). */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen /* if we had already read until EOF, mark the stream again as
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen not being at the end of file. */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainensize_t i_stream_get_data_size(struct istream *stream)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenunsigned char *i_stream_get_modifiable_data(struct istream *stream,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen struct istream_private *_stream = stream->real_stream;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) {
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainenint i_stream_read_data(struct istream *stream, const unsigned char **data_r,
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen /* we need more data */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen } while (ret > 0);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* need to read more */
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen /* we read at least some new data */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid i_stream_compress(struct istream_private *stream)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen memmove(stream->w_buffer, stream->w_buffer + stream->skip,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid i_stream_grow_buffer(struct istream_private *stream, size_t bytes)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (stream->buffer_size <= stream->init_buffer_size)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen stream->buffer_size = stream->init_buffer_size;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->buffer_size = nearest_power(stream->buffer_size);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen max_size = i_stream_get_max_buffer_size(&stream->istream);
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen stream->w_buffer = i_realloc(stream->w_buffer, old_size,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenbool i_stream_try_alloc(struct istream_private *stream,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen if (wanted_size > stream->buffer_size - stream->pos) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* remove the unused bytes from beginning of buffer */
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen } else if (stream->buffer_size < i_stream_get_max_buffer_size(&stream->istream)) {
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen /* buffer is full - grow it */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen i_stream_grow_buffer(stream, I_STREAM_MIN_SIZE);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid *i_stream_alloc(struct istream_private *stream, size_t size)
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen i_stream_try_alloc(stream, size, &avail_size);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen stream->buffer_size = nearest_power(stream->pos + size);
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen stream->w_buffer = i_realloc(stream->w_buffer, old_size,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen i_stream_try_alloc(stream, size, &avail_size);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenbool i_stream_add_data(struct istream *_stream, const unsigned char *data,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct istream_private *stream = _stream->real_stream;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen memcpy(stream->w_buffer + stream->pos, data, size);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainenvoid i_stream_set_input_pending(struct istream *stream, bool pending)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid i_stream_switch_ioloop(struct istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (stream->real_stream->switch_ioloop != NULL)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen stream->real_stream->switch_ioloop(stream->real_stream);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid i_stream_set_io(struct istream *stream, struct io *io)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainenvoid i_stream_unset_io(struct istream *stream, struct io *io)
f38485358ffc04c3466b917770575e29deef24c3Timo Siraineni_stream_default_set_max_buffer_size(struct iostream_private *stream,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen struct istream_private *_stream = (struct istream_private *)stream;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen i_stream_set_max_buffer_size(_stream->parent, max_size);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenstatic void i_stream_default_close(struct iostream_private *stream,
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen struct istream_private *_stream = (struct istream_private *)stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void i_stream_default_destroy(struct iostream_private *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct istream_private *_stream = (struct istream_private *)stream;
f38485358ffc04c3466b917770575e29deef24c3Timo Siraineni_stream_default_seek_seekable(struct istream_private *stream,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenvoid i_stream_default_seek_nonseekable(struct istream_private *stream,
f38485358ffc04c3466b917770575e29deef24c3Timo Sirainen i_panic("stream %s doesn't support seeking backwards",
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* read failed */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen ", because we have data only up to offset %"
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen stream->istream.v_offset, stream->istream.eof ? 1 : 0);
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (available <= v_offset - stream->istream.v_offset)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Siraineni_stream_default_stat(struct istream_private *stream, bool exact)
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen return stream->istream.stream_errno == 0 ? 0 : -1;
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen if (i_stream_stat(stream->parent, exact, &st) < 0) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen stream->istream.stream_errno = stream->parent->stream_errno;
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Sirainen if (exact && !stream->stream_size_passthrough) {
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen /* exact size is not known, even if parent returned something */
97180ea9c26c4de0807daaad21e03c80643b09fdTimo Siraineni_stream_default_get_size(struct istream_private *stream,
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainenvoid i_stream_init_parent(struct istream_private *_stream,
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen _stream->access_counter = parent->real_stream->access_counter;
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen _stream->parent_start_offset = parent->v_offset;
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen _stream->parent_expected_offset = parent->v_offset;
88b315f36ba082708ab6f53ea1924c54d9be0aefTimo Sirainen /* if parent stream is an istream-error, copy the error */
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen _stream->istream.stream_errno = parent->stream_errno;
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Siraineni_stream_create(struct istream_private *_stream, struct istream *parent, int fd)
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen _stream->iostream.close = i_stream_default_close;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen _stream->iostream.destroy = i_stream_default_destroy;
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen _stream->get_size = i_stream_default_get_size;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (_stream->iostream.set_max_buffer_size == NULL) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen _stream->init_buffer_size = I_STREAM_MIN_SIZE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen memset(&_stream->statbuf, 0, sizeof(_stream->statbuf));
7e95ba7f38b9b421287d36c6152f8a9e6b9f225bTimo Sirainenstruct istream *i_stream_create_error(int stream_errno)
struct istream *
return input;