From 0624fdd696422e718ce31f590c213e6f994f0641 Mon Sep 17 00:00:00 2001 From: Jonathan Dieter Date: Sat, 18 Feb 2023 20:54:28 +0000 Subject: [PATCH] Add ZCK_NO_WRITE option to disable writing to a file There are situations where we need to recreate the zchunk header for an uncompressed file without actually writing out the zchunk file. This commit allows setting an `ioption`, `ZCK_NO_WRITE`, that will go through the full process of creating the zchunk file without actually writing it to disk, leaving you with a complete zchunk header in the end. Signed-off-by: Jonathan Dieter --- include/zck.h.in | 2 ++ src/lib/comp/comp.c | 10 +++++----- src/lib/header.c | 2 +- src/lib/io.c | 3 +++ src/lib/zck.c | 17 +++++++++++++++++ src/lib/zck_private.h | 1 + 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/include/zck.h.in b/include/zck.h.in index 93f4706..d641b20 100644 --- a/include/zck.h.in +++ b/include/zck.h.in @@ -28,6 +28,8 @@ typedef enum zck_ioption { ZCK_VAL_HEADER_HASH_TYPE, /* Set what the header hash type *should* be */ ZCK_VAL_HEADER_LENGTH, /* Set what the header length *should* be */ ZCK_UNCOMP_HEADER, /* Header should contain uncompressed size, too */ + ZCK_NO_WRITE, /* Do not write to file when creating zck file - + Used to calculate header from existing umcompressed data */ ZCK_COMP_TYPE = 100, /* Set compression type using zck_comp */ ZCK_MANUAL_CHUNK, /* Disable auto-chunking */ ZCK_CHUNK_MIN, /* Minimum chunk size when manual chunking */ diff --git a/src/lib/comp/comp.c b/src/lib/comp/comp.c index 4786e41..13cb491 100644 --- a/src/lib/comp/comp.c +++ b/src/lib/comp/comp.c @@ -154,7 +154,7 @@ static ssize_t comp_write(zckCtx *zck, const char *src, const size_t src_size) { return -1; zck->comp.dc_data_size += src_size; - if(dst_size > 0 && !write_data(zck, zck->temp_fd, dst, dst_size)) { + if(zck->no_write == 0 && dst_size > 0 && !write_data(zck, zck->temp_fd, dst, dst_size)) { free(dst); return -1; } @@ -217,7 +217,7 @@ bool comp_init(zckCtx *zck) { } } - if(zck->temp_fd) { + if(zck->temp_fd || zck->no_write) { if(zck->comp.dict) { char *dst = NULL; size_t dst_size = 0; @@ -226,7 +226,7 @@ bool comp_init(zckCtx *zck) { zck->comp.dict_size, &dst, &dst_size, 0) < 0) return false; zck->comp.dc_data_size = zck->comp.dict_size; - if(!write_data(zck, zck->temp_fd, dst, dst_size)) { + if(zck->no_write == 0 && !write_data(zck, zck->temp_fd, dst, dst_size)) { free(dst); return false; } @@ -242,7 +242,7 @@ bool comp_init(zckCtx *zck) { if(!zck->comp.end_cchunk(zck, comp, &dst, &dst_size, 0)) return false; zck->comp.dc_data_size = 0; - if(!write_data(zck, zck->temp_fd, dst, dst_size)) { + if(zck->no_write == 0 && !write_data(zck, zck->temp_fd, dst, dst_size)) { free(dst); return false; } @@ -645,7 +645,7 @@ ssize_t ZCK_PUBLIC_API zck_end_chunk(zckCtx *zck) { if(!zck->comp.end_cchunk(zck, &(zck->comp), &dst, &dst_size, 1)) return -1; zck->comp.dc_data_size = 0; - if(dst_size > 0 && !write_data(zck, zck->temp_fd, dst, dst_size)) { + if(zck->no_write == 0 && dst_size > 0 && !write_data(zck, zck->temp_fd, dst, dst_size)) { free(dst); return -1; } diff --git a/src/lib/header.c b/src/lib/header.c index 56d7f1b..565071e 100644 --- a/src/lib/header.c +++ b/src/lib/header.c @@ -462,7 +462,7 @@ bool write_header(zckCtx *zck) { "Writing header: %llu bytes", (long long unsigned) zck->lead_size ); - if(!write_data(zck, zck->fd, zck->header, zck->header_size)) + if(zck->no_write == 0 && !write_data(zck, zck->fd, zck->header, zck->header_size)) return false; return true; } diff --git a/src/lib/io.c b/src/lib/io.c index 67586c1..2c6d88c 100644 --- a/src/lib/io.c +++ b/src/lib/io.c @@ -114,6 +114,9 @@ ssize_t tell_data(zckCtx *zck) { int chunks_from_temp(zckCtx *zck) { int read_count; + if(zck->no_write == 1) + return true; + if(lseek(zck->temp_fd, 0, SEEK_SET) == -1) return false; diff --git a/src/lib/zck.c b/src/lib/zck.c index 61f92d8..8593281 100644 --- a/src/lib/zck.c +++ b/src/lib/zck.c @@ -349,6 +349,23 @@ bool ZCK_PUBLIC_API zck_set_ioption(zckCtx *zck, zck_ioption option, ssize_t val if(!set_chunk_hash_type(zck, ZCK_HASH_SHA256)) return false; } + } else if(option == ZCK_NO_WRITE) { + if(value == 0) { + if(zck->no_write == 1) { + set_error(zck, "Unable to enable write after it's been disabled"); + return false; + } + zck->no_write = 0; + } else if(value == 1) { + zck->no_write = 1; + if(zck->temp_fd) { + close(zck->temp_fd); + zck->temp_fd = 0; + } + } else { + set_error(zck, "Unknown value %lli for ZCK_NO_WRITE", (long long) value); + return false; + } /* Hash options */ } else if(option < 100) { diff --git a/src/lib/zck_private.h b/src/lib/zck_private.h index e91cf90..49a187e 100644 --- a/src/lib/zck_private.h +++ b/src/lib/zck_private.h @@ -271,6 +271,7 @@ struct zckCtx { int has_streams; int has_optional_elems; int has_uncompressed_source; + int no_write; char *read_buf; size_t read_buf_size; -- 2.30.2