aboutsummaryrefslogtreecommitdiff
path: root/src/backup.cpp
diff options
context:
space:
mode:
authorJan Sucan <jan@jansucan.com>2024-03-24 16:22:08 +0100
committerJán Sučan <jan@jansucan.com>2024-03-24 16:25:41 +0100
commite86c9c6135ba0462c5a352e6d8ea4b730aa9c370 (patch)
tree0c1aa521d865c4a17576d1048692922d895112c9 /src/backup.cpp
parentdde03ff8796277f6ed0f8c8e8b18b83b801d6d27 (diff)
Rewrite the option code in object-oriented way
Diffstat (limited to 'src/backup.cpp')
-rw-r--r--src/backup.cpp112
1 files changed, 87 insertions, 25 deletions
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 <stdlib.h>
#include <string.h>
-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;
}
}