/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "llist.h"
#include "istream-private.h"
#include "istream-chain.h"
struct chain_istream;
struct istream_chain_link {
bool eof;
};
struct istream_chain {
};
struct chain_istream {
/* how much of the previous link's stream still exists at the
beginning of our buffer. skipping through this should point to
the beginning of the current link's stream. */
};
static void ATTR_NULL(2)
{
return;
if (cstream->have_explicit_max_buffer_size) {
} else {
}
}
/* if io_add_istream() has been added to this chain stream, notify
the callback that we have more data available. */
}
{
}
{
}
static void
{
}
}
{
}
}
{
const unsigned char *data;
/* a) we have more streams, b) we have EOF, c) we need to wait
for more streams */
if (cstream->prev_stream_left > 0) {
/* we've already buffered some of the prev_input. continue
appending the rest to it. if it's already at EOF, there's
nothing more to append. */
data += cur_data_pos;
/* the stream has now become "previous", so its contents in
buffer are now part of prev_stream_left. */
} else {
cstream->prev_stream_left = 0;
}
if (data_size > 0) {
}
}
{
if (cstream->prev_stream_left == 0) {
/* no need to worry about buffers, skip everything */
/* we're still skipping inside buffer */
bytes_skipped = 0;
} else {
/* done with the buffer */
cstream->prev_stream_left = 0;
}
i_assert(bytes_skipped == 0);
return FALSE;
}
return TRUE;
}
{
const unsigned char *data;
return -1;
}
if (!i_stream_chain_skip(cstream))
return 0;
if (data_size > cur_data_pos)
ret = 0;
else {
/* need to read more - NOTE: Can't use i_stream_read_memarea()
here, because our stream->buffer may point to the parent
istream. This could be avoided if we implemented
snapshotting ourself. */
return ret;
if (ret == -1) {
"read(%s) failed: %s",
return -1;
}
/* EOF of this stream, go to next stream */
return i_stream_chain_read(stream);
}
/* we read something */
}
if (data_size == cur_data_pos) {
/* nothing new read - preserve the buffer as it was */
return ret;
}
if (cstream->prev_stream_left == 0) {
/* we can point directly to the current stream's buffers */
} else {
/* we still have some of the previous stream left. merge the
new data with it. */
}
return ret;
}
bool close_parent)
{
/* seek to the correct position in parent stream in case it didn't
end with EOF */
(void)i_stream_chain_skip(cstream);
if (close_parent) {
}
}
}
{
}