Add ZCK_NO_WRITE option to disable writing to a file
authorJonathan Dieter <jdieter@gmail.com>
Sat, 18 Feb 2023 20:54:28 +0000 (20:54 +0000)
committerJonathan Dieter <jdieter@gmail.com>
Sat, 18 Feb 2023 21:03:07 +0000 (21:03 +0000)
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 <jdieter@gmail.com>
include/zck.h.in
src/lib/comp/comp.c
src/lib/header.c
src/lib/io.c
src/lib/zck.c
src/lib/zck_private.h

index 93f4706802f88701eeea7f1ad646585d65f74a50..d641b206eb6c8f742d8e5f20c57c2a0b441cd005 100644 (file)
@@ -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 */
index 4786e410cfe302eaeeec9917bd8853d94f6264e6..13cb49122c9241be2f6470a2b2d9c0bde1b6ffbb 100644 (file)
@@ -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;
     }
index 56d7f1b7ce8c0adbacdb1ab4c4bcbd647fa244b2..565071e743056d33f5f4cc996a35f056c944f40f 100644 (file)
@@ -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;
 }
index 67586c13ef753e4fa2d8516ef441e06e1d0c5551..2c6d88c74b50f598ae54ae65a2b1aadf96954a51 100644 (file)
@@ -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;
 
index 61f92d8c7967e7d73971ec402c0998cc60a13b6d..859328166d64d3885d9c06809f72eae124d9aa82 100644 (file)
@@ -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) {
index e91cf90de551baca8f9b45fb5d5ebd035cdab018..49a187eafcb6f4e5b59e8f9ed2c9e0fbf90a801b 100644 (file)
@@ -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;