ss_bsdiff: Refactoring 09/271109/5
authorMateusz Moscicki <m.moscicki2@partner.samsung.com>
Fri, 11 Feb 2022 13:27:18 +0000 (14:27 +0100)
committerMateusz Moscicki <m.moscicki2@partner.samsung.com>
Mon, 21 Feb 2022 14:59:47 +0000 (15:59 +0100)
Change-Id: I8c5adaacf740f3e43057068c00a5c33f6900736f

bsdiff/ss_bsdiff.c

index 848e7ff..13ef124 100755 (executable)
@@ -29,6 +29,7 @@
 // search function modification and the error handling.
 
 #define _CRT_SECURE_NO_WARNINGS
+#include <assert.h>
 #include <sys/types.h>
 #include <err.h>
 #include <fcntl.h>
@@ -37,6 +38,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/time.h>
+#include <getopt.h>
 
 #include <Alloc.h>
 #include <7zFile.h>
@@ -52,6 +54,7 @@
 #define PATCH_FILE_FORMAT_MOD       // no accumulation of diff and extra in db and eb; immediate write; also write all 3 parts of control stmt at same time
 #define MULTI_THREADING 1            // only with #define CONST_MEMORY_USAGE or #define MAX_MATCH_SIZE
 #define TIME_LIMIT_CHECK 300
+#define TEMP_PATCH_NAME "temp_patch"
 
 /* Take care :
 1) Use either (MAX_MATCH_SIZE or CONST_MEMORY_USAGE) or (none of both).
@@ -105,6 +108,17 @@ struct data_thread {
        FILE * pfbz2;
 };
 
+enum compression_method {
+       CM_LZMA,
+};
+
+struct bsdiff_info {
+       const char *old_file;
+       const char *new_file;
+       const char *patch_file;
+       enum compression_method comp_method;
+};
+
 struct data_thread data;
 
 int Function(int);
@@ -181,32 +195,33 @@ static void offtout(off_t x, u_char *buf)
                buf[7] |= 0x80;
 }
 
-int create_patch(int argc, const char *argv[], int offset_oldscore)
+int create_patch(const char *old_file, const char *new_file, const char *temp_patch, int offset_oldscore)
 {
+       assert(old_file);
+       assert(new_file);
+
        data.num_threads = MULTI_THREADING;
        data.new = (u_char **)malloc(sizeof(u_char *)*data.num_threads);
-       if (argc != 4)
-               errx(1, "usage: %s oldfile newfile patchfile\n", argv[0]);
 
        /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
                that we never try to malloc(0) and get a NULL pointer */
-       if (((data.fd = open(argv[1], O_RDONLY, 0)) < 0) ||
+       if (((data.fd = open(old_file, O_RDONLY, 0)) < 0) ||
                        ((data.oldsize = lseek(data.fd, 0, SEEK_END)) == -1) ||
                        ((data.old = malloc(data.oldsize + 1)) == NULL) ||
                        (lseek(data.fd, 0, SEEK_SET) != 0) ||
                        (read(data.fd, data.old, data.oldsize) != data.oldsize) ||
                        (close(data.fd) == -1))
-               err(1, "%s", argv[1]);
+               err(1, "%s", old_file);
 
        data.I = malloc((data.oldsize + 1) * sizeof(saidx_t));
        divsufsort(data.old, data.I, data.oldsize);
 
        /* Allocate newsize+1 bytes instead of newsize bytes to ensure
                that we never try to malloc(0) and get a NULL pointer */
-       if (((data.fd = open(argv[2], O_RDONLY, 0)) < 0) ||
+       if (((data.fd = open(new_file, O_RDONLY, 0)) < 0) ||
                        ((data.newsize = lseek(data.fd, 0, SEEK_END)) == -1) ||
                        (lseek(data.fd, 0, SEEK_SET) != 0))
-               err(1, "%s", argv[2]);
+               err(1, "%s", new_file);
        data.size_thread = (data.newsize / data.num_threads);
 
        unsigned int j;
@@ -215,21 +230,21 @@ int create_patch(int argc, const char *argv[], int offset_oldscore)
                        if (((data.new[j] = (u_char *)malloc(sizeof(u_char) * (data.size_thread + 1))) == NULL) ||
                                        (lseek(data.fd, 0, SEEK_CUR) != j * data.size_thread) ||
                                        (read(data.fd, data.new[j], data.size_thread) != data.size_thread))
-                               err(1, "%s", argv[2]);
+                               err(1, "%s", new_file);
                } else {
                        if (((data.new[j] = (u_char *)malloc(sizeof(u_char) * (data.newsize - (j * data.size_thread) + 1))) == NULL) ||
                                        (lseek(data.fd, 0, SEEK_CUR) != j * data.size_thread) ||
                                        (read(data.fd, data.new[j], data.newsize - (j * data.size_thread)) != data.newsize - (j * data.size_thread)))
-                               err(1, "here %s", argv[2]);
+                               err(1, "here %s", new_file);
                }
        }
 
        if ((close(data.fd) == -1))
-               err(1, "%s", argv[2]);
+               err(1, "%s", new_file);
 
        /* Create the patch file */
-       if ((data.pf = fopen("temp_patch", "w")) == NULL)
-               err(1, "%s", "temp_patch");
+       if ((data.pf = fopen(temp_patch, "w")) == NULL)
+               err(1, "%s", temp_patch);
 
        /* Header is
                0       8        "BSDIFF40"
@@ -245,7 +260,7 @@ int create_patch(int argc, const char *argv[], int offset_oldscore)
 
        offtout(data.newsize, data.header + 8);
        if (fwrite(data.header, 16, 1, data.pf) != 1)
-               err(1, "fwrite(%s)", "temp_patch");
+               err(1, "fwrite(%s)", temp_patch);
 
        /* Compute the differences, writing ctrl as we go */
        data.pfbz2 = data.pf;
@@ -261,7 +276,7 @@ int create_patch(int argc, const char *argv[], int offset_oldscore)
 #ifdef TIME_LIMIT_CHECK
        if (ret != 0) {
                printf("bsdiff fails to create delta with offset score %d\n", offset_oldscore);
-               printf("Old: [%s] -> New: [%s]\n", argv[1], argv[2]);
+               printf("Old: [%s] -> New: [%s]\n", old_file, new_file);
        }
 #endif
        /* Seek to the beginning, write the header, and close the file */
@@ -269,7 +284,7 @@ int create_patch(int argc, const char *argv[], int offset_oldscore)
                err(1, "fseeko");
 
        if (fwrite(data.header, 16, 1, data.pf) != 1)
-               err(1, "fwrite(%s)", "temp_patch");
+               err(1, "fwrite(%s)", temp_patch);
        if (fclose(data.pf))
                err(1, "fclose");
        /* Free the memory we used */
@@ -475,7 +490,7 @@ int PrintUserError(char *buffer, int buf_size)
 #define OUT_BUF_SIZE (1 << 16)
 
 
-static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs)
+static SRes lzma_encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 fileSize, char *rs)
 {
        CLzmaEncHandle enc;
        SRes res;
@@ -509,8 +524,11 @@ static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 file
        return res;
 }
 
-int main2(int numArgs, const char *args[], char *rs, int rs_size)
+int lzma_compress(const char *input_file, const char *output_file, char *rs, int rs_size)
 {
+       assert(patch_file);
+       assert(rs);
+
        CFileSeqInStream inStream;
        CFileOutStream outStream;
        int res;
@@ -526,17 +544,17 @@ int main2(int numArgs, const char *args[], char *rs, int rs_size)
        if (t4 != 4 || t8 != 8)
                return PrintError(rs, "Incorrect UInt32 or UInt64", rs_size);
 
-       if (InFile_Open(&inStream.file, "temp_patch") != 0)
+       if (InFile_Open(&inStream.file, input_file) != 0)
                return PrintError(rs, "Can not open input file", rs_size);
 
 
-       if (OutFile_Open(&outStream.file, args[3]) != 0)
+       if (OutFile_Open(&outStream.file, output_file) != 0)
                return PrintError(rs, "Can not open output file", rs_size);
 
 
        UInt64 fileSize;
        File_GetLength(&inStream.file, &fileSize);
-       res = Encode(&outStream.s, &inStream.s, fileSize, rs);
+       res = lzma_encode(&outStream.s, &inStream.s, fileSize, rs);
 
        File_Close(&outStream.file);
        File_Close(&inStream.file);
@@ -555,28 +573,73 @@ int main2(int numArgs, const char *args[], char *rs, int rs_size)
        return 0;
 }
 
-int MY_CDECL main(int numArgs, const char *args[])
+void print_help(const char *arg0)
+{
+       assert(arg0);
+       errx(1, "ss_bsdiff Version 5.0\nUsage: %s oldfile newfile patchfile\n", arg0);
+}
+
+int parse_args(struct bsdiff_info *info, int argc, char *argv[])
+{
+       assert(info);
+       assert(argv);
+
+       struct option long_options[] = {
+               {"compression", optional_argument, NULL, 'c'},
+               {0, 0 , 0, 0}
+       };
+
+       int opt;
+
+       while ((opt = getopt_long(argc, argv, "c:", long_options, NULL)) != -1) {
+               switch (opt) {
+                       case 'c':
+                               if (strcmp("lzma", optarg) == 0)
+                                       info->comp_method = CM_LZMA;
+                               else {
+                                       err(1, "Unknown compression method: %s", optarg);
+                                       return -1;
+                               }
+               }
+       }
+
+       if (optind + 2 >= argc) {
+               err(1, "Not enough parameters");
+               print_help(argv[0]);
+               return -1;
+       }
+
+       info->old_file = argv[optind];
+       info->new_file = argv[optind+1];
+       info->patch_file = argv[optind+2];
+
+       return 0;
+}
+
+int MY_CDECL main(int argc, char *argv[])
 {
        char rs[800] = { 0 };
-       if (numArgs != 4)
-               errx(1, "ss_bsdiff Version 5.0\nUsage: ss_bsdiff oldfile newfile patchfile\n");
 
-       int ret = create_patch(numArgs, args, 8);
+       struct bsdiff_info info;
+       if (parse_args(&info, argc, argv) != 0)
+               return 1;
+
+       int ret = create_patch(info.old_file, info.new_file, TEMP_PATCH_NAME, 8);
 #ifdef TIME_LIMIT_CHECK
        if (ret != 0) {
                printf("Trying with offset score 2\n");
-               ret = create_patch(numArgs, args, 2);
+               ret = create_patch(info.old_file, info.new_file, TEMP_PATCH_NAME, 2);
        }
        if (ret != 0) {
                printf("Trying with offset score 0\n");
-               ret = create_patch(numArgs, args, 0);
+               ret = create_patch(info.old_file, info.new_file, TEMP_PATCH_NAME, 0);
        }
        if (ret != 0)
                err(1, "bsdiff fails to create delta within timelimit");
 #endif
-       int res = main2(numArgs, args, rs, sizeof(rs));
-       if (remove("temp_patch") < 0)
-               printf("Failed to remove temp_patch\n");
+       int res = lzma_compress(TEMP_PATCH_NAME, info.patch_file, rs, sizeof(rs));
+       if (remove(TEMP_PATCH_NAME) < 0)
+               printf("Failed to remove %s\n", TEMP_PATCH_NAME);
        fputs(rs, stdout);
        return res;
 }