diff --git a/commands/command_device.cpp b/commands/command_device.cpp index 13b4ebc7a..b481f5bd2 100644 --- a/commands/command_device.cpp +++ b/commands/command_device.cpp @@ -9,7 +9,7 @@ namespace Command { EditDeviceNickname::EditDeviceNickname(const struct divecomputer *dc, const QString &nicknameIn) : nickname(nicknameIn.toStdString()) { - index = get_or_add_device_for_dc(divelog.devices.get(), dc); + index = get_or_add_device_for_dc(divelog.devices, dc); if (index == -1) return; @@ -18,15 +18,14 @@ EditDeviceNickname::EditDeviceNickname(const struct divecomputer *dc, const QStr bool EditDeviceNickname::workToBeDone() { - return get_device(divelog.devices.get(), index) != nullptr; + return index >= 0; } void EditDeviceNickname::redo() { - device *dev = get_device_mutable(divelog.devices.get(), index); - if (!dev) + if (index < 0 || static_cast(index) >= divelog.devices.size()) return; - std::swap(dev->nickName, nickname); + std::swap(divelog.devices[index].nickName, nickname); emit diveListNotifier.deviceEdited(); } diff --git a/commands/command_divelist.cpp b/commands/command_divelist.cpp index f745f2955..ccb89c6d0 100644 --- a/commands/command_divelist.cpp +++ b/commands/command_divelist.cpp @@ -481,7 +481,7 @@ ImportDives::ImportDives(struct divelog *log, int flags, const QString &source) dive_site_table sites_to_add; process_imported_dives(log, flags, &dives_to_add, &dives_to_remove, &trips_to_add, - sites_to_add, &devicesToAddAndRemove); + sites_to_add, devicesToAddAndRemove); // Add trips to the divesToAdd.trips structure divesToAdd.trips.reserve(trips_to_add.nr); @@ -548,8 +548,8 @@ void ImportDives::redoit() divesAndSitesToRemove = std::move(divesAndSitesToRemoveNew); // Add devices - for (const device &dev: devicesToAddAndRemove.devices) - add_to_device_table(divelog.devices.get(), &dev); + for (const device &dev: devicesToAddAndRemove) + add_to_device_table(divelog.devices, dev); // Add new filter presets for (auto &it: filterPresetsToAdd) { @@ -576,8 +576,8 @@ void ImportDives::undoit() setSelection(selection, currentDive, -1); // Remove devices - for (const device &dev: devicesToAddAndRemove.devices) - remove_device(divelog.devices.get(), &dev); + for (const device &dev: devicesToAddAndRemove) + remove_device(divelog.devices, dev); // Remove filter presets. Do this in reverse order. for (auto it = filterPresetsToRemove.rbegin(); it != filterPresetsToRemove.rend(); ++it) { diff --git a/commands/command_divelist.h b/commands/command_divelist.h index ca550811f..54c4caa8d 100644 --- a/commands/command_divelist.h +++ b/commands/command_divelist.h @@ -108,7 +108,7 @@ private: // For redo and undo DivesAndTripsToAdd divesToAdd; DivesAndSitesToRemove divesAndSitesToRemove; - struct device_table devicesToAddAndRemove; + device_table devicesToAddAndRemove; // For redo std::vector> sitesToAdd; diff --git a/core/device.cpp b/core/device.cpp index 1a9014510..e9a63cc11 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -18,42 +18,35 @@ static bool same_device(const device &dev1, const device &dev2) bool device::operator<(const device &a) const { - int diff; - - diff = model.compare(a.model); - if (diff) - return diff < 0; - - return serialNumber < a.serialNumber; + return std::tie(model, serialNumber) < std::tie(a.model, a.serialNumber); } -const struct device *get_device_for_dc(const struct device_table *table, const struct divecomputer *dc) +const struct device *get_device_for_dc(const device_table &table, const struct divecomputer *dc) { if (dc->model.empty() || dc->serial.empty()) return NULL; - const std::vector &dcs = table->devices; device dev { dc->model, dc->serial }; - auto it = std::lower_bound(dcs.begin(), dcs.end(), dev); - return it != dcs.end() && same_device(*it, dev) ? &*it : NULL; + auto it = std::lower_bound(table.begin(), table.end(), dev); + return it != table.end() && same_device(*it, dev) ? &*it : NULL; } -int get_or_add_device_for_dc(struct device_table *table, const struct divecomputer *dc) +int get_or_add_device_for_dc(device_table &table, const struct divecomputer *dc) { if (dc->model.empty() || dc->serial.empty()) return -1; const struct device *dev = get_device_for_dc(table, dc); if (dev) { - auto it = std::lower_bound(table->devices.begin(), table->devices.end(), *dev); - return it - table->devices.begin(); + auto it = std::lower_bound(table.begin(), table.end(), *dev); + return it - table.begin(); } return create_device_node(table, dc->model, dc->serial, std::string()); } -bool device_exists(const struct device_table *device_table, const struct device *dev) +bool device_exists(const device_table &table, const struct device &dev) { - auto it = std::lower_bound(device_table->devices.begin(), device_table->devices.end(), *dev); - return it != device_table->devices.end() && same_device(*it, *dev); + auto it = std::lower_bound(table.begin(), table.end(), dev); + return it != table.end() && same_device(*it, dev); } void device::showchanges(const std::string &n) const @@ -66,7 +59,7 @@ void device::showchanges(const std::string &n) const } } -static int addDC(std::vector &dcs, const std::string &m, const std::string &s, const std::string &n) +int create_device_node(device_table &dcs, const std::string &m, const std::string &s, const std::string &n) { if (m.empty() || s.empty()) return -1; @@ -86,46 +79,36 @@ static int addDC(std::vector &dcs, const std::string &m, const std::stri } } -int create_device_node(struct device_table *device_table, const std::string &model, const std::string &serial, const std::string &nickname) +int add_to_device_table(device_table &device_table, const struct device &dev) { - return addDC(device_table->devices, model, serial, nickname); + return create_device_node(device_table, dev.model, dev.serialNumber, dev.nickName); } -int add_to_device_table(struct device_table *device_table, const struct device *dev) +int remove_device(device_table &table, const struct device &dev) { - return create_device_node(device_table, dev->model, dev->serialNumber, dev->nickName); -} - -int remove_device(struct device_table *device_table, const struct device *dev) -{ - auto it = std::lower_bound(device_table->devices.begin(), device_table->devices.end(), *dev); - if (it != device_table->devices.end() && same_device(*it, *dev)) { - int idx = it - device_table->devices.begin(); - device_table->devices.erase(it); + auto it = std::lower_bound(table.begin(), table.end(), dev); + if (it != table.end() && same_device(*it, dev)) { + int idx = it - table.begin(); + table.erase(it); return idx; } else { return -1; } } -void remove_from_device_table(struct device_table *device_table, int idx) +void remove_from_device_table(device_table &table, int idx) { - if (idx < 0 || idx >= (int)device_table->devices.size()) + if (idx < 0 || idx >= (int)table.size()) return; - device_table->devices.erase(device_table->devices.begin() + idx); -} - -void clear_device_table(struct device_table *device_table) -{ - device_table->devices.clear(); + table.erase(table.begin() + idx); } /* Returns whether the given device is used by a selected dive. */ -bool device_used_by_selected_dive(const struct device *dev) +bool device_used_by_selected_dive(const struct device &dev) { for (dive *d: getDiveSelection()) { for (auto &dc: d->dcs) { - if (dc.deviceid == dev->deviceId) + if (dc.deviceid == dev.deviceId) return true; } } @@ -139,7 +122,7 @@ int is_default_dive_computer_device(const char *name) std::string get_dc_nickname(const struct divecomputer *dc) { - const device *existNode = get_device_for_dc(divelog.devices.get(), dc); + const device *existNode = get_device_for_dc(divelog.devices, dc); if (existNode && !existNode->nickName.empty()) return existNode->nickName; @@ -147,50 +130,6 @@ std::string get_dc_nickname(const struct divecomputer *dc) return dc->model; } -int nr_devices(const struct device_table *table) -{ - return (int)table->devices.size(); -} - -const struct device *get_device(const struct device_table *table, int i) -{ - if (i < 0 || i > nr_devices(table)) - return NULL; - return &table->devices[i]; -} - -struct device *get_device_mutable(struct device_table *table, int i) -{ - if (i < 0 || i > nr_devices(table)) - return NULL; - return &table->devices[i]; -} - -std::string device_get_model(const struct device *dev) -{ - return dev ? dev->model : std::string(); -} - -std::string device_get_serial(const struct device *dev) -{ - return dev ? dev->serialNumber : std::string(); -} - -std::string device_get_nickname(const struct device *dev) -{ - return dev ? dev->nickName : std::string(); -} - -struct device_table *alloc_device_table() -{ - return new struct device_table; -} - -void free_device_table(struct device_table *devices) -{ - delete devices; -} - // managing fingerprint data bool fingerprint_record::operator<(const fingerprint_record &a) const { diff --git a/core/device.h b/core/device.h index d155588d0..0ad1bd617 100644 --- a/core/device.h +++ b/core/device.h @@ -7,36 +7,32 @@ #include struct divecomputer; -struct device; -struct device_table; struct dive_table; +struct device { + bool operator<(const device &a) const; + void showchanges(const std::string &n) const; + std::string model; + std::string serialNumber; + std::string nickName; + uint32_t deviceId; // Always the string hash of the serialNumber +}; + +using device_table = std::vector; + // global device table extern struct fingerprint_table fingerprint_table; -extern int create_device_node(struct device_table *table, const std::string &model, const std::string &serial, const std::string &nickname); -extern int nr_devices(const struct device_table *table); -extern const struct device *get_device(const struct device_table *table, int i); -extern struct device *get_device_mutable(struct device_table *table, int i); -extern void clear_device_table(struct device_table *table); +extern int create_device_node(device_table &table, const std::string &model, const std::string &serial, const std::string &nickname); std::string get_dc_nickname(const struct divecomputer *dc); -extern bool device_used_by_selected_dive(const struct device *dev); +extern bool device_used_by_selected_dive(const struct device &dev); -extern const struct device *get_device_for_dc(const struct device_table *table, const struct divecomputer *dc); -extern int get_or_add_device_for_dc(struct device_table *table, const struct divecomputer *dc); -extern bool device_exists(const struct device_table *table, const struct device *dev); -extern int add_to_device_table(struct device_table *table, const struct device *dev); // returns index -extern int remove_device(struct device_table *table, const struct device *dev); // returns index or -1 if not found -extern void remove_from_device_table(struct device_table *table, int idx); - -// struct device accessors for C-code. The returned strings are not stable! -std::string device_get_model(const struct device *dev); -std::string device_get_serial(const struct device *dev); -std::string device_get_nickname(const struct device *dev); - -// for C code that needs to alloc/free a device table. (Let's try to get rid of those) -extern struct device_table *alloc_device_table(); -extern void free_device_table(struct device_table *devices); +extern const struct device *get_device_for_dc(const device_table &table, const struct divecomputer *dc); +extern int get_or_add_device_for_dc(device_table &table, const struct divecomputer *dc); +extern bool device_exists(const device_table &table, const struct device &dev); +extern int add_to_device_table(device_table &table, const struct device &dev); // returns index +extern int remove_device(device_table &table, const struct device &dev); // returns index or -1 if not found +extern void remove_from_device_table(device_table &table, int idx); // create fingerprint entry - raw data remains owned by caller extern void create_fingerprint_node(struct fingerprint_table *table, uint32_t model, uint32_t serial, @@ -59,16 +55,6 @@ typedef void (*device_callback_t)(const char *name, void *userdata); extern int enumerate_devices(device_callback_t callback, void *userdata, unsigned int transport); -// Functions and global variables that are only available to C++ code -struct device { - bool operator<(const device &a) const; - void showchanges(const std::string &n) const; - std::string model; - std::string serialNumber; - std::string nickName; - uint32_t deviceId; // Always the string hash of the serialNumber -}; - struct fingerprint_record { bool operator<(const fingerprint_record &a) const; uint32_t model; // model and libdivecomputer serial number to @@ -79,11 +65,6 @@ struct fingerprint_record { unsigned int fdiveid; // corresponding diveid }; -struct device_table { - // Keep the dive computers in a vector sorted by (model, serial) - std::vector devices; -}; - struct fingerprint_table { // Keep the fingerprint records in a vector sorted by (model, serial) - these are uint32_t here std::vector fingerprints; diff --git a/core/divelist.cpp b/core/divelist.cpp index b216c154e..76a6063e7 100644 --- a/core/divelist.cpp +++ b/core/divelist.cpp @@ -934,7 +934,7 @@ void add_imported_dives(struct divelog *import_log, int flags) struct dive_table dives_to_remove = empty_dive_table; struct trip_table trips_to_add = empty_trip_table; dive_site_table dive_sites_to_add; - struct device_table *devices_to_add = alloc_device_table(); + device_table devices_to_add; /* Process imported dives and generate lists of dives * to-be-added and to-be-removed */ @@ -978,16 +978,13 @@ void add_imported_dives(struct divelog *import_log, int flags) divelog.sites->register_site(std::move(ds)); /* Add new devices */ - for (i = 0; i < nr_devices(devices_to_add); i++) { - const struct device *dev = get_device(devices_to_add, i); - add_to_device_table(divelog.devices.get(), dev); - } + for (auto &dev: devices_to_add) + add_to_device_table(divelog.devices, dev); /* We might have deleted the old selected dive. * Choose the newest dive as selected (if any) */ current_dive = divelog.dives->nr > 0 ? divelog.dives->dives[divelog.dives->nr - 1] : NULL; - free_device_table(devices_to_add); free(dives_to_add.dives); free(dives_to_remove.dives); free(trips_to_add.trips); @@ -1066,7 +1063,7 @@ void process_imported_dives(struct divelog *import_log, int flags, /* output parameters: */ struct dive_table *dives_to_add, struct dive_table *dives_to_remove, struct trip_table *trips_to_add, dive_site_table &sites_to_add, - struct device_table *devices_to_add) + device_table &devices_to_add) { int i, j, nr, start_renumbering_at = 0; struct dive_trip *trip_import, *new_trip; @@ -1079,7 +1076,7 @@ void process_imported_dives(struct divelog *import_log, int flags, clear_dive_table(dives_to_remove); clear_trip_table(trips_to_add); sites_to_add.clear(); - clear_device_table(devices_to_add); + devices_to_add.clear(); /* Check if any of the new dives has a number. This will be * important later to decide if we want to renumber the added @@ -1096,9 +1093,8 @@ void process_imported_dives(struct divelog *import_log, int flags, return; /* Add only the devices that we don't know about yet. */ - for (i = 0; i < nr_devices(import_log->devices.get()); i++) { - const struct device *dev = get_device(import_log->devices.get(), i); - if (!device_exists(divelog.devices.get(), dev)) + for (auto &dev: import_log->devices) { + if (!device_exists(divelog.devices, dev)) add_to_device_table(devices_to_add, dev); } diff --git a/core/divelist.h b/core/divelist.h index 2f696291b..e20583f7f 100644 --- a/core/divelist.h +++ b/core/divelist.h @@ -3,12 +3,13 @@ #define DIVELIST_H #include "units.h" +#include struct dive; struct divelog; struct trip_table; class dive_site_table; -struct device_table; +struct device; struct deco_state; struct dive_table { @@ -35,7 +36,7 @@ extern void add_imported_dives(struct divelog *log, int flags); extern void process_imported_dives(struct divelog *import_log, int flags, struct dive_table *dives_to_add, struct dive_table *dives_to_remove, struct trip_table *trips_to_add, dive_site_table &sites_to_add, - struct device_table *devices_to_add); + std::vector &devices_to_add); extern int dive_table_get_insertion_index(struct dive_table *table, struct dive *dive); extern void add_to_dive_table(struct dive_table *table, int idx, struct dive *dive); diff --git a/core/divelog.cpp b/core/divelog.cpp index c32ba7108..47f7dd8c1 100644 --- a/core/divelog.cpp +++ b/core/divelog.cpp @@ -13,7 +13,6 @@ divelog::divelog() : dives(std::make_unique()), trips(std::make_unique()), sites(std::make_unique()), - devices(std::make_unique()), filter_presets(std::make_unique()), autogroup(false) { @@ -55,6 +54,6 @@ void divelog::clear() report_info("Warning: trip table not empty in divelog::clear()!"); trips->nr = 0; } - clear_device_table(devices.get()); + devices.clear(); filter_presets->clear(); } diff --git a/core/divelog.h b/core/divelog.h index 7f245aa69..e105ebe80 100644 --- a/core/divelog.h +++ b/core/divelog.h @@ -4,18 +4,19 @@ #define DIVELOG_H #include +#include struct dive_table; struct trip_table; class dive_site_table; -struct device_table; +struct device; struct filter_preset_table; struct divelog { std::unique_ptr dives; std::unique_ptr trips; std::unique_ptr sites; - std::unique_ptr devices; + std::vector devices; std::unique_ptr filter_presets; bool autogroup; diff --git a/core/load-git.cpp b/core/load-git.cpp index 79c9bbca5..6863ff842 100644 --- a/core/load-git.cpp +++ b/core/load-git.cpp @@ -990,7 +990,7 @@ static void parse_settings_divecomputerid(char *line, struct git_parser_state *s break; line = parse_keyvalue_entry(parse_divecomputerid_keyvalue, &id, line, state); } - create_device_node(state->log->devices.get(), id.model.c_str(), id.serial.c_str(), id.nickname.c_str()); + create_device_node(state->log->devices, id.model.c_str(), id.serial.c_str(), id.nickname.c_str()); } struct fingerprint_helper { diff --git a/core/parse.cpp b/core/parse.cpp index ba3c44784..4e9d3143d 100644 --- a/core/parse.cpp +++ b/core/parse.cpp @@ -177,7 +177,7 @@ void dc_settings_start(struct parser_state *state) void dc_settings_end(struct parser_state *state) { - create_device_node(state->log->devices.get(), + create_device_node(state->log->devices, state->cur_settings.dc.model, state->cur_settings.dc.serial_nr, state->cur_settings.dc.nickname); diff --git a/core/save-git.cpp b/core/save-git.cpp index 49c312651..4565ff343 100644 --- a/core/save-git.cpp +++ b/core/save-git.cpp @@ -835,19 +835,15 @@ static void save_units(void *_b) prefs.units.vertical_speed_time == units::SECONDS ? "SECONDS" : "MINUTES"); } -static void save_one_device(struct membuffer *b, const struct device *d) +static void save_one_device(struct membuffer *b, const struct device &d) { - std::string model = device_get_model(d); - std::string nickname = device_get_nickname(d); - std::string serial = device_get_serial(d); - - if (nickname.empty() || serial.empty()) + if (d.nickName.empty() || d.serialNumber.empty()) return; - show_utf8(b, "divecomputerid ", model.c_str(), ""); - put_format(b, " deviceid=%08x", calculate_string_hash(serial.c_str())); - show_utf8(b, " serial=", serial.c_str(), ""); - show_utf8(b, " nickname=", nickname.c_str(), ""); + show_utf8(b, "divecomputerid ", d.model.c_str(), ""); + put_format(b, " deviceid=%08x", calculate_string_hash(d.serialNumber.c_str())); + show_utf8(b, " serial=", d.serialNumber.c_str(), ""); + show_utf8(b, " nickname=", d.nickName.c_str(), ""); put_string(b, "\n"); } @@ -866,8 +862,8 @@ static void save_settings(git_repository *repo, struct dir *tree) membuffer b; put_format(&b, "version %d\n", DATAFORMAT_VERSION); - for (int i = 0; i < nr_devices(divelog.devices.get()); i++) - save_one_device(&b, get_device(divelog.devices.get(), i)); + for (auto &dev: divelog.devices) + save_one_device(&b, dev); /* save the fingerprint data */ for (int i = 0; i < nr_fingerprints(&fingerprint_table); i++) save_one_fingerprint(&b, i); diff --git a/core/save-xml.cpp b/core/save-xml.cpp index 31ef59e27..604aa89fe 100644 --- a/core/save-xml.cpp +++ b/core/save-xml.cpp @@ -568,21 +568,17 @@ static void save_trip(struct membuffer *b, dive_trip_t *trip, bool anonymize) put_format(b, "\n"); } -static void save_one_device(struct membuffer *b, const struct device *d) +static void save_one_device(struct membuffer *b, const struct device &d) { - std::string model = device_get_model(d); - std::string nickname = device_get_nickname(d); - std::string serial_nr = device_get_serial(d); - /* Nicknames that are empty or the same as the device model are not interesting */ - if (nickname.empty() || serial_nr.empty() || model == nickname) + if (d.nickName.empty() || d.serialNumber.empty() || d.model == d.nickName) return; put_format(b, "\n"); } @@ -655,8 +651,7 @@ static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonym put_format(b, "\n\n", DATAFORMAT_VERSION); /* save the dive computer nicknames, if any */ - for (int i = 0; i < nr_devices(divelog.devices.get()); i++) { - const struct device *d = get_device(divelog.devices.get(), i); + for (auto &d: divelog.devices) { if (!select_only || device_used_by_selected_dive(d)) save_one_device(b, d); }