divelog: turn owning-pointers into unique_ptr<>s

Since everything is C++ now, we can use unique_ptr<>s. This makes
the code significantly shorter, because we can now use the default
move constructor and assignment operators.

This has a semantic change when std::move()-ing the divelog:
now not the contents of the tables are moved, but the pointers.
That is, the moved-from object now has no more tables and
must not be used anymore. This made it necessary to replace
std::move()s by std::swap()s. In that regard, the old code was
in principle broken: it used moved-from objects, which may work
but usually doesn't.

This commit adds a myriad of .get() function calls where the code
expects a C-style pointer. The plan is to remove virtually all of
them, when we move free-standing functions into the class it acts
on. Or, replace C-style pointers by references where we don't support
NULL.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-13 19:34:43 +02:00 committed by bstoeger
parent 6e352d5281
commit d242198c99
22 changed files with 113 additions and 138 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, dc);
index = get_or_add_device_for_dc(divelog.devices.get(), dc);
if (index == -1)
return;
@ -18,12 +18,12 @@ EditDeviceNickname::EditDeviceNickname(const struct divecomputer *dc, const QStr
bool EditDeviceNickname::workToBeDone()
{
return get_device(divelog.devices, index) != nullptr;
return get_device(divelog.devices.get(), index) != nullptr;
}
void EditDeviceNickname::redo()
{
device *dev = get_device_mutable(divelog.devices, index);
device *dev = get_device_mutable(divelog.devices.get(), index);
if (!dev)
return;
std::swap(dev->nickName, nickname);

View file

@ -18,7 +18,7 @@ static void remove_trip_from_backend(dive_trip *trip)
{
if (trip->selected)
deselect_trip(trip);
remove_trip(trip, divelog.trips); // Remove trip from backend
remove_trip(trip, divelog.trips.get()); // Remove trip from backend
}
// This helper function removes a dive, takes ownership of the dive and adds it to a DiveToAdd structure.
@ -78,10 +78,10 @@ dive *DiveListBase::addDive(DiveToAdd &d)
// dives have been added, their status will be updated.
res->hidden_by_filter = true;
int idx = dive_table_get_insertion_index(divelog.dives, res);
fulltext_register(res); // Register the dive's fulltext cache
add_to_dive_table(divelog.dives, idx, res); // Return ownership to backend
invalidate_dive_cache(res); // Ensure that dive is written in git_save()
int idx = dive_table_get_insertion_index(divelog.dives.get(), res);
fulltext_register(res); // Register the dive's fulltext cache
add_to_dive_table(divelog.dives.get(), idx, res); // Return ownership to backend
invalidate_dive_cache(res); // Ensure that dive is written in git_save()
return res;
}
@ -211,7 +211,7 @@ DivesAndSitesToRemove DiveListBase::addDives(DivesAndTripsToAdd &toAdd)
addedTrips.reserve(toAdd.trips.size());
for (OwningTripPtr &trip: toAdd.trips) {
addedTrips.push_back(trip.get());
insert_trip(trip.release(), divelog.trips); // Return ownership to backend
insert_trip(trip.release(), divelog.trips.get()); // Return ownership to backend
}
toAdd.trips.clear();
@ -301,7 +301,7 @@ static void moveDivesBetweenTrips(DivesToTrip &dives)
for (OwningTripPtr &trip: dives.tripsToAdd) {
dive_trip *t = trip.release(); // Give up ownership
createdTrips.push_back(t);
insert_trip(t, divelog.trips); // Return ownership to backend
insert_trip(t, divelog.trips.get()); // Return ownership to backend
}
dives.tripsToAdd.clear();
@ -431,7 +431,7 @@ AddDive::AddDive(dive *d, bool autogroup, bool newNumber)
allocTrip.reset(trip);
}
int idx = dive_table_get_insertion_index(divelog.dives, divePtr.get());
int idx = dive_table_get_insertion_index(divelog.dives.get(), divePtr.get());
if (newNumber)
divePtr->number = get_dive_nr_at_idx(idx);
@ -452,7 +452,7 @@ void AddDive::redoit()
currentDive = current_dive;
divesAndSitesToRemove = addDives(divesToAdd);
sort_trip_table(divelog.trips); // Though unlikely, adding a dive may reorder trips
sort_trip_table(divelog.trips.get()); // Though unlikely, adding a dive may reorder trips
// Select the newly added dive
setSelection(divesAndSitesToRemove.dives, divesAndSitesToRemove.dives[0], -1);
@ -462,7 +462,7 @@ void AddDive::undoit()
{
// Simply remove the dive that was previously added...
divesToAdd = removeDives(divesAndSitesToRemove);
sort_trip_table(divelog.trips); // Though unlikely, removing a dive may reorder trips
sort_trip_table(divelog.trips.get()); // Though unlikely, removing a dive may reorder trips
// ...and restore the selection
setSelection(selection, currentDive, -1);
@ -549,7 +549,7 @@ void ImportDives::redoit()
// Add devices
for (const device &dev: devicesToAddAndRemove.devices)
add_to_device_table(divelog.devices, &dev);
add_to_device_table(divelog.devices.get(), &dev);
// Add new filter presets
for (auto &it: filterPresetsToAdd) {
@ -577,7 +577,7 @@ void ImportDives::undoit()
// Remove devices
for (const device &dev: devicesToAddAndRemove.devices)
remove_device(divelog.devices, &dev);
remove_device(divelog.devices.get(), &dev);
// Remove filter presets. Do this in reverse order.
for (auto it = filterPresetsToRemove.rbegin(); it != filterPresetsToRemove.rend(); ++it) {
@ -606,7 +606,7 @@ bool DeleteDive::workToBeDone()
void DeleteDive::undoit()
{
divesToDelete = addDives(divesToAdd);
sort_trip_table(divelog.trips); // Though unlikely, removing a dive may reorder trips
sort_trip_table(divelog.trips.get()); // Though unlikely, removing a dive may reorder trips
// Select all re-added dives and make the first one current
dive *currentDive = !divesToDelete.dives.empty() ? divesToDelete.dives[0] : nullptr;
@ -616,7 +616,7 @@ void DeleteDive::undoit()
void DeleteDive::redoit()
{
divesToAdd = removeDives(divesToDelete);
sort_trip_table(divelog.trips); // Though unlikely, adding a dive may reorder trips
sort_trip_table(divelog.trips.get()); // Though unlikely, adding a dive may reorder trips
// Deselect all dives and select dive that was close to the first deleted dive
dive *newCurrent = nullptr;
@ -644,8 +644,8 @@ void ShiftTime::redoit()
}
// Changing times may have unsorted the dive and trip tables
sort_dive_table(divelog.dives);
sort_trip_table(divelog.trips);
sort_dive_table(divelog.dives.get());
sort_trip_table(divelog.trips.get());
for (dive_trip *trip: trips)
sort_dive_table(&trip->dives); // Keep the trip-table in order
@ -713,7 +713,7 @@ bool TripBase::workToBeDone()
void TripBase::redoit()
{
moveDivesBetweenTrips(divesToMove);
sort_trip_table(divelog.trips); // Though unlikely, moving dives may reorder trips
sort_trip_table(divelog.trips.get()); // Though unlikely, moving dives may reorder trips
// Select the moved dives
std::vector<dive *> dives;
@ -786,7 +786,7 @@ AutogroupDives::AutogroupDives()
dive_trip *trip;
bool alloc;
int from, to;
for(int i = 0; (trip = get_dives_to_autogroup(divelog.dives, i, &from, &to, &alloc)) != NULL; i = to) {
for(int i = 0; (trip = get_dives_to_autogroup(divelog.dives.get(), i, &from, &to, &alloc)) != NULL; i = to) {
// If this is an allocated trip, take ownership
if (alloc)
divesToMove.tripsToAdd.emplace_back(trip);

View file

@ -1486,8 +1486,8 @@ void EditDive::exchangeDives()
QVector<dive *> dives = { oldDive };
timestamp_t delta = oldDive->when - newDive->when;
if (delta != 0) {
sort_dive_table(divelog.dives);
sort_trip_table(divelog.trips);
sort_dive_table(divelog.dives.get());
sort_trip_table(divelog.trips.get());
if (newDive->divetrip != oldDive->divetrip)
qWarning("Command::EditDive::redo(): This command does not support moving between trips!");
if (oldDive->divetrip)

View file

@ -825,7 +825,7 @@ int try_to_open_cochran(const char *, std::string &mem, struct divelog *log)
break;
cochran_parse_dive(decode, mod, (unsigned char *)mem.data() + dive1,
dive2 - dive1, log->dives);
dive2 - dive1, log->dives.get());
}
return 1; // no further processing needed

View file

@ -700,7 +700,7 @@ int datatrak_import(std::string &mem, std::string &wl_mem, struct divelog *log)
runner = mem.data();
JUMP(runner, 12);
// Secuential parsing. Abort if received NULL from dt_dive_parser.
// Sequential parsing. Abort if received NULL from dt_dive_parser.
while ((i < numdives) && (runner < maxbuf)) {
struct dive *ptdive = alloc_dive();
@ -713,12 +713,12 @@ int datatrak_import(std::string &mem, std::string &wl_mem, struct divelog *log)
rc = 1;
goto out;
} else {
record_dive_to_table(ptdive, log->dives);
record_dive_to_table(ptdive, log->dives.get());
}
i++;
}
out:
sort_dive_table(log->dives);
sort_dive_table(log->dives.get());
return rc;
bail:
return 1;

View file

@ -140,7 +140,7 @@ int is_default_dive_computer_device(const char *name)
const char *get_dc_nickname(const struct divecomputer *dc)
{
const device *existNode = get_device_for_dc(divelog.devices, dc);
const device *existNode = get_device_for_dc(divelog.devices.get(), dc);
if (existNode && !existNode->nickName.empty())
return existNode->nickName.c_str();

View file

@ -758,7 +758,7 @@ struct dive *unregister_dive(int idx)
/* When removing a dive from the global dive table,
* we also have to unregister its fulltext cache. */
fulltext_unregister(dive);
remove_from_dive_table(divelog.dives, idx);
remove_from_dive_table(divelog.dives.get(), idx);
if (dive->selected)
amount_selected--;
dive->selected = false;
@ -767,11 +767,11 @@ struct dive *unregister_dive(int idx)
void process_loaded_dives()
{
sort_dive_table(divelog.dives);
sort_trip_table(divelog.trips);
sort_dive_table(divelog.dives.get());
sort_trip_table(divelog.trips.get());
/* Autogroup dives if desired by user. */
autogroup_dives(divelog.dives, divelog.trips);
autogroup_dives(divelog.dives.get(), divelog.trips.get());
fulltext_populate();
@ -982,12 +982,12 @@ void add_imported_dives(struct divelog *import_log, int flags)
/* Add new dives */
for (i = 0; i < dives_to_add.nr; i++)
insert_dive(divelog.dives, dives_to_add.dives[i]);
insert_dive(divelog.dives.get(), dives_to_add.dives[i]);
dives_to_add.nr = 0;
/* Add new trips */
for (i = 0; i < trips_to_add.nr; i++)
insert_trip(trips_to_add.trips[i], divelog.trips);
insert_trip(trips_to_add.trips[i], divelog.trips.get());
trips_to_add.nr = 0;
/* Add new dive sites */
@ -997,7 +997,7 @@ void add_imported_dives(struct divelog *import_log, int flags)
/* 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, dev);
add_to_device_table(divelog.devices.get(), dev);
}
/* We might have deleted the old selected dive.
@ -1113,20 +1113,20 @@ 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); i++) {
const struct device *dev = get_device(import_log->devices, i);
if (!device_exists(divelog.devices, dev))
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))
add_to_device_table(devices_to_add, dev);
}
/* Sort the table of dives to be imported and combine mergable dives */
sort_dive_table(import_log->dives);
merge_imported_dives(import_log->dives);
sort_dive_table(import_log->dives.get());
merge_imported_dives(import_log->dives.get());
/* Autogroup tripless dives if desired by user. But don't autogroup
* if tripless dives should be added to a new trip. */
if (!(flags & IMPORT_ADD_TO_NEW_TRIP))
autogroup_dives(import_log->dives, import_log->trips);
autogroup_dives(import_log->dives.get(), import_log->trips.get());
/* If dive sites already exist, use the existing versions. */
for (auto &new_ds: *import_log->sites) {
@ -1164,7 +1164,7 @@ void process_imported_dives(struct divelog *import_log, int flags,
for (i = 0; i < import_log->trips->nr; i++) {
trip_import = import_log->trips->trips[i];
if ((flags & IMPORT_MERGE_ALL_TRIPS) || trip_import->autogen) {
if (try_to_merge_trip(trip_import, import_log->dives, flags & IMPORT_PREFER_IMPORTED, dives_to_add, dives_to_remove,
if (try_to_merge_trip(trip_import, import_log->dives.get(), flags & IMPORT_PREFER_IMPORTED, dives_to_add, dives_to_remove,
&sequence_changed, &start_renumbering_at))
continue;
}
@ -1178,7 +1178,7 @@ void process_imported_dives(struct divelog *import_log, int flags,
insert_dive(dives_to_add, d);
sequence_changed |= !dive_is_after_last(d);
remove_dive(d, import_log->dives);
remove_dive(d, import_log->dives.get());
}
/* Then, add trip to list of trips to add */
@ -1205,7 +1205,7 @@ void process_imported_dives(struct divelog *import_log, int flags,
/* The remaining dives in import_log->dives are those that don't belong to
* a trip and the caller does not want them to be associated to a
* new trip. Merge them into the global table. */
sequence_changed |= merge_dive_tables(import_log->dives, NULL, divelog.dives, flags & IMPORT_PREFER_IMPORTED, NULL,
sequence_changed |= merge_dive_tables(import_log->dives.get(), NULL, divelog.dives.get(), flags & IMPORT_PREFER_IMPORTED, NULL,
dives_to_add, dives_to_remove, &start_renumbering_at);
}

View file

@ -54,7 +54,6 @@ int get_min_datafile_version();
void report_datafile_version(int version);
void clear_dive_file_data();
void clear_dive_table(struct dive_table *table);
void move_dive_table(struct dive_table *src, struct dive_table *dst);
struct dive *unregister_dive(int idx);
extern bool has_dive(unsigned int deviceid, unsigned int diveid);

View file

@ -9,15 +9,12 @@
struct divelog divelog;
// We can't use smart pointers, since this is used from C
// and it would be bold to presume that std::unique_ptr<>
// and a plain pointer have the same memory layout.
divelog::divelog() :
dives(new dive_table),
trips(new trip_table),
sites(new dive_site_table),
devices(new device_table),
filter_presets(new filter_preset_table),
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)
{
*dives = empty_dive_table;
@ -26,39 +23,14 @@ divelog::divelog() :
divelog::~divelog()
{
clear_dive_table(dives);
clear_trip_table(trips);
delete dives;
delete trips;
delete sites;
delete devices;
delete filter_presets;
if (dives)
clear_dive_table(dives.get());
if (trips)
clear_trip_table(trips.get());
}
divelog::divelog(divelog &&log) :
dives(new dive_table),
trips(new trip_table),
sites(new dive_site_table(std::move(*log.sites))),
devices(new device_table),
filter_presets(new filter_preset_table)
{
*dives = empty_dive_table;
*trips = empty_trip_table;
move_dive_table(log.dives, dives);
move_trip_table(log.trips, trips);
*devices = std::move(*log.devices);
*filter_presets = std::move(*log.filter_presets);
}
struct divelog &divelog::operator=(divelog &&log)
{
move_dive_table(log.dives, dives);
move_trip_table(log.trips, trips);
*sites = std::move(*log.sites);
*devices = std::move(*log.devices);
*filter_presets = std::move(*log.filter_presets);
return *this;
}
divelog::divelog(divelog &&) = default;
struct divelog &divelog::operator=(divelog &&) = default;
/* this implements the mechanics of removing the dive from the
* dive log and the trip, but doesn't deal with updating dive trips, etc */
@ -69,9 +41,9 @@ void divelog::delete_single_dive(int idx)
return;
}
struct dive *dive = dives->dives[idx];
remove_dive_from_trip(dive, trips);
remove_dive_from_trip(dive, trips.get());
unregister_dive_from_dive_site(dive);
delete_dive_from_table(dives, idx);
delete_dive_from_table(dives.get(), idx);
}
void divelog::clear()
@ -83,6 +55,6 @@ void divelog::clear()
report_info("Warning: trip table not empty in divelog::clear()!");
trips->nr = 0;
}
clear_device_table(devices);
clear_device_table(devices.get());
filter_presets->clear();
}

View file

@ -1,32 +1,33 @@
// SPDX-License-Identifier: GPL-2.0
// A structure that contains all the values we save in a divelog file
// A structure that contains all the data we store in a divelog files
#ifndef DIVELOG_H
#define DIVELOG_H
#include <memory>
struct dive_table;
struct trip_table;
class dive_site_table;
struct device_table;
struct filter_preset_table;
#include <stdbool.h>
struct divelog {
struct dive_table *dives;
struct trip_table *trips;
dive_site_table *sites;
struct device_table *devices;
struct filter_preset_table *filter_presets;
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::unique_ptr<filter_preset_table> filter_presets;
bool autogroup;
divelog();
~divelog();
divelog(divelog &&log); // move constructor (argument is consumed).
divelog &operator=(divelog &&log); // move assignment (argument is consumed).
divelog(divelog &&); // move constructor (argument is consumed).
divelog &operator=(divelog &&); // move assignment (argument is consumed).
void delete_single_dive(int idx);
void clear();
};
extern struct divelog divelog;
#endif

View file

@ -445,7 +445,7 @@ int try_to_open_csv(std::string &mem, enum csv_format type, struct divelog *log)
break;
p = end + 1;
}
record_dive_to_table(dive, log->dives);
record_dive_to_table(dive, log->dives.get());
return 1;
}
@ -750,7 +750,7 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
if (!lineptr || !*lineptr)
break;
}
record_dive_to_table(dive, log->dives);
record_dive_to_table(dive, log->dives.get());
return 1;
} else {
return 0;

View file

@ -885,7 +885,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
dive->dc.sample[1].temperature.mkelvin > dive->dc.sample[0].temperature.mkelvin)
dive->dc.sample[0].temperature.mkelvin = dive->dc.sample[1].temperature.mkelvin;
record_dive_to_table(dive, devdata->log->dives);
record_dive_to_table(dive, devdata->log->dives.get());
return true;
error_exit:

View file

@ -450,7 +450,7 @@ int try_to_open_liquivision(const char *, std::string &mem, struct divelog *log)
}
ptr += 4;
parse_dives(log_version, buf + ptr, buf_size - ptr, log->dives, *log->sites);
parse_dives(log_version, buf + ptr, buf_size - ptr, log->dives.get(), *log->sites);
return 1;
}

View file

@ -991,7 +991,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, id.model.c_str(), id.serial.c_str(), id.nickname.c_str());
create_device_node(state->log->devices.get(), id.model.c_str(), id.serial.c_str(), id.nickname.c_str());
}
struct fingerprint_helper {
@ -1386,7 +1386,7 @@ static void finish_active_trip(struct git_parser_state *state)
if (trip) {
state->active_trip = NULL;
insert_trip(trip, state->log->trips);
insert_trip(trip, state->log->trips.get());
}
}
@ -1396,7 +1396,7 @@ static void finish_active_dive(struct git_parser_state *state)
if (dive) {
state->active_dive = NULL;
record_dive_to_table(dive, state->log->dives);
record_dive_to_table(dive, state->log->dives.get());
}
}
@ -1787,7 +1787,7 @@ static int parse_filter_preset(struct git_parser_state *state, const git_tree_en
git_blob_free(blob);
add_filter_preset_to_table(state->active_filter.get(), state->log->filter_presets);
add_filter_preset_to_table(state->active_filter.get(), state->log->filter_presets.get());
state->active_filter.reset();
return 0;

View file

@ -176,6 +176,6 @@ void ostctools_import(const char *file, struct divelog *log)
} else {
add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial);
}
record_dive_to_table(ostcdive.release(), log->dives);
sort_dive_table(log->dives);
record_dive_to_table(ostcdive.release(), log->dives.get());
sort_dive_table(log->dives.get());
}

View file

@ -178,7 +178,7 @@ void dc_settings_start(struct parser_state *state)
void dc_settings_end(struct parser_state *state)
{
create_device_node(state->log->devices,
create_device_node(state->log->devices.get(),
state->cur_settings.dc.model.c_str(),
state->cur_settings.dc.serial_nr.c_str(),
state->cur_settings.dc.nickname.c_str());
@ -217,7 +217,7 @@ void filter_preset_start(struct parser_state *state)
void filter_preset_end(struct parser_state *state)
{
add_filter_preset_to_table(state->cur_filter.get(), state->log->filter_presets);
add_filter_preset_to_table(state->cur_filter.get(), state->log->filter_presets.get());
state->cur_filter.reset();
}
@ -277,7 +277,7 @@ void dive_end(struct parser_state *state)
if (!is_dive(state)) {
free_dive(state->cur_dive);
} else {
record_dive_to_table(state->cur_dive, state->log->dives);
record_dive_to_table(state->cur_dive, state->log->dives.get());
if (state->cur_trip)
add_dive_to_trip(state->cur_dive, state->cur_trip);
}
@ -300,7 +300,7 @@ void trip_end(struct parser_state *state)
{
if (!state->cur_trip)
return;
insert_trip(state->cur_trip, state->log->trips);
insert_trip(state->cur_trip, state->log->trips.get());
state->cur_trip = NULL;
}

View file

@ -1000,14 +1000,14 @@ static QString get_dive_only_date_string(timestamp_t when)
QString get_first_dive_date_string()
{
const dive_table *dives = divelog.dives;
return dives->nr > 0 ? get_dive_only_date_string(dives->dives[0]->when) : gettextFromC::tr("no dives");
const dive_table &dives = *divelog.dives;
return dives.nr > 0 ? get_dive_only_date_string(dives.dives[0]->when) : gettextFromC::tr("no dives");
}
QString get_last_dive_date_string()
{
const dive_table *dives = divelog.dives;
return dives->nr > 0 ? get_dive_only_date_string(dives->dives[dives->nr - 1]->when) : gettextFromC::tr("no dives");
const dive_table &dives = *divelog.dives;
return dives.nr > 0 ? get_dive_only_date_string(dives.dives[dives.nr - 1]->when) : gettextFromC::tr("no dives");
}
std::string get_current_date()

View file

@ -893,8 +893,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); i++)
save_one_device(&b, get_device(divelog.devices, i));
for (int i = 0; i < nr_devices(divelog.devices.get()); i++)
save_one_device(&b, get_device(divelog.devices.get(), i));
/* save the fingerprint data */
for (int i = 0; i < nr_fingerprints(&fingerprint_table); i++)
save_one_fingerprint(&b, i);

View file

@ -686,8 +686,8 @@ 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); i++) {
const struct device *d = get_device(divelog.devices, i);
for (int i = 0; i < nr_devices(divelog.devices.get()); i++) {
const struct device *d = get_device(divelog.devices.get(), i);
if (!select_only || device_used_by_selected_dive(d))
save_one_device(b, d);
}

View file

@ -936,14 +936,14 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
bp = bp.substr(1);
if (bp[0] != '{' && bp.find("{{") != std::string::npos) {
done = false;
record_dive_to_table(dive, devdata->log->dives);
record_dive_to_table(dive, devdata->log->dives.get());
dive = uemis_start_dive(deviceid);
}
}
}
if (is_log) {
if (dive->dc.diveid) {
record_dive_to_table(dive, devdata->log->dives);
record_dive_to_table(dive, devdata->log->dives.get());
} else { /* partial dive */
free_dive(dive);
return false;
@ -970,7 +970,7 @@ static std::pair<uint32_t, uint32_t> uemis_get_divenr(uint32_t deviceid, struct
* Otherwise, use the global dive table.
*/
if (!force && !table->nr)
table = divelog.dives;
table = divelog.dives.get();
for (i = 0; i < table->nr; i++) {
struct dive *d = table->dives[i];
@ -1150,7 +1150,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
#if UEMIS_DEBUG & 16
do_dump_buffer_to_file(mbuf, "Dive");
#endif
mem_status = get_memory(data->log->dives, uemis_checkpoint::single_dive);
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::single_dive);
if (mem_status == uemis_mem_status::ok) {
/* if the memory isn's completely full we can try to read more dive log vs. dive details
* and the dive spots should fit into the UEMIS memory
@ -1214,7 +1214,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
} else {
/* At this point the memory of the UEMIS is full, let's cleanup all dive log files were
* we could not match the details to. */
do_delete_dives(data->log->dives, idx);
do_delete_dives(data->log->dives.get(), idx);
return false;
}
}
@ -1273,7 +1273,7 @@ std::string do_uemis_import(device_data_t *data)
param_buff[1] = "notempty";
{
auto [mindiveid, maxdiveid] = uemis_get_divenr(deviceidnr, data->log->dives, force_download);
auto [mindiveid, maxdiveid] = uemis_get_divenr(deviceidnr, data->log->dives.get(), force_download);
newmax = maxdiveid;
if (verbose)
report_info("Uemis downloader: start looking at dive nr %d", newmax);
@ -1297,7 +1297,7 @@ std::string do_uemis_import(device_data_t *data)
param_buff[2] = newmax_str.c_str();
param_buff[3].clear();
std::string mbuf = uemis_get_answer(mountpath, "getDivelogs", 3, 0, result);
mem_status = get_memory(data->log->dives, uemis_checkpoint::details);
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::details);
/* first, remove any leading garbage... this needs to start with a '{' */
std::string_view realmbuf = mbuf;
size_t pos = realmbuf.find('{');
@ -1350,7 +1350,7 @@ std::string do_uemis_import(device_data_t *data)
start = end;
/* Do some memory checking here */
mem_status = get_memory(data->log->dives, uemis_checkpoint::log);
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::log);
if (mem_status != uemis_mem_status::ok) {
#if UEMIS_DEBUG & 4
report_info("d_u_i out of memory, bailing\n");
@ -1364,7 +1364,7 @@ std::string do_uemis_import(device_data_t *data)
// Resetting to original state
filenr = 0;
max_mem_used = -1;
mem_status = get_memory(data->log->dives, uemis_checkpoint::details);
mem_status = get_memory(data->log->dives.get(), uemis_checkpoint::details);
if (uemis_get_answer(mountpath, "getDeviceId", 0, 1, result).empty())
goto bail;
if (deviceid != param_buff[0]) {
@ -1407,7 +1407,7 @@ std::string do_uemis_import(device_data_t *data)
* be deleted from the download_table.
*/
if (mem_status == uemis_mem_status::full)
do_delete_dives(data->log->dives, match_dive_and_log);
do_delete_dives(data->log->dives.get(), match_dive_and_log);
#if UEMIS_DEBUG & 4
report_info("d_u_i out of memory, bailing instead of processing\n");
#endif

View file

@ -52,7 +52,7 @@ QVariant DiveImportedModel::data(const QModelIndex &index, int role) const
if (index.row() >= log.dives->nr)
return QVariant();
struct dive *d = get_dive_from_table(index.row(), log.dives);
struct dive *d = get_dive_from_table(index.row(), log.dives.get());
if (!d)
return QVariant();
@ -124,8 +124,10 @@ void DiveImportedModel::downloadThreadFinished()
{
beginResetModel();
// Move the table data from thread to model
log = std::move(thread.log);
// Move the table data from thread to model. Replace the downloads thread's log
// with an empty log, because it may reuse it.
log.clear();
std::swap(log, thread.log);
checkStates.resize(log.dives->nr);
std::fill(checkStates.begin(), checkStates.end(), true);
@ -150,8 +152,9 @@ struct divelog DiveImportedModel::consumeTables()
{
beginResetModel();
// Move tables to result
struct divelog res(std::move(log));
// Move tables to result and reset local tables (oldschool pre-C++11 flair).
struct divelog res;
std::swap(res, log);
// Reset indices
checkStates.clear();
@ -176,7 +179,7 @@ void DiveImportedModel::deleteDeselected()
j++;
} else {
beginRemoveRows(QModelIndex(), j, j);
delete_dive_from_table(log.dives, j);
delete_dive_from_table(log.dives.get(), j);
endRemoveRows();
}
}

View file

@ -1041,11 +1041,11 @@ void smartrak_import(const char *file, struct divelog *log)
smtk_parse_bookmarks(mdb_clon, smtkdive, (char *)col[0]->bind_ptr);
concat(&smtkdive->notes, "\n", std::string((char *)col[coln(REMARKS)]->bind_ptr));
record_dive_to_table(smtkdive, log->dives);
record_dive_to_table(smtkdive, log->dives.get());
}
mdb_free_catalog(mdb_clon);
mdb->catalog = NULL;
mdb_close(mdb_clon);
mdb_close(mdb);
sort_dive_table(log->dives);
sort_dive_table(log->dives.get());
}