return -EBADMSG;
}
-int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
+int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size) {
#if HAVE_XZ
_cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
lzma_ret ret;
return k;
if (ret == LZMA_STREAM_END) {
+ if (ret_uncompressed_size)
+ *ret_uncompressed_size = s.total_in;
+
log_debug("XZ compression finished (%"PRIu64" -> %"PRIu64" bytes, %.1f%%)",
s.total_in, s.total_out,
(double) s.total_out / s.total_in * 100);
#define LZ4_BUFSIZE (512*1024u)
-int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
+int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size) {
#if HAVE_LZ4
LZ4F_errorCode_t c;
_cleanup_(LZ4F_freeCompressionContextp) LZ4F_compressionContext_t ctx = NULL;
_cleanup_free_ void *in_buff = NULL;
_cleanup_free_ char *out_buff = NULL;
- size_t out_allocsize, n, total_in = 0, total_out, offset = 0, frame_size;
+ size_t out_allocsize, n, offset = 0, frame_size;
+ uint64_t total_in = 0, total_out;
int r;
static const LZ4F_preferences_t preferences = {
.frameInfo.blockSizeID = 5,
if (r < 0)
return r;
- log_debug("LZ4 compression finished (%zu -> %zu bytes, %.1f%%)",
+ if (ret_uncompressed_size)
+ *ret_uncompressed_size = total_in;
+
+ log_debug("LZ4 compression finished (%" PRIu64 " -> %" PRIu64 " bytes, %.1f%%)",
total_in, total_out,
(double) total_out / total_in * 100);
#endif
}
-int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes) {
+int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size) {
#if HAVE_ZSTD
_cleanup_(ZSTD_freeCCtxp) ZSTD_CCtx *cctx = NULL;
_cleanup_free_ void *in_buff = NULL, *out_buff = NULL;
break;
}
+ if (ret_uncompressed_size)
+ *ret_uncompressed_size = in_bytes;
+
if (in_bytes > 0)
log_debug("ZSTD compression finished (%" PRIu64 " -> %" PRIu64 " bytes, %.1f%%)",
in_bytes, max_bytes - left, (double) (max_bytes - left) / in_bytes * 100);
const void *prefix, size_t prefix_len,
uint8_t extra);
-int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes);
-int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes);
-int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes);
+int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size);
+int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size);
+int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size);
int decompress_stream_xz(int fdf, int fdt, uint64_t max_size);
int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size);
# define compress_stream compress_stream_xz
# define COMPRESSED_EXT ".xz"
#else
-static inline int compress_stream(int fdf, int fdt, uint64_t max_size) {
+static inline int compress_stream(int fdf, int fdt, uint64_t max_size, uint64_t *ret_uncompressed_size) {
return -EOPNOTSUPP;
}
# define COMPRESSED_EXT ""
const void *prefix, size_t prefix_len,
uint8_t extra);
-typedef int (compress_stream_t)(int fdf, int fdt, uint64_t max_bytes);
+typedef int (compress_stream_t)(int fdf, int fdt, uint64_t max_bytes, uint64_t *uncompressed_size);
typedef int (decompress_stream_t)(int fdf, int fdt, uint64_t max_size);
#if HAVE_COMPRESSION
int r;
_cleanup_free_ char *cmd = NULL, *cmd2 = NULL;
struct stat st = {};
+ uint64_t uncompressed_size;
r = find_executable(cat, NULL);
if (r < 0) {
assert_se((dst = mkostemp_safe(pattern)) >= 0);
- assert_se(compress(src, dst, -1) == 0);
+ assert_se(compress(src, dst, -1, &uncompressed_size) == 0);
if (cat) {
assert_se(asprintf(&cmd, "%s %s | diff %s -", cat, pattern, srcfile) > 0);
assert_se((dst2 = mkostemp_safe(pattern2)) >= 0);
assert_se(stat(srcfile, &st) == 0);
+ assert_se((uint64_t)st.st_size == uncompressed_size);
assert_se(lseek(dst, 0, SEEK_SET) == 0);
r = decompress(dst, dst2, st.st_size);