From e86c9c6135ba0462c5a352e6d8ea4b730aa9c370 Mon Sep 17 00:00:00 2001 From: Jan Sucan Date: Sun, 24 Mar 2024 16:22:08 +0100 Subject: Rewrite the option code in object-oriented way --- src/backup.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 87 insertions(+), 25 deletions(-) (limited to 'src/backup.cpp') diff --git a/src/backup.cpp b/src/backup.cpp index 0b558b6..b0b0054 100644 --- a/src/backup.cpp +++ b/src/backup.cpp @@ -34,14 +34,69 @@ #include #include -static int check_files(const options_backup_t *const opts, +typedef struct { + FILE *in_file; + FILE *ref_file; + FILE *out_file; + + char *in_buffer; + char *ref_buffer; + char *out_buffer; + + size_t out_buffer_size; +} resources_backup_t; + +static int check_files(const OptionsBackup &opts, const resources_backup_t *const res); static int write_out_buffer(const char *const buffer, size_t size, FILE *const file); static int -check_files(const options_backup_t *const opts, - const resources_backup_t *const res) +resources_allocate_for_backup(const OptionsBackup &opts, + resources_backup_t *const res) +{ + if ((res->in_file = fopen(opts.getInFilePath().c_str(), "r")) == NULL) { + print_error("cannot open input file: %s", strerror(errno)); + return 1; + } + + if ((res->ref_file = fopen(opts.getRefFilePath().c_str(), "r")) == NULL) { + print_error("cannot open reference file: %s", strerror(errno)); + return 1; + } + + /* When backing up, the output file is truncated to hold the + * new data + */ + if ((res->out_file = fopen(opts.getOutFilePath().c_str(), "w+")) == NULL) { + print_error("cannot open output file: %s", strerror(errno)); + return 1; + } + + /* The output buffer contains also the offsets */ + res->out_buffer_size = + ((opts.getBufferSize() / opts.getSectorSize()) * sizeof(uint64_t)) + + opts.getBufferSize(); + + // TODO: separate function + if ((res->in_buffer = (char *)malloc(opts.getBufferSize())) == NULL) { + print_error("cannot allocate buffer for input file data"); + return 1; + } else if ((res->ref_buffer = (char *)malloc(opts.getBufferSize())) == + NULL) { + print_error("cannot allocate buffer for reference file data"); + return 1; + } else if ((res->out_buffer = (char *)malloc(res->out_buffer_size)) == + NULL) { + print_error("cannot allocate buffer for output file data"); + return 1; + } + + return 0; +} + +static int +check_files(const OptionsBackup &opts, const resources_backup_t *const res) { bool in_size_ok = false; const size_t in_size = file_size(res->in_file, &in_size_ok); @@ -63,10 +118,10 @@ check_files(const options_backup_t *const opts, if (in_size != ref_size) { print_error("input file and reference file differ in size"); return 1; - } else if ((in_size % opts->sector_size) != 0) { + } else if ((in_size % opts.getSectorSize()) != 0) { print_error( "size of input file and reference file is not multiple of %" PRIu32, - opts->sector_size); + opts.getSectorSize()); return 1; } @@ -87,9 +142,15 @@ write_out_buffer(const char *const buffer, size_t size, FILE *const file) } int -backup(const options_backup_t *const opts, const resources_backup_t *const res) +backup(const OptionsBackup &opts) { - if (check_files(opts, res) != 0) { + resources_backup_t res; + + if (resources_allocate_for_backup(opts, &res) != 0) { + return 1; + } + + if (check_files(opts, &res) != 0) { return 1; } @@ -99,11 +160,12 @@ backup(const options_backup_t *const opts, const resources_backup_t *const res) for (;;) { /* Read the sectors from the input and reference files into the buffers */ - const size_t in_sectors_read = file_read_sectors( - res->in_file, res->in_buffer, opts->buffer_size, opts->sector_size); + const size_t in_sectors_read = + file_read_sectors(res.in_file, res.in_buffer, opts.getBufferSize(), + opts.getSectorSize()); const size_t ref_sectors_read = - file_read_sectors(res->ref_file, res->ref_buffer, opts->buffer_size, - opts->sector_size); + file_read_sectors(res.ref_file, res.ref_buffer, + opts.getBufferSize(), opts.getSectorSize()); if ((in_sectors_read == 0) || (ref_sectors_read == 0)) { break; @@ -115,39 +177,39 @@ backup(const options_backup_t *const opts, const resources_backup_t *const res) /* Process the sectors in the buffers */ for (size_t sector = 0; sector < in_sectors_read; ++sector) { - const size_t buffer_offset = sector * opts->sector_size; + const size_t buffer_offset = sector * opts.getSectorSize(); - if (memcmp(res->in_buffer + buffer_offset, - res->ref_buffer + buffer_offset, - opts->sector_size) != 0) { + if (memcmp(res.in_buffer + buffer_offset, + res.ref_buffer + buffer_offset, + opts.getSectorSize()) != 0) { /* Backup the changed sector */ - if (out_buffer_index >= res->out_buffer_size) { + if (out_buffer_index >= res.out_buffer_size) { /* The output buffer is full. Write it to the output file */ - if (write_out_buffer(res->out_buffer, out_buffer_index, - res->out_file) != 0) { + if (write_out_buffer(res.out_buffer, out_buffer_index, + res.out_file) != 0) { return 1; } out_buffer_index = 0; } /* Write the next backup record */ const uint64_t o = htole64(input_file_offset); - memcpy(res->out_buffer + out_buffer_index, (void *)&o, + memcpy(res.out_buffer + out_buffer_index, (void *)&o, sizeof(o)); out_buffer_index += sizeof(o); - memcpy(res->out_buffer + out_buffer_index, - res->in_buffer + buffer_offset, opts->sector_size); - out_buffer_index += opts->sector_size; + memcpy(res.out_buffer + out_buffer_index, + res.in_buffer + buffer_offset, opts.getSectorSize()); + out_buffer_index += opts.getSectorSize(); } - input_file_offset += opts->sector_size; + input_file_offset += opts.getSectorSize(); } } /* Write out the output buffer */ if (out_buffer_index > 0) { - if (write_out_buffer(res->out_buffer, out_buffer_index, - res->out_file) != 0) { + if (write_out_buffer(res.out_buffer, out_buffer_index, res.out_file) != + 0) { return 1; } } -- cgit v1.2.3