diff --git a/core/dive.cpp b/core/dive.cpp index 7304b5eff..10e98ae6b 100644 --- a/core/dive.cpp +++ b/core/dive.cpp @@ -19,6 +19,7 @@ #include "extradata.h" #include "interpolate.h" #include "qthelper.h" +#include "range.h" #include "membuffer.h" #include "picture.h" #include "sample.h" @@ -174,13 +175,6 @@ int dive_getUniqID() return maxId; } -/* copy an element in a list of dive computer extra data */ -static void copy_extra_data(struct extra_data *sed, struct extra_data *ded) -{ - ded->key = copy_string(sed->key); - ded->value = copy_string(sed->value); -} - /* this is very different from the copy_dive_computer later in this file; * this function actually makes full copies of the content */ static void copy_dc(const struct divecomputer *sdc, struct divecomputer *ddc) @@ -188,7 +182,6 @@ static void copy_dc(const struct divecomputer *sdc, struct divecomputer *ddc) *ddc = *sdc; copy_samples(sdc, ddc); copy_events(sdc, ddc); - STRUCTURED_LIST_COPY(struct extra_data, sdc->extra_data, ddc->extra_data, copy_extra_data); } static void dc_cylinder_renumber(struct dive *dive, struct divecomputer *dc, const int mapping[]); @@ -1453,26 +1446,9 @@ static void merge_samples(struct divecomputer *res, } } -/* - * Does the extradata key/value pair already exist in the - * supplied dive computer data? - * - * This is not hugely efficient (with the whole "do this for - * every value you merge" it's O(n**2)) but it's not like we - * have very many extra_data entries per dive computer anyway. - */ -static bool extra_data_exists(const struct extra_data *ed, const struct divecomputer *dc) +static bool operator==(const struct extra_data &e1, const struct extra_data &e2) { - const struct extra_data *p; - - for (p = dc->extra_data; p; p = p->next) { - if (strcmp(p->key, ed->key)) - continue; - if (strcmp(p->value, ed->value)) - continue; - return true; - } - return false; + return std::tie(e1.key, e1.value) == std::tie(e2.key, e2.value); } /* @@ -1480,29 +1456,20 @@ static bool extra_data_exists(const struct extra_data *ed, const struct divecomp * * The extra data from 'a' has already been copied into 'res'. So * we really should just copy over the data from 'b' too. + * + * This is not hugely efficient (with the whole "check this for + * every value you merge" it's O(n**2)) but it's not like we + * have very many extra_data entries per dive computer anyway. */ static void merge_extra_data(struct divecomputer *res, const struct divecomputer *a, const struct divecomputer *b) { - struct extra_data **ed, *src; - - // Find the place to add things in the result - ed = &res->extra_data; - while (*ed) - ed = &(*ed)->next; - - for (src = b->extra_data; src; src = src->next) { - if (extra_data_exists(src, a)) + for (auto &ed: b->extra_data) { + if (range_contains(a->extra_data, ed)) continue; - *ed = (extra_data *)malloc(sizeof(struct extra_data)); - if (!*ed) - break; - copy_extra_data(src, *ed); - ed = &(*ed)->next; - } - // Terminate the result list - *ed = NULL; + res->extra_data.push_back(ed); + } } static char *merge_text(const char *a, const char *b, const char *sep) @@ -2449,7 +2416,6 @@ static const struct divecomputer *find_matching_computer(const struct divecomput static void copy_dive_computer(struct divecomputer *res, const struct divecomputer *a) { *res = *a; - STRUCTURED_LIST_COPY(struct extra_data, a->extra_data, res->extra_data, copy_extra_data); res->samples = res->alloc_samples = 0; res->sample = NULL; res->events = NULL; @@ -3415,19 +3381,19 @@ int dive_has_gps_location(const struct dive *dive) * or GPS2 extra data fields */ static location_t dc_get_gps_location(const struct divecomputer *dc) { - location_t res = { }; + location_t res; - for (struct extra_data *data = dc->extra_data; data; data = data->next) { - if (!strcmp(data->key, "GPS1")) { - parse_location(data->value, &res); + for (const auto &data: dc->extra_data) { + if (data.key == "GPS1") { + parse_location(data.value.c_str(), &res); /* If we found a valid GPS1 field exit early since * it has priority over GPS2 */ if (has_location(&res)) break; - } else if (!strcmp(data->key, "GPS2")) { + } else if (data.key == "GPS2") { /* For GPS2 fields continue searching, as we might * still find a GPS1 field */ - parse_location(data->value, &res); + parse_location(data.value.c_str(), &res); } } return res; diff --git a/core/divecomputer.cpp b/core/divecomputer.cpp index e42f75654..131758226 100644 --- a/core/divecomputer.cpp +++ b/core/divecomputer.cpp @@ -20,6 +20,8 @@ divecomputer::~divecomputer() free_dc_contents(this); } +divecomputer::divecomputer(divecomputer &&) = default; + /* * Good fake dive profiles are hard. * @@ -483,26 +485,16 @@ void remove_event_from_dc(struct divecomputer *dc, struct event *event) } } -void add_extra_data(struct divecomputer *dc, const char *key, const char *value) +void add_extra_data(struct divecomputer *dc, const std::string &key, const std::string &value) { - struct extra_data **ed = &dc->extra_data; - - if (!strcasecmp(key, "Serial")) { - dc->deviceid = calculate_string_hash(value); + if (key == "Serial") { + dc->deviceid = calculate_string_hash(value.c_str()); dc->serial = value; } - if (!strcmp(key, "FW Version")) { + if (key == "FW Version") dc->fw_version = value; - } - while (*ed) - ed = &(*ed)->next; - *ed = (struct extra_data *)malloc(sizeof(struct extra_data)); - if (*ed) { - (*ed)->key = strdup(key); - (*ed)->value = strdup(value); - (*ed)->next = NULL; - } + dc->extra_data.push_back(extra_data { key, value }); } /* @@ -534,17 +526,10 @@ int match_one_dc(const struct divecomputer *a, const struct divecomputer *b) return a->diveid == b->diveid && a->when == b->when ? 1 : -1; } -static void free_extra_data(struct extra_data *ed) -{ - free((void *)ed->key); - free((void *)ed->value); -} - void free_dc_contents(struct divecomputer *dc) { free(dc->sample); free_events(dc->events); - STRUCTURED_LIST_FREE(struct extra_data, dc->extra_data, free_extra_data); } static const char *planner_dc_name = "planned dive"; diff --git a/core/divecomputer.h b/core/divecomputer.h index eb1c914bc..1e7240809 100644 --- a/core/divecomputer.h +++ b/core/divecomputer.h @@ -5,6 +5,7 @@ #include "divemode.h" #include "units.h" #include +#include struct extra_data; struct sample; @@ -39,11 +40,12 @@ struct divecomputer { int samples = 0, alloc_samples = 0; struct sample *sample = nullptr; struct event *events = nullptr; - struct extra_data *extra_data = nullptr; + std::vector extra_data; struct divecomputer *next = nullptr; divecomputer(); ~divecomputer(); + divecomputer(divecomputer &&); }; extern void fake_dc(struct divecomputer *dc); @@ -65,7 +67,7 @@ extern void copy_samples(const struct divecomputer *s, struct divecomputer *d); extern void add_event_to_dc(struct divecomputer *dc, struct event *ev); extern struct event *add_event(struct divecomputer *dc, unsigned int time, int type, int flags, int value, const std::string &name); extern void remove_event_from_dc(struct divecomputer *dc, struct event *event); -extern void add_extra_data(struct divecomputer *dc, const char *key, const char *value); +extern void add_extra_data(struct divecomputer *dc, const std::string &key, const std::string &value); extern uint32_t calculate_string_hash(const char *str); extern bool is_dc_planner(const struct divecomputer *dc); extern void make_planner_dc(struct divecomputer *dc); diff --git a/core/divelist.cpp b/core/divelist.cpp index 9cf5023d8..21795f499 100644 --- a/core/divelist.cpp +++ b/core/divelist.cpp @@ -616,12 +616,6 @@ void update_cylinder_related_info(struct dive *dive) } } -/* Like strcmp(), but don't crash on null-pointers */ -static int safe_strcmp(const char *s1, const char *s2) -{ - return strcmp(s1 ? s1 : "", s2 ? s2 : ""); -} - /* Compare a list of dive computers by model name */ static int comp_dc(const struct divecomputer *dc1, const struct divecomputer *dc2) { diff --git a/core/extradata.h b/core/extradata.h index 4f9a72f20..d81ad17ad 100644 --- a/core/extradata.h +++ b/core/extradata.h @@ -2,10 +2,11 @@ #ifndef EXTRADATA_H #define EXTRADATA_H +#include + struct extra_data { - const char *key; - const char *value; - struct extra_data *next; + std::string key; + std::string value; }; #endif diff --git a/core/import-csv.cpp b/core/import-csv.cpp index 6c8208fb5..2d148ed34 100644 --- a/core/import-csv.cpp +++ b/core/import-csv.cpp @@ -548,7 +548,7 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log) std::string value = parse_mkvi_value(lineptr, key.c_str()); if (value.empty()) break; - add_extra_data(&dive->dc, key.c_str(), value.c_str()); + add_extra_data(&dive->dc, key, value); } dc = &dive->dc; diff --git a/core/load-git.cpp b/core/load-git.cpp index 29b3b8aaa..3f892522c 100644 --- a/core/load-git.cpp +++ b/core/load-git.cpp @@ -828,7 +828,7 @@ static void parse_dc_keyvalue(char *line, struct git_parser_state *state) if (state->converted_strings.size() != 2) return; - add_extra_data(state->active_dc, state->converted_strings[0].c_str(), state->converted_strings[1].c_str()); + add_extra_data(state->active_dc, state->converted_strings[0], state->converted_strings[1]); } static void parse_dc_event(char *line, struct git_parser_state *state) diff --git a/core/ostctools.cpp b/core/ostctools.cpp index 4355c0e82..a1ec4bb9d 100644 --- a/core/ostctools.cpp +++ b/core/ostctools.cpp @@ -52,7 +52,6 @@ void ostctools_import(const char *file, struct divelog *log) dc_status_t rc = DC_STATUS_SUCCESS; int model, ret, i = 0, c; unsigned int serial; - struct extra_data *ptr; const char *failed_to_read_msg = translate("gettextFromC", "Failed to read '%s'"); // Open the archive @@ -161,21 +160,16 @@ void ostctools_import(const char *file, struct divelog *log) 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. + // catch it. If Serial is part of the extra_data, and set to zero, replace it. ostcdive->dc.serial = std::to_string(serial); - if (ostcdive->dc.extra_data) { - ptr = ostcdive->dc.extra_data; - while (strcmp(ptr->key, "Serial")) - ptr = ptr->next; - if (!strcmp(ptr->value, "0")) { - add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial.c_str()); - *ptr = *(ptr)->next; - } - } else { - add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial.c_str()); - } + auto it = find_if(ostcdive->dc.extra_data.begin(), ostcdive->dc.extra_data.end(), + [](auto &ed) { return ed.key == "Serial"; }); + if (it != ostcdive->dc.extra_data.end() && it->value == "0") + it->value = ostcdive->dc.serial.c_str(); + else if (it == ostcdive->dc.extra_data.end()) + add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial); + record_dive_to_table(ostcdive.release(), log->dives.get()); sort_dive_table(log->dives.get()); } diff --git a/core/parse-xml.cpp b/core/parse-xml.cpp index 9e84bc1ba..4a85a58e0 100644 --- a/core/parse-xml.cpp +++ b/core/parse-xml.cpp @@ -2114,20 +2114,21 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) /* device configuration */ switch (((ptr[3] & 0x7f) << 3) + ((ptr[2] & 0xe0) >> 5)) { // Buffer to print extra string into - char config_buf[256]; // Local variables to temporary decode into struct tm tm; const char *device; const char *deep_stops; case 0: // TEST_CCR_FULL_1 utc_mkdate(parse_dlf_timestamp(ptr + 12), &tm); - snprintf(config_buf, sizeof(config_buf), "START=%04u-%02u-%02u %02u:%02u:%02u,TEST=%02X%02X%02X%02X,RESULT=%02X%02X%02X%02X", tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ptr[7], ptr[6], ptr[5], ptr[4], ptr[11], ptr[10], ptr[9], ptr[8]); - add_extra_data(state.cur_dc, "TEST_CCR_FULL_1", config_buf); + add_extra_data(state.cur_dc, "TEST_CCR_FULL_1", + format_string_std("START=%04u-%02u-%02u %02u:%02u:%02u,TEST=%02X%02X%02X%02X,RESULT=%02X%02X%02X%02X", + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ptr[7], ptr[6], ptr[5], ptr[4], ptr[11], ptr[10], ptr[9], ptr[8])); break; case 1: // TEST_CCR_PARTIAL_1 utc_mkdate(parse_dlf_timestamp(ptr + 12), &tm); - snprintf(config_buf, sizeof(config_buf), "START=%04u-%02u-%02u %02u:%02u:%02u,TEST=%02X%02X%02X%02X,RESULT=%02X%02X%02X%02X", tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ptr[7], ptr[6], ptr[5], ptr[4], ptr[11], ptr[10], ptr[9], ptr[8]); - add_extra_data(state.cur_dc, "TEST_CCR_PARTIAL_1", config_buf); + add_extra_data(state.cur_dc, "TEST_CCR_PARTIAL_1", + format_string_std("START=%04u-%02u-%02u %02u:%02u:%02u,TEST=%02X%02X%02X%02X,RESULT=%02X%02X%02X%02X", + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ptr[7], ptr[6], ptr[5], ptr[4], ptr[11], ptr[10], ptr[9], ptr[8])); break; case 2: // CFG_OXYGEN_CALIBRATION utc_mkdate(parse_dlf_timestamp(ptr + 12), &tm); @@ -2135,12 +2136,14 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) o2_sensor_calibration_values[1] = (ptr[7] << 8) + ptr[6]; o2_sensor_calibration_values[2] = (ptr[9] << 8) + ptr[8]; o2_sensor_calibration_values[3] = (ptr[11] << 8) + ptr[10]; - snprintf(config_buf, sizeof(config_buf), "%04u,%04u,%04u,%04u,TIME=%04u-%02u-%02u %02u:%02u:%02u", o2_sensor_calibration_values[0], o2_sensor_calibration_values[1], o2_sensor_calibration_values[2], o2_sensor_calibration_values[3], tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - add_extra_data(state.cur_dc, "CFG_OXYGEN_CALIBRATION", config_buf); + add_extra_data(state.cur_dc, "CFG_OXYGEN_CALIBRATION", + format_string_std("%04u,%04u,%04u,%04u,TIME=%04u-%02u-%02u %02u:%02u:%02u", + o2_sensor_calibration_values[0], o2_sensor_calibration_values[1], o2_sensor_calibration_values[2], o2_sensor_calibration_values[3], tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec)); break; case 3: // CFG_SERIAL - snprintf(config_buf, sizeof(config_buf), "PRODUCT=%c%c%c%c,SERIAL=%c%c%c%c%c%c%c%c", ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]); - add_extra_data(state.cur_dc, "CFG_SERIAL", config_buf); + add_extra_data(state.cur_dc, "CFG_SERIAL", + format_string_std("PRODUCT=%c%c%c%c,SERIAL=%c%c%c%c%c%c%c%c", + ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15])); break; case 4: // CFG_CONFIG_DECO switch ((ptr[5] & 0xC0) >> 6) { @@ -2158,12 +2161,15 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) break; } - snprintf(config_buf, sizeof(config_buf), "%s,%s,%s,safety stop required=%s,last_stop=%s,deco_algorithm=%s,stop_rounding=%u,deep_stops=%s", (ptr[4] & 0x80) ? "imperial" : "metric", (ptr[4] & 0x40) ? "sea" : "fresh", (ptr[4] & 0x30) ? "stops" : "ceiling", (ptr[4] & 0x10) ? "yes" : "no", (ptr[4] & 0x08) ? "6m" : "3m", (ptr[4] & 0x04) ? "VPM" : "Buhlmann+GF", (ptr[4] & 0x03) ? (ptr[4] & 0x03) * 30 : 1, deep_stops); - add_extra_data(state.cur_dc, "CFG_CONFIG_DECO part 1", config_buf); - snprintf(config_buf, sizeof(config_buf), "deep_stop_len=%u min,gas_switch_len=%u min,gf_low=%u,gf_high=%u,gf_low_bailout=%u,gf_high_bailout=%u,ppO2_low=%4.2f,ppO2_high=%4.2f", (ptr[5] & 0x38) >> 3, ptr[5] & 0x07, ptr[6], ptr[7], ptr[8], ptr[9], ptr[10] / 100.0f, ptr[11] / 100.0f); - add_extra_data(state.cur_dc, "CFG_CONFIG_DECO part 2", config_buf); - snprintf(config_buf, sizeof(config_buf), "alarm_global=%u,alarm_cns=%u,alarm_ppO2=%u,alarm_ceiling=%u,alarm_stop_miss=%u,alarm_decentrate=%u,alarm_ascentrate=%u", (ptr[12] & 0x80) >> 7, (ptr[12] & 0x40) >> 6, (ptr[12] & 0x20) >> 5, (ptr[12] & 0x10) >> 4, (ptr[12] & 0x08) >> 3, (ptr[12] & 0x04) >> 2, (ptr[12] & 0x02) >> 1); - add_extra_data(state.cur_dc, "CFG_CONFIG_DECO part 3", config_buf); + add_extra_data(state.cur_dc, "CFG_CONFIG_DECO part 1", + format_string_std("%s,%s,%s,safety stop required=%s,last_stop=%s,deco_algorithm=%s,stop_rounding=%u,deep_stops=%s", + (ptr[4] & 0x80) ? "imperial" : "metric", (ptr[4] & 0x40) ? "sea" : "fresh", (ptr[4] & 0x30) ? "stops" : "ceiling", (ptr[4] & 0x10) ? "yes" : "no", (ptr[4] & 0x08) ? "6m" : "3m", (ptr[4] & 0x04) ? "VPM" : "Buhlmann+GF", (ptr[4] & 0x03) ? (ptr[4] & 0x03) * 30 : 1, deep_stops)); + add_extra_data(state.cur_dc, "CFG_CONFIG_DECO part 2", + format_string_std("deep_stop_len=%u min,gas_switch_len=%u min,gf_low=%u,gf_high=%u,gf_low_bailout=%u,gf_high_bailout=%u,ppO2_low=%4.2f,ppO2_high=%4.2f", + (ptr[5] & 0x38) >> 3, ptr[5] & 0x07, ptr[6], ptr[7], ptr[8], ptr[9], ptr[10] / 100.0f, ptr[11] / 100.0f)); + add_extra_data(state.cur_dc, "CFG_CONFIG_DECO part 3", + format_string_std("alarm_global=%u,alarm_cns=%u,alarm_ppO2=%u,alarm_ceiling=%u,alarm_stop_miss=%u,alarm_decentrate=%u,alarm_ascentrate=%u", + (ptr[12] & 0x80) >> 7, (ptr[12] & 0x40) >> 6, (ptr[12] & 0x20) >> 5, (ptr[12] & 0x10) >> 4, (ptr[12] & 0x08) >> 3, (ptr[12] & 0x04) >> 2, (ptr[12] & 0x02) >> 1)); break; case 5: // CFG_VERSION switch (ptr[4]) { @@ -2180,8 +2186,9 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log) device = "UNKNOWN"; break; } - snprintf(config_buf, sizeof(config_buf), "DEVICE=%s,HW=%d.%d,FW=%d.%d.%d.%d,FLAGS=%04X", device, ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], (ptr[15] << 24) + (ptr[14] << 16) + (ptr[13] << 8) + (ptr[12]), (ptr[11] << 8) + ptr[10]); - add_extra_data(state.cur_dc, "CFG_VERSION", config_buf); + add_extra_data(state.cur_dc, "CFG_VERSION", + format_string_std("DEVICE=%s,HW=%d.%d,FW=%d.%d.%d.%d,FLAGS=%04X", + device, ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], (ptr[15] << 24) + (ptr[14] << 16) + (ptr[13] << 8) + (ptr[12]), (ptr[11] << 8) + ptr[10])); break; } break; diff --git a/core/save-git.cpp b/core/save-git.cpp index d8d85ef0b..0e4de1867 100644 --- a/core/save-git.cpp +++ b/core/save-git.cpp @@ -119,12 +119,11 @@ static void save_tags(struct membuffer *b, struct tag_entry *tags) put_string(b, "\n"); } -static void save_extra_data(struct membuffer *b, struct extra_data *ed) +static void save_extra_data(struct membuffer *b, const struct divecomputer *dc) { - while (ed) { - if (ed->key && ed->value) - put_format(b, "keyvalue \"%s\" \"%s\"\n", ed->key ? : "", ed->value ? : ""); - ed = ed->next; + for (const auto &ed: dc->extra_data) { + if (!ed.key.empty() && !ed.value.empty()) + put_format(b, "keyvalue \"%s\" \"%s\"\n", ed.key.c_str(), ed.value.c_str()); } } @@ -442,7 +441,7 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer save_salinity(b, dc); put_duration(b, dc->surfacetime, "surfacetime ", "min\n"); - save_extra_data(b, dc->extra_data); + save_extra_data(b, dc); save_events(b, dive, dc->events); save_samples(b, dive, dc); } diff --git a/core/save-xml.cpp b/core/save-xml.cpp index 2530df97e..b4748649d 100644 --- a/core/save-xml.cpp +++ b/core/save-xml.cpp @@ -396,16 +396,15 @@ static void save_tags(struct membuffer *b, struct tag_entry *entry) } } -static void save_extra_data(struct membuffer *b, struct extra_data *ed) +static void save_extra_data(struct membuffer *b, const struct divecomputer *dc) { - while (ed) { - if (ed->key && ed->value) { + for (const auto &ed: dc->extra_data) { + if (!ed.key.empty() && !ed.value.empty()) { put_string(b, " key, " key='", "'", 1); - show_utf8(b, ed->value, " value='", "'", 1); + show_utf8(b, ed.key.c_str(), " key='", "'", 1); + show_utf8(b, ed.value.c_str(), " value='", "'", 1); put_string(b, " />\n"); } - ed = ed->next; } } @@ -471,7 +470,7 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer save_airpressure(b, dc); save_salinity(b, dc); put_duration(b, dc->surfacetime, " ", " min\n"); - save_extra_data(b, dc->extra_data); + save_extra_data(b, dc); save_events(b, dive, dc->events); save_samples(b, dive, dc); diff --git a/core/uemis.cpp b/core/uemis.cpp index 22ce6359a..7ff20ea3e 100644 --- a/core/uemis.cpp +++ b/core/uemis.cpp @@ -18,6 +18,7 @@ #include "divecomputer.h" #include "divesite.h" #include "errorhelper.h" +#include "format.h" #include "sample.h" #include #include @@ -356,22 +357,20 @@ void uemis::parse_divelog_binary(std::string_view base64, struct dive *dive) dive->dc.duration.seconds = sample->time.seconds - 1; /* get data from the footer */ - char buffer[24]; - - snprintf(buffer, sizeof(buffer), "%1u.%02u", data[18], data[17]); - add_extra_data(dc, "FW Version", buffer); - snprintf(buffer, sizeof(buffer), "%08x", *(uint32_t *)(data.data() + 9)); - add_extra_data(dc, "Serial", buffer); - snprintf(buffer, sizeof(buffer), "%d", *(uint16_t *)(data.data() + i + 35)); - add_extra_data(dc, "main battery after dive", buffer); - snprintf(buffer, sizeof(buffer), "%0u:%02u", FRACTION_TUPLE(*(uint16_t *)(data.data() + i + 24), 60)); - add_extra_data(dc, "no fly time", buffer); - snprintf(buffer, sizeof(buffer), "%0u:%02u", FRACTION_TUPLE(*(uint16_t *)(data.data() + i + 26), 60)); - add_extra_data(dc, "no dive time", buffer); - snprintf(buffer, sizeof(buffer), "%0u:%02u", FRACTION_TUPLE(*(uint16_t *)(data.data() + i + 28), 60)); - add_extra_data(dc, "desat time", buffer); - snprintf(buffer, sizeof(buffer), "%u", *(uint16_t *)(data.data() + i + 30)); - add_extra_data(dc, "allowed altitude", buffer); + add_extra_data(dc, "FW Version", + format_string_std("%1u.%02u", data[18], data[17])); + add_extra_data(dc, "Serial", + format_string_std("%08x", *(uint32_t *)(data.data() + 9))); + add_extra_data(dc, "main battery after dive", + std::to_string(*(uint16_t *)(data.data() + i + 35))); + add_extra_data(dc, "no fly time", + format_string_std("%0u:%02u", FRACTION_TUPLE(*(uint16_t *)(data.data() + i + 24), 60))); + add_extra_data(dc, "no dive time", + format_string_std("%0u:%02u", FRACTION_TUPLE(*(uint16_t *)(data.data() + i + 26), 60))); + add_extra_data(dc, "desat time", + format_string_std("%0u:%02u", FRACTION_TUPLE(*(uint16_t *)(data.data() + i + 28), 60))); + add_extra_data(dc, "allowed altitude", + std::to_string(*(uint16_t *)(data.data() + i + 30))); return; } diff --git a/qt-models/divecomputerextradatamodel.cpp b/qt-models/divecomputerextradatamodel.cpp index d0cf2d98d..a47e6af82 100644 --- a/qt-models/divecomputerextradatamodel.cpp +++ b/qt-models/divecomputerextradatamodel.cpp @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "qt-models/divecomputerextradatamodel.h" #include "core/divecomputer.h" -#include "core/extradata.h" #include "core/metrics.h" ExtraDataModel::ExtraDataModel(QObject *parent) : CleanerTableModel(parent) @@ -21,7 +20,7 @@ QVariant ExtraDataModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.row() > (int)items.size()) return QVariant(); - const Item &item = items[index.row()]; + const extra_data &item = items[index.row()]; switch (role) { case Qt::FontRole: @@ -31,9 +30,9 @@ QVariant ExtraDataModel::data(const QModelIndex &index, int role) const case Qt::DisplayRole: switch (index.column()) { case KEY: - return item.key; + return QString::fromStdString(item.key); case VALUE: - return item.value; + return QString::fromStdString(item.value); } return QVariant(); } @@ -48,11 +47,9 @@ int ExtraDataModel::rowCount(const QModelIndex&) const void ExtraDataModel::updateDiveComputer(const struct divecomputer *dc) { beginResetModel(); - struct extra_data *ed = dc ? dc->extra_data : nullptr; - items.clear(); - while (ed) { - items.push_back({ ed->key, ed->value }); - ed = ed->next; - } + if (dc) + items = dc->extra_data; + else + items.clear(); endResetModel(); } diff --git a/qt-models/divecomputerextradatamodel.h b/qt-models/divecomputerextradatamodel.h index 9af4028eb..be1d8bb40 100644 --- a/qt-models/divecomputerextradatamodel.h +++ b/qt-models/divecomputerextradatamodel.h @@ -3,6 +3,7 @@ #define DIVECOMPUTEREXTRADATAMODEL_H #include "cleanertablemodel.h" +#include "core/extradata.h" struct divecomputer; @@ -22,11 +23,7 @@ public: void updateDiveComputer(const struct divecomputer *dc); private: - struct Item { - QString key; - QString value; - }; - std::vector items; + std::vector items; }; #endif