core: convert ostctools as C++

Replace some of the memory management by C++ idioms.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-02 09:36:00 +02:00
parent 98693c6ccb
commit 3d1ae76ebe
4 changed files with 54 additions and 66 deletions

View file

@ -81,7 +81,7 @@ SOURCES += subsurface-mobile-main.cpp \
core/version.cpp \ core/version.cpp \
core/save-git.cpp \ core/save-git.cpp \
core/datatrak.cpp \ core/datatrak.cpp \
core/ostctools.c \ core/ostctools.cpp \
core/planner.cpp \ core/planner.cpp \
core/save-xml.cpp \ core/save-xml.cpp \
core/cochran.cpp \ core/cochran.cpp \

View file

@ -131,7 +131,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
metadata.h metadata.h
metrics.cpp metrics.cpp
metrics.h metrics.h
ostctools.c ostctools.cpp
owning_ptrs.h owning_ptrs.h
parse-gpx.cpp parse-gpx.cpp
parse-xml.cpp parse-xml.cpp

View file

@ -31,24 +31,24 @@ struct divelog;
struct devices; struct devices;
typedef struct { typedef struct {
dc_descriptor_t *descriptor; dc_descriptor_t *descriptor = nullptr;
const char *vendor, *product, *devname; const char *vendor = nullptr, *product = nullptr, *devname = nullptr;
const char *model, *btname; const char *model = nullptr, *btname = nullptr;
unsigned char *fingerprint; unsigned char *fingerprint = nullptr;
unsigned int fsize, fdeviceid, fdiveid; unsigned int fsize = 0, fdeviceid = 0, fdiveid = 0;
struct dc_event_devinfo_t devinfo; struct dc_event_devinfo_t devinfo = { };
uint32_t diveid; uint32_t diveid = 0;
dc_device_t *device; dc_device_t *device = nullptr;
dc_context_t *context; dc_context_t *context = nullptr;
dc_iostream_t *iostream; dc_iostream_t *iostream = nullptr;
bool force_download; bool force_download = false;
bool libdc_log; bool libdc_log = false;
bool libdc_dump; bool libdc_dump = false;
bool bluetooth_mode; bool bluetooth_mode = false;
bool sync_time; bool sync_time = false;
FILE *libdc_logfile; FILE *libdc_logfile = nullptr;
struct divelog *log; struct divelog *log = nullptr;
void *androidUsbDeviceDescriptor; void *androidUsbDeviceDescriptor = nullptr;
} device_data_t; } device_data_t;
const char *errmsg (dc_status_t rc); const char *errmsg (dc_status_t rc);

View file

@ -12,23 +12,25 @@
#include "divelog.h" #include "divelog.h"
#include "extradata.h" #include "extradata.h"
#include "file.h" #include "file.h"
#include "format.h"
#include "libdivecomputer.h" #include "libdivecomputer.h"
#include "owning_ptrs.h"
/* /*
* Fills a device_data_t structure with known dc data and a descriptor. * 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; dc_descriptor_t *data_descriptor;
dev_data->device = NULL; dev_data.device = NULL;
dev_data->context = NULL; dev_data.context = NULL;
data_descriptor = get_descriptor(dc_fam, data_model); data_descriptor = get_descriptor(dc_fam, data_model);
if (data_descriptor) { if (data_descriptor) {
dev_data->descriptor = data_descriptor; dev_data.descriptor = data_descriptor;
dev_data->vendor = copy_string(dc_descriptor_get_vendor(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.model = copy_string(dc_descriptor_get_product(data_descriptor));
} else { } else {
return 0; 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 * 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. * 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; FILE *archive;
device_data_t *devdata = calloc(1, sizeof(device_data_t)); device_data_t devdata;
dc_family_t dc_fam; dc_family_t dc_fam;
unsigned char *buffer = calloc(65536, 1); std::vector<unsigned char> buffer(65536, 0);
unsigned char uc_tmp[2]; unsigned char uc_tmp[2];
char *tmp; OwningDivePtr ostcdive(alloc_dive());
struct dive *ostcdive = alloc_dive(); dc_status_t rc = DC_STATUS_SUCCESS;
dc_status_t rc = 0;
int model, ret, i = 0, c; int model, ret, i = 0, c;
unsigned int serial; unsigned int serial;
struct extra_data *ptr; struct extra_data *ptr;
@ -58,41 +59,40 @@ void ostctools_import(const char *file, struct divelog *log)
// Open the archive // Open the archive
if ((archive = subsurface_fopen(file, "rb")) == NULL) { if ((archive = subsurface_fopen(file, "rb")) == NULL) {
report_error(failed_to_read_msg, file); report_error(failed_to_read_msg, file);
free_dive(ostcdive); return;
goto out;
} }
// Read dive number from the log // Read dive number from the log
if (fseek(archive, 258, 0) == -1) { if (fseek(archive, 258, 0) == -1) {
report_error(failed_to_read_msg, file); report_error(failed_to_read_msg, file);
free_dive(ostcdive); fclose(archive);
goto close_out; return;
} }
if (fread(uc_tmp, 1, 2, archive) != 2) { if (fread(uc_tmp, 1, 2, archive) != 2) {
report_error(failed_to_read_msg, file); report_error(failed_to_read_msg, file);
free_dive(ostcdive); fclose(archive);
goto close_out; return;
} }
ostcdive->number = uc_tmp[0] + (uc_tmp[1] << 8); ostcdive->number = uc_tmp[0] + (uc_tmp[1] << 8);
// Read device's serial number // Read device's serial number
if (fseek(archive, 265, 0) == -1) { if (fseek(archive, 265, 0) == -1) {
report_error(failed_to_read_msg, file); report_error(failed_to_read_msg, file);
free_dive(ostcdive); fclose(archive);
goto close_out; return;
} }
if (fread(uc_tmp, 1, 2, archive) != 2) { if (fread(uc_tmp, 1, 2, archive) != 2) {
report_error(failed_to_read_msg, file); report_error(failed_to_read_msg, file);
free_dive(ostcdive); fclose(archive);
goto close_out; return;
} }
serial = uc_tmp[0] + (uc_tmp[1] << 8); serial = uc_tmp[0] + (uc_tmp[1] << 8);
// Read dive's raw data, header + profile // Read dive's raw data, header + profile
if (fseek(archive, 456, 0) == -1) { if (fseek(archive, 456, 0) == -1) {
report_error(failed_to_read_msg, file); report_error(failed_to_read_msg, file);
free_dive(ostcdive); fclose(archive);
goto close_out; return;
} }
while ((c = getc(archive)) != EOF) { while ((c = getc(archive)) != EOF) {
buffer[i] = c; buffer[i] = c;
@ -102,9 +102,10 @@ void ostctools_import(const char *file, struct divelog *log)
} }
if (ferror(archive)) { if (ferror(archive)) {
report_error(failed_to_read_msg, file); report_error(failed_to_read_msg, file);
free_dive(ostcdive); fclose(archive);
goto close_out; return;
} }
fclose(archive);
// Try to determine the dc family based on the header type // Try to determine the dc family based on the header type
if (buffer[2] == 0x20 || buffer[2] == 0x21) { if (buffer[2] == 0x20 || buffer[2] == 0x21) {
@ -120,8 +121,7 @@ void ostctools_import(const char *file, struct divelog *log)
break; break;
default: default:
report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number); report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number);
free_dive(ostcdive); return;
goto close_out;
} }
} }
@ -151,26 +151,20 @@ void ostctools_import(const char *file, struct divelog *log)
ret = ostc_prepare_data(model, dc_fam, devdata); ret = ostc_prepare_data(model, dc_fam, devdata);
if (ret == 0) { if (ret == 0) {
report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number); report_error(translate("gettextFromC", "Unknown DC in dive %d"), ostcdive->number);
free_dive(ostcdive); return;
goto close_out;
} }
tmp = calloc(strlen(devdata->vendor) + strlen(devdata->model) + 28, 1); std::string tmp = format_string_std("%s %s (Imported from OSTCTools)", devdata.vendor, devdata.model);
sprintf(tmp, "%s %s (Imported from OSTCTools)", devdata->vendor, devdata->model); ostcdive->dc.model = copy_string(tmp.c_str());
ostcdive->dc.model = copy_string(tmp);
free(tmp);
// Parse the dive data // 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) if (rc != DC_STATUS_SUCCESS)
report_error(translate("gettextFromC", "Error - %s - parsing dive %d"), errmsg(rc), ostcdive->number); 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 // 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 // catch it. If Serial is part of the extra_data, and set to zero, remove
// it from the list and add again. // it from the list and add again.
tmp = calloc(12, 1); ostcdive->dc.serial = copy_string(std::to_string(serial).c_str());
sprintf(tmp, "%d", serial);
ostcdive->dc.serial = copy_string(tmp);
free(tmp);
if (ostcdive->dc.extra_data) { if (ostcdive->dc.extra_data) {
ptr = ostcdive->dc.extra_data; ptr = ostcdive->dc.extra_data;
@ -183,12 +177,6 @@ void ostctools_import(const char *file, struct divelog *log)
} else { } else {
add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial); 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); sort_dive_table(log->dives);
close_out:
fclose(archive);
out:
free(devdata);
free(buffer);
} }