diff --git a/commands/command_device.cpp b/commands/command_device.cpp index 540e80adf..cef91c5d2 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, 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); diff --git a/commands/command_divelist.cpp b/commands/command_divelist.cpp index 67b2a7366..dac5663b1 100644 --- a/commands/command_divelist.cpp +++ b/commands/command_divelist.cpp @@ -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 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); diff --git a/commands/command_edit.cpp b/commands/command_edit.cpp index 6232890e4..48d34fdee 100644 --- a/commands/command_edit.cpp +++ b/commands/command_edit.cpp @@ -1486,8 +1486,8 @@ void EditDive::exchangeDives() QVector 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) diff --git a/core/cochran.cpp b/core/cochran.cpp index ed65950ab..4d8243e93 100644 --- a/core/cochran.cpp +++ b/core/cochran.cpp @@ -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 diff --git a/core/datatrak.cpp b/core/datatrak.cpp index 6cf029e97..8485d6acf 100644 --- a/core/datatrak.cpp +++ b/core/datatrak.cpp @@ -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; diff --git a/core/device.cpp b/core/device.cpp index 9a64cf83d..4eb3a2acc 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -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(); diff --git a/core/divelist.cpp b/core/divelist.cpp index 7c775de0a..badae34f1 100644 --- a/core/divelist.cpp +++ b/core/divelist.cpp @@ -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); } diff --git a/core/divelist.h b/core/divelist.h index 3f8ceac07..2f696291b 100644 --- a/core/divelist.h +++ b/core/divelist.h @@ -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); diff --git a/core/divelog.cpp b/core/divelog.cpp index 2cc2a06f1..c32ba7108 100644 --- a/core/divelog.cpp +++ b/core/divelog.cpp @@ -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()), + trips(std::make_unique()), + sites(std::make_unique()), + devices(std::make_unique()), + filter_presets(std::make_unique()), 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(); } diff --git a/core/divelog.h b/core/divelog.h index 04f292f74..7f245aa69 100644 --- a/core/divelog.h +++ b/core/divelog.h @@ -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 + struct dive_table; struct trip_table; class dive_site_table; struct device_table; struct filter_preset_table; -#include - 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 dives; + std::unique_ptr trips; + std::unique_ptr sites; + std::unique_ptr devices; + std::unique_ptr 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 diff --git a/core/import-csv.cpp b/core/import-csv.cpp index ed677c0ad..940d8428a 100644 --- a/core/import-csv.cpp +++ b/core/import-csv.cpp @@ -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; diff --git a/core/libdivecomputer.cpp b/core/libdivecomputer.cpp index 35dd4beea..5faf00a72 100644 --- a/core/libdivecomputer.cpp +++ b/core/libdivecomputer.cpp @@ -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: diff --git a/core/liquivision.cpp b/core/liquivision.cpp index 04bcc42a7..30a05f27f 100644 --- a/core/liquivision.cpp +++ b/core/liquivision.cpp @@ -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; } diff --git a/core/load-git.cpp b/core/load-git.cpp index b3a2c0d63..20100ff25 100644 --- a/core/load-git.cpp +++ b/core/load-git.cpp @@ -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; diff --git a/core/ostctools.cpp b/core/ostctools.cpp index b13adea83..b3f1e4b68 100644 --- a/core/ostctools.cpp +++ b/core/ostctools.cpp @@ -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()); } diff --git a/core/parse.cpp b/core/parse.cpp index be797a288..6e98db153 100644 --- a/core/parse.cpp +++ b/core/parse.cpp @@ -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; } diff --git a/core/qthelper.cpp b/core/qthelper.cpp index c0f9a5052..87563bc0f 100644 --- a/core/qthelper.cpp +++ b/core/qthelper.cpp @@ -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() diff --git a/core/save-git.cpp b/core/save-git.cpp index 12b73829f..64a033631 100644 --- a/core/save-git.cpp +++ b/core/save-git.cpp @@ -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); diff --git a/core/save-xml.cpp b/core/save-xml.cpp index 5669f272d..8d7b0596f 100644 --- a/core/save-xml.cpp +++ b/core/save-xml.cpp @@ -686,8 +686,8 @@ 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); 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); } diff --git a/core/uemis-downloader.cpp b/core/uemis-downloader.cpp index 86936c8ec..cb6d86940 100644 --- a/core/uemis-downloader.cpp +++ b/core/uemis-downloader.cpp @@ -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 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 diff --git a/qt-models/diveimportedmodel.cpp b/qt-models/diveimportedmodel.cpp index 27c2335dc..840c3a030 100644 --- a/qt-models/diveimportedmodel.cpp +++ b/qt-models/diveimportedmodel.cpp @@ -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(); } } diff --git a/smtk-import/smartrak.cpp b/smtk-import/smartrak.cpp index e0618d860..40b891c65 100644 --- a/smtk-import/smartrak.cpp +++ b/smtk-import/smartrak.cpp @@ -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()); }