istream.c revision c2cda8cd0043443566efc5da30f79865508a1947
/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "str.h"
#include "istream-private.h"
{
}
{
return "";
}
}
{
if (stream->stream_errno == 0)
}
{
}
{
}
{
}
}
{
}
void (*callback)())
{
callback);
}
{
}
{
struct istream *s;
/* we'll only return errors for streams that have stream_errno set.
we might be returning unintended error otherwise. */
if (stream->stream_errno == 0)
return "<no error>";
if (s->stream_errno == 0)
break;
}
}
{
}
{
}
{
}
{
}
{
}
{
stream->access_counter++;
else {
}
}
{
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;
}
{
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;
}
{
/* within buffer */
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;
}
{
}
{
if (i_stream_get_data_size(stream) == 0)
(void)i_stream_read(stream);
return !i_stream_have_bytes_left(stream);
}
{
}
{
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 NULL;
}
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 NULL;
}
}
{
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;
}
{
}
{
else
else {
}
}
{
i_assert(wanted_size > 0);
/* remove the unused bytes from beginning of buffer */
} else if (stream->max_buffer_size == 0 ||
/* buffer is full - grow it */
}
}
if (stream->try_alloc_limit > 0 &&
return *size_r > 0;
}
{
if (avail_size < size) {
}
}
{
return FALSE;
return TRUE;
}
{
if (!pending)
return;
}
}
{
do {
}
{
}
}
{
}
}
static void
{
}
bool 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 *
{
}
}
if (_stream->init_buffer_size == 0)
}
{
struct istream_private *stream;
}
struct istream *
{
return input;
}