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; }