static int o_stream_lzma_send_flush(struct lzma_ostream *zstream) { lzma_stream *zs = &zstream->strm; unsigned int len; bool done = FALSE; int ret; if (zs->avail_in != 0) { i_assert(zstream->ostream.ostream.last_failed_errno != 0); zstream->ostream.ostream.stream_errno = zstream->ostream.ostream.last_failed_errno; return -1; } if (zstream->flushed) return 0; if ((ret = o_stream_flush_parent_if_needed(&zstream->ostream)) <= 0) return ret; if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) return ret; i_assert(zstream->outbuf_used == 0); do { ret = lzma_code(zs, LZMA_FINISH); switch (ret) { case LZMA_OK: break; case LZMA_STREAM_END: done = TRUE; break; case LZMA_MEM_ERROR: i_fatal_status(FATAL_OUTOFMEM, "lzma.write(%s): Out of memory", o_stream_get_name(&zstream->ostream.ostream)); default: i_panic("lzma.write(%s) flush failed with unexpected code %d", o_stream_get_name(&zstream->ostream.ostream), ret); } if (zs->avail_out == 0 || done) { len = sizeof(zstream->outbuf) - zs->avail_out; zs->next_out = zstream->outbuf; zs->avail_out = sizeof(zstream->outbuf); zstream->outbuf_used = len; if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) return ret; } } while (!done); zstream->flushed = TRUE; return 0; }
static int o_stream_bzlib_send_flush(struct bzlib_ostream *zstream) { bz_stream *zs = &zstream->zs; unsigned int len; bool done = FALSE; int ret; if (zs->avail_in != 0) { i_assert(zstream->ostream.ostream.last_failed_errno != 0); zstream->ostream.ostream.stream_errno = zstream->ostream.ostream.last_failed_errno; return -1; } if (zstream->flushed) return 0; if ((ret = o_stream_flush_parent_if_needed(&zstream->ostream)) <= 0) return ret; if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) return ret; i_assert(zstream->outbuf_used == 0); do { len = sizeof(zstream->outbuf) - zs->avail_out; if (len != 0) { zs->next_out = zstream->outbuf; zs->avail_out = sizeof(zstream->outbuf); zstream->outbuf_used = len; if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) return ret; if (done) break; } ret = BZ2_bzCompress(zs, BZ_FINISH); switch (ret) { case BZ_STREAM_END: done = TRUE; break; case BZ_FINISH_OK: break; default: i_unreached(); } } while (zs->avail_out != sizeof(zstream->outbuf)); zstream->flushed = TRUE; return 0; }
static ssize_t o_stream_lzma_sendv(struct ostream_private *stream, const struct const_iovec *iov, unsigned int iov_count) { struct lzma_ostream *zstream = (struct lzma_ostream *)stream; ssize_t ret, bytes = 0; unsigned int i; if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) { /* error / we still couldn't flush existing data to parent stream. */ return ret; } for (i = 0; i < iov_count; i++) { ret = o_stream_lzma_send_chunk(zstream, iov[i].iov_base, iov[i].iov_len); if (ret < 0) return -1; bytes += ret; if ((size_t)ret != iov[i].iov_len) break; } stream->ostream.offset += bytes; /* avail_in!=0 check is used to detect errors. if it's non-zero here it simply means we didn't send all the data */ zstream->strm.avail_in = 0; return bytes; }
static ssize_t o_stream_zlib_send_chunk(struct zlib_ostream *zstream, const void *data, size_t size) { z_stream *zs = &zstream->zs; int ret, flush; i_assert(zstream->outbuf_used == 0); flush = zstream->ostream.corked || zstream->gz ? Z_NO_FLUSH : Z_SYNC_FLUSH; if (!zstream->header_sent) { if (o_stream_zlib_send_gz_header(zstream) < 0) return -1; } zs->next_in = (void *)data; zs->avail_in = size; while (zs->avail_in > 0) { if (zs->avail_out == 0) { /* previous block was compressed. send it and start compression for a new block. */ zs->next_out = zstream->outbuf; zs->avail_out = sizeof(zstream->outbuf); zstream->outbuf_used = sizeof(zstream->outbuf); if ((ret = o_stream_zlib_send_outbuf(zstream)) < 0) return -1; if (ret == 0) { /* parent stream's buffer full */ break; } } ret = deflate(zs, flush); switch (ret) { case Z_OK: case Z_BUF_ERROR: break; case Z_STREAM_ERROR: i_assert(zstream->gz); i_panic("zlib.write(%s) failed: Can't write more data to .gz after flushing", o_stream_get_name(&zstream->ostream.ostream)); default: i_panic("zlib.write(%s) failed with unexpected code %d", o_stream_get_name(&zstream->ostream.ostream), ret); } } size -= zs->avail_in; zstream->crc = crc32_data_more(zstream->crc, data, size); zstream->bytes32 += size; zstream->flushed = flush == Z_SYNC_FLUSH && zs->avail_in == 0 && zs->avail_out == sizeof(zstream->outbuf); return size; }
static ssize_t o_stream_lzma_send_chunk(struct lzma_ostream *zstream, const void *data, size_t size) { lzma_stream *zs = &zstream->strm; int ret; i_assert(zstream->outbuf_used == 0); zs->next_in = (void *)data; zs->avail_in = size; while (zs->avail_in > 0) { if (zs->avail_out == 0) { /* previous block was compressed. send it and start compression for a new block. */ zs->next_out = zstream->outbuf; zs->avail_out = sizeof(zstream->outbuf); zstream->outbuf_used = sizeof(zstream->outbuf); if ((ret = o_stream_zlib_send_outbuf(zstream)) < 0) return -1; if (ret == 0) { /* parent stream's buffer full */ break; } } ret = lzma_code(zs, LZMA_RUN); switch (ret) { case LZMA_OK: break; case LZMA_MEM_ERROR: i_fatal_status(FATAL_OUTOFMEM, "lzma.write(%s): Out of memory", o_stream_get_name(&zstream->ostream.ostream)); default: i_panic("lzma.write(%s) failed with unexpected code %d", o_stream_get_name(&zstream->ostream.ostream), ret); } } size -= zs->avail_in; zstream->flushed = FALSE; return size; }
static ssize_t o_stream_bzlib_send_chunk(struct bzlib_ostream *zstream, const void *data, size_t size) { bz_stream *zs = &zstream->zs; int ret; i_assert(zstream->outbuf_used == 0); zs->next_in = (void *)data; zs->avail_in = size; while (zs->avail_in > 0) { if (zs->avail_out == 0) { /* previous block was compressed. send it and start compression for a new block. */ zs->next_out = zstream->outbuf; zs->avail_out = sizeof(zstream->outbuf); zstream->outbuf_used = sizeof(zstream->outbuf); if ((ret = o_stream_zlib_send_outbuf(zstream)) < 0) return -1; if (ret == 0) { /* parent stream's buffer full */ break; } } switch (BZ2_bzCompress(zs, BZ_RUN)) { case BZ_RUN_OK: break; default: i_unreached(); } } size -= zs->avail_in; zstream->flushed = FALSE; return size; }