if (skip_header(mstream) < 0)
return -1;
+ if (!mstream->end_body_with_lf) {
+ /* no last-LF */
+ } else if (mstream->last_lf_added) {
+ /* yes, we have added LF */
+ stream->statbuf.st_size += mstream->crlf ? 2 : 1;
+ } else if (mstream->last_lf_offset != (uoff_t)-1) {
+ /* no, we didn't need to add LF */
+ } else {
+ /* check if we need to add LF */
+ i_stream_seek(stream->parent, st->st_size - 1);
+ (void)i_stream_read(stream->parent);
+ if (stream->parent->stream_errno != 0) {
+ stream->istream.stream_errno =
+ stream->parent->stream_errno;
+ return -1;
+ }
+ i_assert(stream->parent->eof);
+ ssize_t ret = handle_end_body_with_lf(mstream, -1);
+ if (ret > 0)
+ stream->statbuf.st_size += ret;
+ }
+
stream->statbuf.st_size -=
(off_t)mstream->header_size.physical_size -
(off_t)mstream->header_size.virtual_size;
mstream->add_missing_eoh = (flags & HEADER_FILTER_ADD_MISSING_EOH) != 0;
mstream->end_body_with_lf =
(flags & HEADER_FILTER_END_BODY_WITH_LF) != 0;
+ mstream->last_lf_offset = (uoff_t)-1;
mstream->istream.iostream.destroy = i_stream_header_filter_destroy;
mstream->istream.read = i_stream_header_filter_read;
unsigned int input_len, const char *output)
{
unsigned int i, output_len = strlen(output);
+ const struct stat *st;
const unsigned char *data;
size_t size;
while (i_stream_read(filter) > 0) ;
data = i_stream_get_data(filter, &size);
test_assert(size == output_len && memcmp(data, output, size) == 0);
+ test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
+ (uoff_t)st->st_size == size);
}
static void ATTR_NULL(3)
unsigned int i, input_len = strlen(input);
unsigned int output_len = strlen(output);
const unsigned char *data;
+ const struct stat *st;
size_t size;
test_begin("i_stream_create_header_filter(exclude)");
data = i_stream_get_data(filter, &size);
test_assert(size == output_len && memcmp(data, output, size) == 0);
+ test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
+ (uoff_t)st->st_size == size);
+
i_stream_skip(filter, size);
i_stream_seek(filter, 0);
while (i_stream_read(filter) > 0) ;
data = i_stream_get_data(filter, &size);
test_assert(size == output_len && memcmp(data, output, size) == 0);
+ test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
+ (uoff_t)st->st_size == size);
i_stream_unref(&filter);
i_stream_unref(&istream);
{
string_t *input, *output;
struct istream *istream, *filter;
+ const struct stat *st;
const unsigned char *data;
size_t size, prefix_len;
const char *p;
i_assert(p != NULL);
test_assert(strcmp(p+1, str_c(output) + prefix_len) == 0);
+ test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
+ (uoff_t)st->st_size == filter->v_offset + size);
+
/* seek back and retry once with caching and different
buffer size */
i_stream_seek(filter, 0);
static void test_istream_callbacks(void)
{
string_t *input, *output;
+ const struct stat *st;
struct istream *istream, *filter;
unsigned int i;
i_stream_skip(filter, i_stream_get_data_size(filter));
}
+ test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
+ (uoff_t)st->st_size == str_len(output));
test_assert(strcmp(str_c(output), str_c(input)) == 0);
str_free(&input);
str_free(&output);
{
const char *input = "From: foo\n\nhello world";
const char *output = "From: foo\n\nhello world\n";
+ const struct stat *st;
struct istream *istream, *filter;
unsigned int i, input_len = strlen(input);
unsigned int output_len = strlen(output);
data = i_stream_get_data(filter, &size);
test_assert(size == output_len && memcmp(data, output, size) == 0);
+ test_assert(i_stream_stat(filter, TRUE, &st) == 0 &&
+ (uoff_t)st->st_size == filter->v_offset + size);
i_stream_skip(filter, size);
i_stream_seek(filter, 0);