return 1;
}
+static int i_stream_lz4_read_chunk_header(struct lz4_istream *zstream)
+{
+ int ret;
+ size_t size;
+ const unsigned char *data;
+ struct istream_private *stream = &zstream->istream;
+
+ i_assert(zstream->chunk_buf->used <= IOSTREAM_LZ4_CHUNK_PREFIX_LEN);
+ ret = i_stream_read_more(stream->parent, &data, &size);
+ size = I_MIN(size, IOSTREAM_LZ4_CHUNK_PREFIX_LEN - zstream->chunk_buf->used);
+ buffer_append(zstream->chunk_buf, data, size);
+ i_stream_skip(stream->parent, size);
+ if (ret < 0) {
+ stream->istream.stream_errno = stream->parent->stream_errno;
+ if (stream->istream.stream_errno == 0) {
+ stream->istream.eof = TRUE;
+ stream->cached_stream_size =
+ stream->istream.v_offset +
+ stream->pos - stream->skip;
+ }
+ return ret;
+ }
+ i_assert(ret != 0 || !stream->istream.blocking);
+ if (ret == 0)
+ return ret;
+ if (zstream->chunk_buf->used < IOSTREAM_LZ4_CHUNK_PREFIX_LEN)
+ return 0;
+ zstream->chunk_size = zstream->chunk_left =
+ be32_to_cpu_unaligned(zstream->chunk_buf->data);
+ if (zstream->chunk_size == 0 ||
+ zstream->chunk_size > ISTREAM_LZ4_CHUNK_SIZE) {
+ lz4_read_error(zstream, t_strdup_printf(
+ "invalid lz4 chunk size: %u", zstream->chunk_size));
+ stream->istream.stream_errno = EINVAL;
+ return -1;
+ }
+ buffer_set_used_size(zstream->chunk_buf, 0);
+ return 1;
+}
+
static ssize_t i_stream_lz4_read(struct istream_private *stream)
{
struct lz4_istream *zstream = (struct lz4_istream *)stream;
}
if (zstream->chunk_left == 0) {
- i_assert(zstream->chunk_buf->used <= IOSTREAM_LZ4_CHUNK_PREFIX_LEN);
- ret = i_stream_read_more(stream->parent, &data, &size);
- if (size > IOSTREAM_LZ4_CHUNK_PREFIX_LEN - zstream->chunk_buf->used)
- size = IOSTREAM_LZ4_CHUNK_PREFIX_LEN - zstream->chunk_buf->used;
- buffer_append(zstream->chunk_buf, data, size);
- i_stream_skip(stream->parent, size);
- if (ret < 0) {
- stream->istream.stream_errno =
- stream->parent->stream_errno;
- if (stream->istream.stream_errno == 0) {
- stream->istream.eof = TRUE;
- stream->cached_stream_size =
- stream->istream.v_offset +
- stream->pos - stream->skip;
- }
- return ret;
+ while ((ret = i_stream_lz4_read_chunk_header(zstream)) == 0) {
+ if (ret == 0 && !stream->istream.blocking)
+ return 0;
}
- if (ret == 0 && !stream->istream.eof)
- return 0;
- if (zstream->chunk_buf->used < IOSTREAM_LZ4_CHUNK_PREFIX_LEN)
- return 0;
- zstream->chunk_size = zstream->chunk_left =
- be32_to_cpu_unaligned(zstream->chunk_buf->data);
- buffer_set_used_size(zstream->chunk_buf, 0);
- if (zstream->chunk_size == 0 ||
- zstream->chunk_size > ISTREAM_LZ4_CHUNK_SIZE) {
- lz4_read_error(zstream, t_strdup_printf(
- "invalid lz4 chunk size: %u", zstream->chunk_size));
- stream->istream.stream_errno = EINVAL;
- return -1;
- }
- buffer_set_used_size(zstream->chunk_buf, 0);
+ if (ret < 0)
+ return ret;
}
/* read the whole compressed chunk into memory */
}
zstream->istream.istream.stream_errno =
zstream->istream.parent->stream_errno;
+ i_assert(ret != 0 || !stream->istream.blocking);
return ret;
}
/* if we already have max_buffer_size amount of data, fail here */