From 3d1ae76ebe7d2248bf5dd9cad8f138ff0caeaae1 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Thu, 2 May 2024 09:36:00 +0200 Subject: [PATCH] core: convert ostctools as C++ Replace some of the memory management by C++ idioms. Signed-off-by: Berthold Stoeger --- Subsurface-mobile.pro | 2 +- core/CMakeLists.txt | 2 +- core/libdivecomputer.h | 36 ++++++------- core/{ostctools.c => ostctools.cpp} | 80 ++++++++++++----------------- 4 files changed, 54 insertions(+), 66 deletions(-) rename core/{ostctools.c => ostctools.cpp} (73%) diff --git a/Subsurface-mobile.pro b/Subsurface-mobile.pro index 447484236..a2dadee57 100644 --- a/Subsurface-mobile.pro +++ b/Subsurface-mobile.pro @@ -81,7 +81,7 @@ SOURCES += subsurface-mobile-main.cpp \ core/version.cpp \ core/save-git.cpp \ core/datatrak.cpp \ - core/ostctools.c \ + core/ostctools.cpp \ core/planner.cpp \ core/save-xml.cpp \ core/cochran.cpp \ diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index dbefcd7b2..3cce0fcf1 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -131,7 +131,7 @@ set(SUBSURFACE_CORE_LIB_SRCS metadata.h metrics.cpp metrics.h - ostctools.c + ostctools.cpp owning_ptrs.h parse-gpx.cpp parse-xml.cpp diff --git a/core/libdivecomputer.h b/core/libdivecomputer.h index 62e7bca5e..556b83dff 100644 --- a/core/libdivecomputer.h +++ b/core/libdivecomputer.h @@ -31,24 +31,24 @@ struct divelog; struct devices; typedef struct { - dc_descriptor_t *descriptor; - const char *vendor, *product, *devname; - const char *model, *btname; - unsigned char *fingerprint; - unsigned int fsize, fdeviceid, fdiveid; - struct dc_event_devinfo_t devinfo; - uint32_t diveid; - dc_device_t *device; - dc_context_t *context; - dc_iostream_t *iostream; - bool force_download; - bool libdc_log; - bool libdc_dump; - bool bluetooth_mode; - bool sync_time; - FILE *libdc_logfile; - struct divelog *log; - void *androidUsbDeviceDescriptor; + dc_descriptor_t *descriptor = nullptr; + const char *vendor = nullptr, *product = nullptr, *devname = nullptr; + const char *model = nullptr, *btname = nullptr; + unsigned char *fingerprint = nullptr; + unsigned int fsize = 0, fdeviceid = 0, fdiveid = 0; + struct dc_event_devinfo_t devinfo = { }; + uint32_t diveid = 0; + dc_device_t *device = nullptr; + dc_context_t *context = nullptr; + dc_iostream_t *iostream = nullptr; + bool force_download = false; + bool libdc_log = false; + bool libdc_dump = false; + bool bluetooth_mode = false; + bool sync_time = false; + FILE *libdc_logfile = nullptr; + struct divelog *log = nullptr; + void *androidUsbDeviceDescriptor = nullptr; } device_data_t; const char *errmsg (dc_status_t rc); diff --git a/core/ostctools.c b/core/ostctools.cpp similarity index 73% rename from core/ostctools.c rename to core/ostctools.cpp index 72db14977..17607302d 100644 --- a/core/ostctools.c +++ b/core/ostctools.cpp @@ -12,23 +12,25 @@ #include "divelog.h" #include "extradata.h" #include "file.h" +#include "format.h" #include "libdivecomputer.h" +#include "owning_ptrs.h" /* * Fills a device_data_t structure with known dc data and a descriptor. */ -static int ostc_prepare_data(int data_model, dc_family_t dc_fam, device_data_t *dev_data) +static int ostc_prepare_data(int data_model, dc_family_t dc_fam, device_data_t &dev_data) { dc_descriptor_t *data_descriptor; - dev_data->device = NULL; - dev_data->context = NULL; + dev_data.device = NULL; + dev_data.context = NULL; data_descriptor = get_descriptor(dc_fam, data_model); if (data_descriptor) { - dev_data->descriptor = data_descriptor; - dev_data->vendor = copy_string(dc_descriptor_get_vendor(data_descriptor)); - dev_data->model = copy_string(dc_descriptor_get_product(data_descriptor)); + dev_data.descriptor = data_descriptor; + dev_data.vendor = copy_string(dc_descriptor_get_vendor(data_descriptor)); + dev_data.model = copy_string(dc_descriptor_get_product(data_descriptor)); } else { return 0; } @@ -40,16 +42,15 @@ static int ostc_prepare_data(int data_model, dc_family_t dc_fam, device_data_t * * each file. So it's not necessary to iterate once and again on a parsing * function. Actually there's only one kind of archive for every DC model. */ -void ostctools_import(const char *file, struct divelog *log) +extern "C" void ostctools_import(const char *file, struct divelog *log) { FILE *archive; - device_data_t *devdata = calloc(1, sizeof(device_data_t)); + device_data_t devdata; dc_family_t dc_fam; - unsigned char *buffer = calloc(65536, 1); + std::vector buffer(65536, 0); unsigned char uc_tmp[2]; - char *tmp; - struct dive *ostcdive = alloc_dive(); - dc_status_t rc = 0; + OwningDivePtr ostcdive(alloc_dive()); + dc_status_t rc = DC_STATUS_SUCCESS; int model, ret, i = 0, c; unsigned int serial; struct extra_data *ptr; @@ -58,41 +59,40 @@ void ostctools_import(const char *file, struct divelog *log) // Open the archive if ((archive = subsurface_fopen(file, "rb")) == NULL) { report_error(failed_to_read_msg, file); - free_dive(ostcdive); - goto out; + return; } // Read dive number from the log if (fseek(archive, 258, 0) == -1) { report_error(failed_to_read_msg, file); - free_dive(ostcdive); - goto close_out; + fclose(archive); + return; } if (fread(uc_tmp, 1, 2, archive) != 2) { report_error(failed_to_read_msg, file); - free_dive(ostcdive); - goto close_out; + fclose(archive); + return; } ostcdive->number = uc_tmp[0] + (uc_tmp[1] << 8); // Read device's serial number if (fseek(archive, 265, 0) == -1) { report_error(failed_to_read_msg, file); - free_dive(ostcdive); - goto close_out; + fclose(archive); + return; } if (fread(uc_tmp, 1, 2, archive) != 2) { report_error(failed_to_read_msg, file); - free_dive(ostcdive); - goto close_out; + fclose(archive); + return; } serial = uc_tmp[0] + (uc_tmp[1] << 8); // Read dive's raw data, header + profile if (fseek(archive, 456, 0) == -1) { report_error(failed_to_read_msg, file); - free_dive(ostcdive); - goto close_out; + fclose(archive); + return; } while ((c = getc(archive)) != EOF) { buffer[i] = c; @@ -102,9 +102,10 @@ void ostctools_import(const char *file, struct divelog *log) } if (ferror(archive)) { report_error(failed_to_read_msg, file); - free_dive(ostcdive); - goto close_out; + fclose(archive); + return; } + fclose(archive); // Try to determine the dc family based on the header type if (buffer[2] == 0x20 || buffer[2] == 0x21) { @@ -120,8 +121,7 @@ void ostctools_import(const char *file, struct divelog *log) break; default: report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number); - free_dive(ostcdive); - goto close_out; + return; } } @@ -151,26 +151,20 @@ void ostctools_import(const char *file, struct divelog *log) ret = ostc_prepare_data(model, dc_fam, devdata); if (ret == 0) { report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number); - free_dive(ostcdive); - goto close_out; + return; } - tmp = calloc(strlen(devdata->vendor) + strlen(devdata->model) + 28, 1); - sprintf(tmp, "%s %s (Imported from OSTCTools)", devdata->vendor, devdata->model); - ostcdive->dc.model = copy_string(tmp); - free(tmp); + std::string tmp = format_string_std("%s %s (Imported from OSTCTools)", devdata.vendor, devdata.model); + ostcdive->dc.model = copy_string(tmp.c_str()); // Parse the dive data - rc = libdc_buffer_parser(ostcdive, devdata, buffer, i + 1); + rc = libdc_buffer_parser(ostcdive.get(), &devdata, buffer.data(), i + 1); if (rc != DC_STATUS_SUCCESS) report_error(translate("gettextFromC", "Error - %s - parsing dive %d"), errmsg(rc), ostcdive->number); // Serial number is not part of the header nor the profile, so libdc won't // catch it. If Serial is part of the extra_data, and set to zero, remove // it from the list and add again. - tmp = calloc(12, 1); - sprintf(tmp, "%d", serial); - ostcdive->dc.serial = copy_string(tmp); - free(tmp); + ostcdive->dc.serial = copy_string(std::to_string(serial).c_str()); if (ostcdive->dc.extra_data) { ptr = ostcdive->dc.extra_data; @@ -183,12 +177,6 @@ void ostctools_import(const char *file, struct divelog *log) } else { add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial); } - record_dive_to_table(ostcdive, log->dives); + record_dive_to_table(ostcdive.release(), log->dives); sort_dive_table(log->dives); - -close_out: - fclose(archive); -out: - free(devdata); - free(buffer); }