core: remove device C access code

This was used from C, so there was lots of access code, which is
not necessary.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-31 07:08:54 +02:00 committed by bstoeger
parent 9e3e0a5a05
commit 73f2605ab1
13 changed files with 84 additions and 177 deletions

View file

@ -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<size_t>(index) >= divelog.devices.size())
return;
std::swap(dev->nickName, nickname);
std::swap(divelog.devices[index].nickName, nickname);
emit diveListNotifier.deviceEdited();
}

View file

@ -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) {

View file

@ -108,7 +108,7 @@ private:
// For redo and undo
DivesAndTripsToAdd divesToAdd;
DivesAndSitesToRemove divesAndSitesToRemove;
struct device_table devicesToAddAndRemove;
device_table devicesToAddAndRemove;
// For redo
std::vector<std::unique_ptr<dive_site>> sitesToAdd;

View file

@ -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<device> &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<device> &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<device> &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
{

View file

@ -7,36 +7,32 @@
#include <vector>
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<device>;
// 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<device> devices;
};
struct fingerprint_table {
// Keep the fingerprint records in a vector sorted by (model, serial) - these are uint32_t here
std::vector<fingerprint_record> fingerprints;

View file

@ -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);
}

View file

@ -3,12 +3,13 @@
#define DIVELIST_H
#include "units.h"
#include <vector>
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<device> &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);

View file

@ -13,7 +13,6 @@ divelog::divelog() :
dives(std::make_unique<dive_table>()),
trips(std::make_unique<trip_table>()),
sites(std::make_unique<dive_site_table>()),
devices(std::make_unique<device_table>()),
filter_presets(std::make_unique<filter_preset_table>()),
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();
}

View file

@ -4,18 +4,19 @@
#define DIVELOG_H
#include <memory>
#include <vector>
struct dive_table;
struct trip_table;
class dive_site_table;
struct device_table;
struct device;
struct filter_preset_table;
struct divelog {
std::unique_ptr<dive_table> dives;
std::unique_ptr<trip_table> trips;
std::unique_ptr<dive_site_table> sites;
std::unique_ptr<device_table> devices;
std::vector<device> devices;
std::unique_ptr<filter_preset_table> filter_presets;
bool autogroup;

View file

@ -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 {

View file

@ -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);

View file

@ -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);

View file

@ -568,21 +568,17 @@ static void save_trip(struct membuffer *b, dive_trip_t *trip, bool anonymize)
put_format(b, "</trip>\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, "<divecomputerid");
show_utf8(b, model.c_str(), " model='", "'", 1);
put_format(b, " deviceid='%08x'", calculate_string_hash(serial_nr.c_str()));
show_utf8(b, serial_nr.c_str(), " serial='", "'", 1);
show_utf8(b, nickname.c_str(), " nickname='", "'", 1);
show_utf8(b, d.model.c_str(), " model='", "'", 1);
put_format(b, " deviceid='%08x'", calculate_string_hash(d.serialNumber.c_str()));
show_utf8(b, d.serialNumber.c_str(), " serial='", "'", 1);
show_utf8(b, d.nickName.c_str(), " nickname='", "'", 1);
put_format(b, "/>\n");
}
@ -655,8 +651,7 @@ static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonym
put_format(b, "<divelog program='subsurface' version='%d'>\n<settings>\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);
}