diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-09-15 21:13:56 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-09-16 09:34:35 +0200 | 
| commit | 183cf393a453cddb689666ce7fb35a97e7f523bf (patch) | |
| tree | 7f57b466be7fdbe8cae1ad1f5562fa493ad3312b /lib/fstream/compress | |
| parent | 15431d4fd8de67a03af4ee9cc8e774e1750e9da2 (diff) | |
Add bzip2 stream compression support
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/fstream/compress')
| -rw-r--r-- | lib/fstream/compress/bzip2.c | 87 | ||||
| -rw-r--r-- | lib/fstream/compress/ostream_compressor.c | 5 | 
2 files changed, 92 insertions, 0 deletions
diff --git a/lib/fstream/compress/bzip2.c b/lib/fstream/compress/bzip2.c new file mode 100644 index 0000000..3ca425a --- /dev/null +++ b/lib/fstream/compress/bzip2.c @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * bzip2.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "../internal.h" + +#include <bzlib.h> + +typedef struct { +	ostream_comp_t base; + +	bz_stream strm; +} ostream_bzip2_t; + +static int flush_inbuf(ostream_comp_t *base, bool finish) +{ +	ostream_bzip2_t *bzip2 = (ostream_bzip2_t *)base; +	size_t have; +	int ret; + +	bzip2->strm.next_in = (char *)base->inbuf; +	bzip2->strm.avail_in = base->inbuf_used; + +	for (;;) { +		bzip2->strm.next_out = (char *)base->outbuf; +		bzip2->strm.avail_out = sizeof(base->outbuf); + +		ret = BZ2_bzCompress(&bzip2->strm, finish ? BZ_FINISH : BZ_RUN); + +		if (ret < 0 && ret != BZ_OUTBUFF_FULL) { +			fprintf(stderr, "%s: internal error in bzip2 " +				"compressor.\n", +				base->wrapped->get_filename(base->wrapped)); +			return -1; +		} + +		have = sizeof(base->outbuf) - bzip2->strm.avail_out; + +		if (base->wrapped->append(base->wrapped, base->outbuf, have)) +			return -1; + +		if (ret == BZ_STREAM_END || ret == BZ_OUTBUFF_FULL || +		    bzip2->strm.avail_in == 0) { +			break; +		} +	} + +	if (bzip2->strm.avail_in > 0) { +		memmove(base->inbuf, bzip2->strm.next_in, +			bzip2->strm.avail_in); +	} + +	base->inbuf_used = bzip2->strm.avail_in; +	return 0; +} + +static void cleanup(ostream_comp_t *base) +{ +	ostream_bzip2_t *bzip2 = (ostream_bzip2_t *)base; + +	BZ2_bzCompressEnd(&bzip2->strm); +} + +ostream_comp_t *ostream_bzip2_create(const char *filename) +{ +	ostream_bzip2_t *bzip2 = calloc(1, sizeof(*bzip2)); +	ostream_comp_t *base = (ostream_comp_t *)bzip2; + +	if (bzip2 == NULL) { +		fprintf(stderr, "%s: creating bzip2 compressor: %s.\n", +			filename, strerror(errno)); +		return NULL; +	} + +	if (BZ2_bzCompressInit(&bzip2->strm, 9, 0, 30) != BZ_OK) { +		fprintf(stderr, "%s: error initializing bzip2 compressor.\n", +			filename); +		free(bzip2); +		return NULL; +	} + +	base->flush_inbuf = flush_inbuf; +	base->cleanup = cleanup; +	return base; +} diff --git a/lib/fstream/compress/ostream_compressor.c b/lib/fstream/compress/ostream_compressor.c index d1d55e1..7ea7919 100644 --- a/lib/fstream/compress/ostream_compressor.c +++ b/lib/fstream/compress/ostream_compressor.c @@ -82,6 +82,11 @@ ostream_t *ostream_compressor_create(ostream_t *strm, int comp_id)  		comp = ostream_zstd_create(strm->get_filename(strm));  #endif  		break; +	case FSTREAM_COMPRESSOR_BZIP2: +#ifdef WITH_BZIP2 +		comp = ostream_bzip2_create(strm->get_filename(strm)); +#endif +		break;  	default:  		break;  	}  | 
