core: remove device-fingerprint C access code

No need to have this code, as all callers are now C++.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-31 08:22:30 +02:00 committed by bstoeger
parent 73f2605ab1
commit 2fd226964c
9 changed files with 69 additions and 128 deletions

View file

@ -8,7 +8,7 @@
#include "selection.h"
#include "core/settings/qPrefDiveComputer.h"
struct fingerprint_table fingerprint_table;
fingerprint_table fingerprints;
static bool same_device(const device &dev1, const device &dev2)
{
@ -133,111 +133,68 @@ std::string get_dc_nickname(const struct divecomputer *dc)
// managing fingerprint data
bool fingerprint_record::operator<(const fingerprint_record &a) const
{
if (model == a.model)
return serial < a.serial;
return model < a.model;
return std::tie(model, serial) < std::tie(a.model, a.serial);
}
// annoyingly, the Cressi Edy doesn't support a serial number (it's always 0), but still uses fingerprints
// so we can't bail on the serial number being 0
unsigned int get_fingerprint_data(const struct fingerprint_table *table, uint32_t model, uint32_t serial, const unsigned char **fp_out)
std::pair<int, const unsigned char *> get_fingerprint_data(const fingerprint_table &table, uint32_t model, uint32_t serial)
{
if (model == 0 || fp_out == nullptr)
return 0;
if (model == 0)
return { 0, nullptr };
struct fingerprint_record fpr = { model, serial };
auto it = std::lower_bound(table->fingerprints.begin(), table->fingerprints.end(), fpr);
if (it != table->fingerprints.end() && it->model == model && it->serial == serial) {
auto it = std::lower_bound(table.begin(), table.end(), fpr);
if (it != table.end() && it->model == model && it->serial == serial) {
// std::lower_bound gets us the first element that isn't smaller than what we are looking
// for - so if one is found, we still need to check for equality
if (has_dive(it->fdeviceid, it->fdiveid)) {
*fp_out = it->raw_data;
return it->fsize;
}
if (has_dive(it->fdeviceid, it->fdiveid))
return { it->fsize, it->raw_data.get() };
}
return 0;
return { 0, nullptr };
}
void create_fingerprint_node(struct fingerprint_table *table, uint32_t model, uint32_t serial,
const unsigned char *raw_data_in, unsigned int fsize, uint32_t fdeviceid, uint32_t fdiveid)
void create_fingerprint_node(fingerprint_table &table, uint32_t model, uint32_t serial,
const unsigned char *raw_data_in, unsigned int fsize, uint32_t fdeviceid, uint32_t fdiveid)
{
// since raw data can contain \0 we copy this manually, not as string
unsigned char *raw_data = (unsigned char *)malloc(fsize);
if (!raw_data)
return;
memcpy(raw_data, raw_data_in, fsize);
auto raw_data = std::make_unique<unsigned char []>(fsize);
std::copy(raw_data_in, raw_data_in + fsize, raw_data.get());
struct fingerprint_record fpr = { model, serial, raw_data, fsize, fdeviceid, fdiveid };
auto it = std::lower_bound(table->fingerprints.begin(), table->fingerprints.end(), fpr);
if (it != table->fingerprints.end() && it->model == model && it->serial == serial) {
struct fingerprint_record fpr = { model, serial, std::move(raw_data), fsize, fdeviceid, fdiveid };
auto it = std::lower_bound(table.begin(), table.end(), fpr);
if (it != table.end() && it->model == model && it->serial == serial) {
// std::lower_bound gets us the first element that isn't smaller than what we are looking
// for - so if one is found, we still need to check for equality - and then we
// can update the existing entry; first we free the memory for the stored raw data
free(it->raw_data);
it->fdeviceid = fdeviceid;
it->fdiveid = fdiveid;
it->raw_data = raw_data;
it->raw_data = std::move(fpr.raw_data);
it->fsize = fsize;
} else {
// insert a new one
table->fingerprints.insert(it, fpr);
table.insert(it, std::move(fpr));
}
}
void create_fingerprint_node_from_hex(struct fingerprint_table *table, uint32_t model, uint32_t serial,
const char *hex_data, uint32_t fdeviceid, uint32_t fdiveid)
void create_fingerprint_node_from_hex(fingerprint_table &table, uint32_t model, uint32_t serial,
const std::string &hex_data, uint32_t fdeviceid, uint32_t fdiveid)
{
QByteArray raw = QByteArray::fromHex(hex_data);
QByteArray raw = QByteArray::fromHex(hex_data.c_str());
create_fingerprint_node(table, model, serial,
(const unsigned char *)raw.constData(), raw.size(), fdeviceid, fdiveid);
}
int nr_fingerprints(struct fingerprint_table *table)
{
return table->fingerprints.size();
}
uint32_t fp_get_model(struct fingerprint_table *table, unsigned int i)
{
if (!table || i >= table->fingerprints.size())
return 0;
return table->fingerprints[i].model;
}
uint32_t fp_get_serial(struct fingerprint_table *table, unsigned int i)
{
if (!table || i >= table->fingerprints.size())
return 0;
return table->fingerprints[i].serial;
}
uint32_t fp_get_deviceid(struct fingerprint_table *table, unsigned int i)
{
if (!table || i >= table->fingerprints.size())
return 0;
return table->fingerprints[i].fdeviceid;
}
uint32_t fp_get_diveid(struct fingerprint_table *table, unsigned int i)
{
if (!table || i >= table->fingerprints.size())
return 0;
return table->fingerprints[i].fdiveid;
}
static char to_hex_digit(unsigned char d)
{
return d <= 9 ? d + '0' : d - 10 + 'a';
}
std::string fp_get_data(struct fingerprint_table *table, unsigned int i)
std::string fingerprint_record::get_data() const
{
if (!table || i >= table->fingerprints.size())
return std::string();
struct fingerprint_record *fpr = &table->fingerprints[i];
std::string res(fpr->fsize * 2, ' ');
for (unsigned int i = 0; i < fpr->fsize; ++i) {
res[2 * i] = to_hex_digit((fpr->raw_data[i] >> 4) & 0xf);
res[2 * i + 1] = to_hex_digit(fpr->raw_data[i] & 0xf);
std::string res(fsize * 2, ' ');
for (unsigned int i = 0; i < fsize; ++i) {
res[2 * i] = to_hex_digit((raw_data[i] >> 4) & 0xf);
res[2 * i + 1] = to_hex_digit(raw_data[i] & 0xf);
}
return res;
}

View file

@ -3,6 +3,7 @@
#define DEVICE_H
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
@ -20,9 +21,6 @@ struct device {
using device_table = std::vector<device>;
// global device table
extern struct fingerprint_table fingerprint_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);
@ -34,20 +32,29 @@ extern int add_to_device_table(device_table &table, const struct device &dev); /
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,
const unsigned char *raw_data, unsigned int fsize, uint32_t fdeviceid, uint32_t fdiveid);
extern void create_fingerprint_node_from_hex(struct fingerprint_table *table, uint32_t model, uint32_t serial,
const char *hex_data, uint32_t fdeviceid, uint32_t fdiveid);
// look up the fingerprint for model/serial - returns the number of bytes in the fingerprint; memory owned by the table
extern unsigned int get_fingerprint_data(const struct fingerprint_table *table, uint32_t model, uint32_t serial, const unsigned char **fp_out);
struct fingerprint_record {
bool operator<(const fingerprint_record &a) const;
uint32_t model; // model and libdivecomputer serial number to
uint32_t serial; // look up the fingerprint
std::unique_ptr<unsigned char[]> raw_data; // fingerprint data as provided by libdivecomputer
unsigned int fsize; // size of raw fingerprint data
unsigned int fdeviceid; // corresponding deviceid
unsigned int fdiveid; // corresponding diveid
std::string get_data() const; // As hex-string
};
// access the fingerprint data from C
extern int nr_fingerprints(struct fingerprint_table *table);
extern uint32_t fp_get_model(struct fingerprint_table *table, unsigned int i);
extern uint32_t fp_get_serial(struct fingerprint_table *table, unsigned int i);
extern uint32_t fp_get_deviceid(struct fingerprint_table *table, unsigned int i);
extern uint32_t fp_get_diveid(struct fingerprint_table *table, unsigned int i);
using fingerprint_table = std::vector<fingerprint_record>;
// global device table
extern fingerprint_table fingerprints;
// create fingerprint entry - raw data remains owned by caller
extern void create_fingerprint_node(fingerprint_table &table, uint32_t model, uint32_t serial,
const unsigned char *raw_data, unsigned int fsize, uint32_t fdeviceid, uint32_t fdiveid);
extern void create_fingerprint_node_from_hex(fingerprint_table &table, uint32_t model, uint32_t serial,
const std::string &hex_data, uint32_t fdeviceid, uint32_t fdiveid);
// look up the fingerprint for model/serial - returns the number of bytes in the fingerprint; memory owned by the table
extern std::pair <int, const unsigned char *> get_fingerprint_data(const fingerprint_table &table, uint32_t model, uint32_t serial);
extern int is_default_dive_computer_device(const char *);
@ -55,21 +62,5 @@ typedef void (*device_callback_t)(const char *name, void *userdata);
extern int enumerate_devices(device_callback_t callback, void *userdata, unsigned int transport);
struct fingerprint_record {
bool operator<(const fingerprint_record &a) const;
uint32_t model; // model and libdivecomputer serial number to
uint32_t serial; // look up the fingerprint
unsigned char *raw_data; // fingerprint data as provided by libdivecomputer
unsigned int fsize; // size of raw fingerprint data
unsigned int fdeviceid; // corresponding deviceid
unsigned int fdiveid; // corresponding diveid
};
struct fingerprint_table {
// Keep the fingerprint records in a vector sorted by (model, serial) - these are uint32_t here
std::vector<fingerprint_record> fingerprints;
};
std::string fp_get_data(struct fingerprint_table *table, unsigned int i);
#endif // DEVICE_H

View file

@ -1010,13 +1010,11 @@ static void verify_fingerprint(dc_device_t *device, device_data_t *devdata, cons
*/
static void lookup_fingerprint(dc_device_t *device, device_data_t *devdata)
{
const unsigned char *raw_data;
if (devdata->force_download)
return;
/* first try our in memory data - raw_data is owned by the table, the dc_device_set_fingerprint function copies the data */
int fsize = get_fingerprint_data(&fingerprint_table, calculate_string_hash(devdata->model.c_str()), devdata->devinfo.serial, &raw_data);
auto [fsize, raw_data] = get_fingerprint_data(fingerprints, calculate_string_hash(devdata->model.c_str()), devdata->devinfo.serial);
if (fsize) {
if (verbose)
dev_info(devdata, "... found fingerprint in dive table");
@ -1538,7 +1536,7 @@ std::string do_libdivecomputer_import(device_data_t *data)
*/
save_fingerprint(data);
if (data->fingerprint && data->fdiveid)
create_fingerprint_node(&fingerprint_table, calculate_string_hash(data->model.c_str()), data->devinfo.serial,
create_fingerprint_node(fingerprints, calculate_string_hash(data->model.c_str()), data->devinfo.serial,
data->fingerprint, data->fsize, data->fdeviceid, data->fdiveid);
free(data->fingerprint);
data->fingerprint = NULL;

View file

@ -1042,8 +1042,8 @@ static void parse_settings_fingerprint(char *line, struct git_parser_state *stat
}
if (verbose > 1)
report_info("fingerprint %08x %08x %08x %08x %s\n", fph.model, fph.serial, fph.fdeviceid, fph.fdiveid, fph.hex_data.c_str());
create_fingerprint_node_from_hex(&fingerprint_table, fph.model, fph.serial,
fph.hex_data.c_str(), fph.fdeviceid, fph.fdiveid);
create_fingerprint_node_from_hex(fingerprints, fph.model, fph.serial,
fph.hex_data, fph.fdeviceid, fph.fdiveid);
}
static void parse_picture_filename(char *, struct git_parser_state *state)

View file

@ -1749,7 +1749,7 @@ int parse_xml_buffer(const char *url, const char *buffer, int, struct divelog *l
struct parser_state state;
state.log = log;
state.fingerprints = &fingerprint_table; // simply use the global table for now
state.fingerprints = &fingerprints; // simply use the global table for now
doc = xmlReadMemory(res, strlen(res), url, NULL, XML_PARSE_HUGE);
if (!doc)
doc = xmlReadMemory(res, strlen(res), url, "latin1", XML_PARSE_HUGE);

View file

@ -162,10 +162,10 @@ void fingerprint_settings_start(struct parser_state *state)
void fingerprint_settings_end(struct parser_state *state)
{
create_fingerprint_node_from_hex(state->fingerprints,
create_fingerprint_node_from_hex(*state->fingerprints,
state->cur_settings.fingerprint.model,
state->cur_settings.fingerprint.serial,
state->cur_settings.fingerprint.data.c_str(),
state->cur_settings.fingerprint.data,
state->cur_settings.fingerprint.fdeviceid,
state->cur_settings.fingerprint.fdiveid);
}

View file

@ -12,9 +12,11 @@
#include <sqlite3.h>
#include <string>
#include <time.h>
#include <vector>
struct xml_params;
struct divelog;
struct fingerprint_record;
/*
* Dive info as it is being built up..
@ -82,7 +84,8 @@ struct parser_state {
struct { std::string key; std::string value; } cur_extra_data;
struct units xml_parsing_units;
struct divelog *log = nullptr; /* non-owning */
struct fingerprint_table *fingerprints = nullptr; /* non-owning */
std::vector<fingerprint_record> *fingerprints = nullptr;
/* non-owning */
sqlite3 *sql_handle = nullptr; /* for SQL based parsers */
bool event_active = false;

View file

@ -847,14 +847,10 @@ static void save_one_device(struct membuffer *b, const struct device &d)
put_string(b, "\n");
}
static void save_one_fingerprint(struct membuffer *b, int i)
static void save_one_fingerprint(struct membuffer *b, const fingerprint_record &fp)
{
put_format(b, "fingerprint model=%08x serial=%08x deviceid=%08x diveid=%08x data=\"%s\"\n",
fp_get_model(&fingerprint_table, i),
fp_get_serial(&fingerprint_table, i),
fp_get_deviceid(&fingerprint_table, i),
fp_get_diveid(&fingerprint_table, i),
fp_get_data(&fingerprint_table, i).c_str());
fp.model, fp.serial, fp.fdeviceid, fp.fdiveid, fp.get_data().c_str());
}
static void save_settings(git_repository *repo, struct dir *tree)
@ -865,8 +861,8 @@ static void save_settings(git_repository *repo, struct dir *tree)
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);
for (auto &fp: fingerprints)
save_one_fingerprint(&b, fp);
cond_put_format(divelog.autogroup, &b, "autogroup\n");
save_units(&b);

View file

@ -582,14 +582,10 @@ static void save_one_device(struct membuffer *b, const struct device &d)
put_format(b, "/>\n");
}
static void save_one_fingerprint(struct membuffer *b, int i)
static void save_one_fingerprint(struct membuffer *b, const fingerprint_record &fp)
{
put_format(b, "<fingerprint model='%08x' serial='%08x' deviceid='%08x' diveid='%08x' data='%s'/>\n",
fp_get_model(&fingerprint_table, i),
fp_get_serial(&fingerprint_table, i),
fp_get_deviceid(&fingerprint_table, i),
fp_get_diveid(&fingerprint_table, i),
fp_get_data(&fingerprint_table, i).c_str());
fp.model, fp.serial, fp.fdeviceid, fp.fdiveid, fp.get_data().c_str());
}
int save_dives(const char *filename)
@ -656,8 +652,8 @@ static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonym
save_one_device(b, d);
}
/* save the fingerprint data */
for (int i = 0; i < nr_fingerprints(&fingerprint_table); i++)
save_one_fingerprint(b, i);
for (auto &fp: fingerprints)
save_one_fingerprint(b, fp);
if (divelog.autogroup)
put_format(b, " <autogroup state='1' />\n");