/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "str.h"
#include "memarea.h"
#include "istream-private.h"
{
}
{
return "";
}
}
{
if (stream->stream_errno == 0)
}
{
return;
}
{
}
{
return;
}
}
{
}
void (*callback)())
{
callback);
}
{
}
{
struct istream *s;
/* we'll only return errors for streams that have stream_errno set or
that have reached EOF. we might be returning unintended error
otherwise. */
if (stream->stream_errno == 0)
if (s->stream_errno == 0)
break;
}
}
{
}
{
}
{
}
{
}
{
do {
return max_size;
}
{
}
{
do {
}
{
do {
}
}
{
stream->access_counter++;
else {
}
}
{
return TRUE;
return FALSE;
}
struct istream_snapshot *
struct istream_snapshot *prev_snapshot)
{
if (prev_snapshot != NULL) {
return prev_snapshot;
}
/* This stream has a memarea. Reference it, so we can later on
rollback if needed. */
return snapshot;
}
if (stream->nonpersistent_buffers) {
/* Assume that memarea would be used normally, but
now it's NULL because the buffer is empty and
empty buffers are freed. */
return prev_snapshot;
}
}
}
{
return;
}
static struct istream_snapshot *
struct istream_snapshot *prev_snapshot)
{
return prev_snapshot;
}
{
#ifdef DEBUG
if (invalid)
;
else {
}
#endif
if (ret > 0)
#ifdef DEBUG
else if (!invalid) {
else {
}
}
#endif
return ret;
}
{
return -1;
}
switch (ret) {
case -2:
break;
case -1:
if (stream->stream_errno != 0) {
/* error handling should be easier if we now just
assume the stream is now at EOF */
} else {
}
break;
case 0:
break;
default:
break;
}
if (stream->stream_errno != 0) {
/* error handling should be easier if we now just
assume the stream is now at EOF. Note that we could get here
even if read() didn't return -1, although that's a little
bit sloppy istream implementation. */
}
/* verify that parents' access_counters are valid. the parent's
i_stream_read() should guarantee this. */
return ret;
}
{
if (*size_r > 0)
return 1;
return ret;
}
{
}
{
ret = 0;
else do {
return -2;
}
/* check again, in case the parent stream had been seeked
backwards and the previous read() didn't get us far
enough. */
(ret == 0 ? 0 : -1);
return ret;
}
{
} else {
/* don't know how to free it */
return;
}
stream->buffer_size = 0;
}
{
/* within buffer */
if (_stream->nonpersistent_buffers &&
}
return;
}
/* have to seek forward */
return;
}
{
return TRUE;
/* use the fast route only if the parent stream hasn't been changed */
if (stream->access_counter !=
return FALSE;
}
{
else {
return;
}
}
}
{
return;
}
{
return;
}
}
{
return -1;
return -1;
}
return 0;
}
{
return -1;
int ret;
return ret;
}
{
}
{
if (i_stream_get_data_size(stream) == 0)
(void)i_stream_read(stream);
return !i_stream_have_bytes_left(stream);
}
{
}
return abs_offset;
}
{
char *ret;
end = i - 1;
} else {
end = i;
}
/* modify the buffer directly */
} else {
/* use a temporary string to return it */
}
i++;
return ret;
}
{
/* the last line is missing LF and we want to return it. */
}
return NULL;
}
{
const unsigned char *pos;
return NULL;
return i_stream_next_line_finish(_stream,
} else {
return i_stream_last_line(_stream);
}
}
{
char *line;
for (;;) {
break;
switch (i_stream_read(stream)) {
case -2:
"Line is too long (over %"PRIuSIZE_T
return NULL;
case -1:
case 0:
return NULL;
}
}
return line;
}
{
}
{
/* the buffer can't point to parent, because it doesn't exist */
return FALSE;
}
/* we can pretty safely assume that the stream is using its
own private buffer, so it can never become invalid. */
return FALSE;
}
if (stream->access_counter !=
/* parent has been modified behind this stream, we can't trust
that our buffer is valid */
return TRUE;
}
}
const unsigned char *
{
*size_r = 0;
return uchar_empty_ptr;
}
if (i_stream_is_buffer_invalid(_stream)) {
/* This stream may be using parent's buffer directly as
_stream->buffer, but the parent stream has already been
modified indirectly. This means that the buffer might no
longer point to where we assume it points to. So we'll
just return the stream as empty until it's read again.
It's a bit ugly to suddenly drop data from the stream that
was already read, but since this happens only with shared
parent istreams the caller is hopefully aware enough that
something like this might happen. The other solutions would
be to a) try to automatically read the data back (but we
can't handle errors..) or b) always copy data to stream's
own buffer instead of pointing to parent's buffer (but this
causes data copying that is nearly always unnecessary). */
*size_r = 0;
/* if we had already read until EOF, mark the stream again as
not being at the end of file. */
if (stream->stream_errno == 0) {
}
return uchar_empty_ptr;
}
}
{
return size;
}
{
*size_r = 0;
return NULL;
}
}
{
do {
return 1;
/* we need more data */
if (ret > 0)
} while (ret > 0);
if (ret == -2)
return -2;
if (ret == 0) {
/* need to read more */
return 0;
}
if (read_more) {
/* we read at least some new data */
return 0;
}
} else {
}
return -1;
}
{
}
}
{
}
static void
{
void *new_buffer;
/* Nobody else is referencing the memarea.
We can just reallocate it. */
} else {
if (old_size > 0) {
}
}
}
{
else
else
}
{
i_assert(wanted_size > 0);
/* remove the unused bytes from beginning of buffer */
/* The memarea is still referenced. We can't
overwrite data until extra references are
gone. */
}
/* buffer is full - grow it */
}
}
if (stream->try_alloc_limit > 0 &&
return *size_r > 0;
}
{
/* try first with skip=0, so no compression is done */
return ret;
/* it's full. try with compression. */
}
{
if (avail_size < size) {
}
}
{
return FALSE;
return TRUE;
}
{
}
return stream;
}
{
if (!pending)
return;
}
{
do {
}
}
{
}
{
}
{
}
static void
{
}
bool close_parent)
{
if (close_parent)
}
{
}
static void
{
}
{
i_panic("stream %s doesn't support seeking backwards",
if (available == 0) {
/* read failed */
return;
}
"Can't seek to offset %"PRIuUOFF_T
", because we have data only up to offset %"
return;
}
else {
}
}
}
static int
{
return -1;
}
/* exact size is not known, even if parent returned something */
}
return 0;
}
static int
{
return -1;
return 0;
return 1;
}
{
/* if parent stream is an istream-error, copy the error */
}
struct istream *
enum istream_create_flag flags)
{
/* The stream has no parent and no memarea yet. We'll assume
that it wants to be using memareas for the reads. */
}
}
}
}
if (_stream->init_buffer_size == 0)
}
{
}
struct istream *
{
return input;
}