size_t size;
int ret;
- ret = i_stream_read_bytes(zstream->istream.parent, &data, &size,
- sizeof(*hdr));
+ ret = i_stream_read_more(zstream->istream.parent, &data, &size);
+ size = I_MIN(size, sizeof(*hdr));
+ buffer_append(zstream->chunk_buf, data, size);
+ i_stream_skip(zstream->istream.parent, size);
if (ret < 0) {
zstream->istream.istream.stream_errno =
zstream->istream.parent->stream_errno;
}
if (ret == 0 && !zstream->istream.istream.eof)
return 0;
- hdr = (const void *)data;
+ if (zstream->chunk_buf->used < sizeof(*hdr))
+ return 0;
+
+ hdr = zstream->chunk_buf->data;
if (ret == 0 || memcmp(hdr->magic, IOSTREAM_LZ4_MAGIC,
IOSTREAM_LZ4_MAGIC_LEN) != 0) {
lz4_read_error(zstream, "wrong magic in header (not lz4 file?)");
}
zstream->max_uncompressed_chunk_size =
be32_to_cpu_unaligned(hdr->max_uncompressed_chunk_size);
+ buffer_set_used_size(zstream->chunk_buf, 0);
if (zstream->max_uncompressed_chunk_size > ISTREAM_LZ4_CHUNK_SIZE) {
lz4_read_error(zstream, t_strdup_printf(
"lz4 max chunk size too large (%u > %u)",
zstream->istream.istream.stream_errno = EINVAL;
return -1;
}
- i_stream_skip(zstream->istream.parent, sizeof(*hdr));
return 1;
}
int ret;
if (!zstream->header_read) {
- if ((ret = i_stream_lz4_read_header(zstream)) <= 0)
+ if ((ret = i_stream_lz4_read_header(zstream)) <= 0) {
+ stream->istream.eof = TRUE;
return ret;
+ }
zstream->header_read = TRUE;
}
if (zstream->chunk_left == 0) {
- ret = i_stream_read_bytes(stream->parent, &data, &size,
- IOSTREAM_LZ4_CHUNK_PREFIX_LEN);
+ 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 (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(data);
+ 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(
stream->istream.stream_errno = EINVAL;
return -1;
}
- i_stream_skip(stream->parent, IOSTREAM_LZ4_CHUNK_PREFIX_LEN);
buffer_set_used_size(zstream->chunk_buf, 0);
}
i_assert(ret > 0);
stream->pos += ret;
i_assert(stream->pos <= stream->buffer_size);
+
+ /* we are going to get next chunk after this, so reset here
+ so we can reuse the chunk buf for reading next buffer prefix */
+ if (zstream->chunk_left == 0)
+ buffer_set_used_size(zstream->chunk_buf, 0);
+
return ret;
}
stream->parent_expected_offset = stream->parent_start_offset;
stream->skip = stream->pos = 0;
stream->istream.v_offset = 0;
+ buffer_set_used_size(zstream->chunk_buf, 0);
}
static void