1
/* Copyright (c) 2007-2013 Dovecot authors, see the included COPYING file */
4
#include "istream-private.h"
5
#include "istream-nonuls.h"
7
struct nonuls_istream {
8
struct istream_private istream;
12
static int i_stream_read_parent(struct istream_private *stream)
16
if (i_stream_get_data_size(stream->parent) > 0)
19
ret = i_stream_read(stream->parent);
21
stream->istream.stream_errno = stream->parent->stream_errno;
22
stream->istream.eof = stream->parent->eof;
25
i_assert(i_stream_get_data_size(stream->parent) != 0);
29
static ssize_t i_stream_nonuls_read(struct istream_private *stream)
31
struct nonuls_istream *nstream = (struct nonuls_istream *)stream;
32
const unsigned char *data, *p;
33
size_t i, size, avail_size;
36
if ((ret = i_stream_read_parent(stream)) <= 0)
39
data = i_stream_get_data(stream->parent, &size);
40
if (!i_stream_try_alloc(stream, size, &avail_size))
42
if (size > avail_size)
46
p = memchr(data, '\0', size);
48
/* no NULs in this block */
49
memcpy(stream->w_buffer+stream->pos, data, size);
52
memcpy(stream->w_buffer+stream->pos, data, i);
53
for (; i < size; i++) {
54
stream->w_buffer[stream->pos+i] = data[i] == '\0' ?
55
nstream->replace_chr : data[i];
59
i_stream_skip(stream->parent, size);
63
struct istream *i_stream_create_nonuls(struct istream *input, char replace_chr)
65
struct nonuls_istream *nstream;
67
nstream = i_new(struct nonuls_istream, 1);
68
nstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
69
nstream->istream.stream_size_passthrough = TRUE;
71
nstream->istream.read = i_stream_nonuls_read;
73
nstream->istream.istream.readable_fd = FALSE;
74
nstream->istream.istream.blocking = input->blocking;
75
nstream->istream.istream.seekable = FALSE;
76
nstream->replace_chr = replace_chr;
77
return i_stream_create(&nstream->istream, input,
78
i_stream_get_fd(input));