core: add constructor/destructor pairs to dive and divecomputer

This allows us to use non-C member variables. Convert a number
of pointers to unique_ptr<>s.

Code in uemis-downloader.cpp had to be refactored, because
it mixed owning and non-owning pointers. Mad.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-16 20:11:21 +02:00 committed by bstoeger
parent bfb54aa581
commit cc39f709ce
35 changed files with 289 additions and 308 deletions

View file

@ -411,7 +411,7 @@ AddDive::AddDive(dive *d, bool autogroup, bool newNumber)
currentDive = nullptr;
// Get an owning pointer to a moved dive.
OwningDivePtr divePtr(move_dive(d));
std::unique_ptr<dive> divePtr = move_dive(d);
divePtr->selected = false; // If we clone a planned dive, it might have been selected.
// We have to clear the flag, as selections will be managed
// on dive-addition.
@ -494,7 +494,7 @@ ImportDives::ImportDives(struct divelog *log, int flags, const QString &source)
// Add dives to the divesToAdd.dives structure
divesToAdd.dives.reserve(dives_to_add.nr);
for (int i = 0; i < dives_to_add.nr; ++i) {
OwningDivePtr divePtr(dives_to_add.dives[i]);
std::unique_ptr<dive> divePtr(dives_to_add.dives[i]);
divePtr->selected = false; // See above in AddDive::AddDive()
dive_trip *trip = divePtr->divetrip;
divePtr->divetrip = nullptr; // See above in AddDive::AddDive()
@ -971,7 +971,7 @@ MergeDives::MergeDives(const QVector <dive *> &dives)
dive_trip *preferred_trip;
dive_site *preferred_site;
OwningDivePtr d(merge_dives(dives[0], dives[1], dives[1]->when - dives[0]->when, false, &preferred_trip, &preferred_site));
std::unique_ptr<dive> d(merge_dives(dives[0], dives[1], dives[1]->when - dives[0]->when, false, &preferred_trip, &preferred_site));
// Currently, the core code selects the dive -> this is not what we want, as
// we manually manage the selection post-command.

View file

@ -15,9 +15,9 @@ namespace Command {
// This helper structure describes a dive that we want to add.
struct DiveToAdd {
OwningDivePtr dive; // Dive to add
dive_trip *trip; // Trip the dive belongs to, may be null
dive_site *site; // Site the dive is associated with, may be null
std::unique_ptr<struct dive> dive; // Dive to add
dive_trip *trip; // Trip the dive belongs to, may be null
dive_site *site; // Site the dive is associated with, may be null
};
// Multiple trips, dives and dive sites that have to be added for a command

View file

@ -797,7 +797,6 @@ ReplanDive::ReplanDive(dive *source) : d(current_dive),
when(0),
maxdepth({0}),
meandepth({0}),
dc({ 0 }),
notes(nullptr),
surface_pressure({0}),
duration({0}),
@ -885,8 +884,7 @@ EditProfile::EditProfile(const dive *source, int dcNr, EditProfileType type, int
maxdepth({0}),
meandepth({0}),
dcmaxdepth({0}),
duration({0}),
dc({ 0 })
duration({0})
{
const struct divecomputer *sdc = get_dive_dc_const(source, dcNr);
if (!sdc)

View file

@ -465,7 +465,7 @@ public:
EditDive(dive *oldDive, dive *newDive, dive_site *createDs, dive_site *editDs, location_t dsLocation); // Takes ownership of newDive
private:
dive *oldDive; // Dive that is going to be overwritten
OwningDivePtr newDive; // New data
std::unique_ptr<dive> newDive; // New data
dive_site *newDiveSite;
int changedFields;

View file

@ -606,7 +606,6 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
struct dive_table *table)
{
unsigned char *buf = (unsigned char *)malloc(size);
struct dive *dive;
struct divecomputer *dc;
struct tm tm = {0};
@ -666,7 +665,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
puts("\nSample Data\n");
#endif
dive = alloc_dive();
auto dive = std::make_unique<struct dive>();
dc = &dive->dc;
unsigned char *log = (buf + 0x4914);
@ -678,7 +677,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
cylinder_t cyl;
dc->model = "Gemini";
dc->deviceid = buf[0x18c] * 256 + buf[0x18d]; // serial no
fill_default_cylinder(dive, &cyl);
fill_default_cylinder(dive.get(), &cyl);
cyl.gasmix.o2.permille = (log[CMD_O2_PERCENT] / 256
+ log[CMD_O2_PERCENT + 1]) * 10;
cyl.gasmix.he.permille = 0;
@ -688,7 +687,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
dc->deviceid = array_uint32_le(buf + 0x31e); // serial no
for (g = 0; g < 2; g++) {
cylinder_t cyl;
fill_default_cylinder(dive, &cyl);
fill_default_cylinder(dive.get(), &cyl);
cyl.gasmix.o2.permille = (log[CMD_O2_PERCENT + g * 2] / 256
+ log[CMD_O2_PERCENT + g * 2 + 1]) * 10;
cyl.gasmix.he.permille = 0;
@ -731,7 +730,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
dc->deviceid = array_uint32_le(buf + 0x31e); // serial no
for (g = 0; g < 4; g++) {
cylinder_t cyl;
fill_default_cylinder(dive, &cyl);
fill_default_cylinder(dive.get(), &cyl);
cyl.gasmix.o2.permille =
(log[EMC_O2_PERCENT + g * 2] / 256
+ log[EMC_O2_PERCENT + g * 2 + 1]) * 10;
@ -778,7 +777,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
if (sample_pre_offset < sample_end_offset && sample_end_offset != 0xffffffff)
sample_size = sample_end_offset - sample_pre_offset;
cochran_parse_samples(dive, buf + 0x4914, buf + 0x4914
cochran_parse_samples(dive.get(), buf + 0x4914, buf + 0x4914
+ config.logbook_size, sample_size,
&duration, &max_depth, &avg_depth, &min_temp);
@ -790,7 +789,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
dc->duration.seconds = duration;
}
record_dive_to_table(dive, table);
record_dive_to_table(dive.release(), table);
free(buf);
}

View file

@ -702,18 +702,17 @@ int datatrak_import(std::string &mem, std::string &wl_mem, struct divelog *log)
// Sequential parsing. Abort if received NULL from dt_dive_parser.
while ((i < numdives) && (runner < maxbuf)) {
struct dive *ptdive = alloc_dive();
auto ptdive = std::make_unique<dive>();
runner = dt_dive_parser((unsigned char *)runner, ptdive, log, maxbuf);
runner = dt_dive_parser((unsigned char *)runner, ptdive.get(), log, maxbuf);
if (!wl_mem.empty())
wlog_compl_parser(wl_mem, ptdive, i);
wlog_compl_parser(wl_mem, ptdive.get(), i);
if (runner == NULL) {
report_error("%s", translate("gettextFromC", "Error: no dive"));
free(ptdive);
rc = 1;
goto out;
} else {
record_dive_to_table(ptdive, log->dives.get());
record_dive_to_table(ptdive.release(), log->dives.get());
}
i++;
}

View file

@ -40,6 +40,17 @@ const char *divemode_text[] = {"OC", "CCR", "PSCR", "Freedive"};
static double calculate_depth_to_mbarf(int depth, pressure_t surface_pressure, int salinity);
dive::dive()
{
id = dive_getUniqID();
}
static void free_dive_structures(struct dive *d);
dive::~dive()
{
free_dive_structures(this);
}
/*
* The legacy format for sample pressures has a single pressure
* for each sample that can have any sensor, plus a possible
@ -163,18 +174,6 @@ int dive_getUniqID()
return maxId;
}
struct dive *alloc_dive()
{
struct dive *dive;
dive = (struct dive *)malloc(sizeof(*dive));
if (!dive)
exit(1);
memset(dive, 0, sizeof(*dive));
dive->id = dive_getUniqID();
return dive;
}
/* copy an element in a list of dive computer extra data */
static void copy_extra_data(struct extra_data *sed, struct extra_data *ded)
{
@ -208,7 +207,7 @@ static void copy_dc_renumber(struct dive *d, const struct divecomputer *sdc, str
if (!sdc->next)
break;
sdc = sdc->next;
ddc->next = (divecomputer *)calloc(1, sizeof(struct divecomputer));
ddc->next = new divecomputer;
ddc = ddc->next;
}
ddc->next = NULL;
@ -235,12 +234,6 @@ static void free_dive_structures(struct dive *d)
free(d->pictures.pictures);
}
void free_dive(struct dive *d)
{
free_dive_structures(d);
free(d);
}
/* copy_dive makes duplicates of many components of a dive;
* in order not to leak memory, we need to free those .
* copy_dive doesn't play with the divetrip and forward/backward pointers
@ -250,7 +243,7 @@ void clear_dive(struct dive *d)
if (!d)
return;
free_dive_structures(d);
memset(d, 0, sizeof(struct dive));
*d = dive();
}
/* make a true copy that is independent of the source dive;
@ -297,12 +290,11 @@ static void copy_dive_onedc(const struct dive *s, const struct divecomputer *sdc
/* make a clone of the source dive and clean out the source dive;
* this allows us to create a dive on the stack and then
* add it to the divelist. */
struct dive *move_dive(struct dive *s)
struct std::unique_ptr<dive> move_dive(struct dive *s)
{
struct dive *dive = alloc_dive();
*dive = *s; // so all the pointers in dive point to the things s pointed to
memset(s, 0, sizeof(struct dive)); // and now the pointers in s are gone
return dive;
auto d = std::make_unique<dive>();
std::swap(*s, *d);
return d;
}
#define CONDITIONAL_COPY_STRING(_component) \
@ -1300,7 +1292,7 @@ struct dive *fixup_dive(struct dive *dive)
const weightsystem_t &ws = dive->weightsystems.weightsystems[i];
add_weightsystem_description(ws);
}
/* we should always have a uniq ID as that gets assigned during alloc_dive(),
/* we should always have a uniq ID as that gets assigned during dive creation,
* but we want to make sure... */
if (!dive->id)
dive->id = dive_getUniqID();
@ -2432,7 +2424,7 @@ static void remove_redundant_dc(struct divecomputer *dc, int prefer_downloaded)
if (same_dc(dc, check) || (prefer_downloaded && might_be_same_device(dc, check))) {
*p = check->next;
check->next = NULL;
free_dc(check);
delete check;
continue;
}
p = &check->next;
@ -2502,7 +2494,7 @@ static void interleave_dive_computers(struct dive *d, struct divecomputer *res,
a = a->next;
if (!a)
break;
res->next = (divecomputer *)calloc(1, sizeof(struct divecomputer));
res->next = new divecomputer;
res = res->next;
} while (res);
}
@ -2542,7 +2534,7 @@ static void join_dive_computers(struct dive *d, struct divecomputer *res,
while (tmp->next)
tmp = tmp->next;
tmp->next = (divecomputer *)calloc(1, sizeof(*tmp));
tmp->next = new divecomputer;
copy_dc_renumber(d, b, tmp->next, cylinders_map_b);
remove_redundant_dc(res, prefer_downloaded);
@ -2602,7 +2594,7 @@ bool is_logged(const struct dive *dive)
*/
struct dive *merge_dives(const struct dive *a, const struct dive *b, int offset, bool prefer_downloaded, struct dive_trip **trip, struct dive_site **site)
{
struct dive *res = alloc_dive();
struct dive *res = new dive;
if (offset) {
/*
@ -2670,12 +2662,11 @@ struct dive *merge_dives(const struct dive *a, const struct dive *b, int offset,
// copy_dive(), but retaining the new ID for the copied dive
static struct dive *create_new_copy(const struct dive *from)
{
struct dive *to = alloc_dive();
int id;
struct dive *to = new dive;
// alloc_dive() gave us a new ID, we just need to
// dive creation gave us a new ID, we just need to
// make sure it's not overwritten.
id = to->id;
int id = to->id;
copy_dive(from, to);
to->id = id;
return to;
@ -3049,11 +3040,10 @@ void set_git_prefs(const char *prefs)
/* clones a dive and moves given dive computer to front */
struct dive *make_first_dc(const struct dive *d, int dc_number)
{
struct dive *res;
struct divecomputer *dc, *newdc, *old_dc;
/* copy the dive */
res = alloc_dive();
dive *res = new dive;
copy_dive(d, res);
/* make a new unique id, since we still can't handle two equal ids */
@ -3092,12 +3082,12 @@ static void delete_divecomputer(struct dive *d, int num)
return;
if (num == 0) {
/* remove the first one, so copy the second one in place of the first and free the second one
* be careful about freeing the no longer needed structures - since we copy things around we can't use free_dc()*/
/* During our move to C++, copy the divecomputer instead of moving the internals.
* Yes, this is "inefficient", but I don't care. Will be removed anyways. */
struct divecomputer *fdc = d->dc.next;
free_dc_contents(&d->dc);
memcpy(&d->dc, fdc, sizeof(struct divecomputer));
free(fdc);
copy_dc(fdc, &d->dc);
delete fdc;
} else {
struct divecomputer *pdc = &d->dc;
for (i = 0; i < num - 1 && pdc; i++)
@ -3105,7 +3095,7 @@ static void delete_divecomputer(struct dive *d, int num)
if (pdc && pdc->next) {
struct divecomputer *dc = pdc->next;
pdc->next = dc->next;
free_dc(dc);
delete dc;
}
}
}
@ -3113,10 +3103,8 @@ static void delete_divecomputer(struct dive *d, int num)
/* Clone a dive and delete goven dive computer */
struct dive *clone_delete_divecomputer(const struct dive *d, int dc_number)
{
struct dive *res;
/* copy the dive */
res = alloc_dive();
dive *res = new dive;
copy_dive(d, res);
/* make a new unique id, since we still can't handle two equal ids */
@ -3140,7 +3128,7 @@ void split_divecomputer(const struct dive *src, int num, struct dive **out1, str
if (src && srcdc) {
// Copy the dive, but only using the selected dive computer
*out2 = alloc_dive();
*out2 = new dive;
copy_dive_onedc(src, srcdc, *out2);
// This will also make fixup_dive() to allocate a new dive id...

View file

@ -25,37 +25,40 @@ struct full_text_cache;
struct event;
struct trip_table;
struct dive {
struct dive_trip *divetrip;
timestamp_t when;
struct dive_site *dive_site;
char *notes;
char *diveguide, *buddy;
struct cylinder_table cylinders;
struct weightsystem_table weightsystems;
char *suit;
int number;
int rating;
int wavesize, current, visibility, surge, chill; /* 0 - 5 star ratings */
int sac, otu, cns, maxcns;
struct dive_trip *divetrip = nullptr;
timestamp_t when = 0;
struct dive_site *dive_site = nullptr;
char *notes = nullptr;
char *diveguide = nullptr, *buddy = nullptr;
struct cylinder_table cylinders = { };
struct weightsystem_table weightsystems = { };
char *suit = nullptr;
int number = 0;
int rating = 0;
int wavesize = 0, current = 0, visibility = 0, surge = 0, chill = 0; /* 0 - 5 star ratings */
int sac = 0, otu = 0, cns = 0, maxcns = 0;
/* Calculated based on dive computer data */
temperature_t mintemp, maxtemp, watertemp, airtemp;
depth_t maxdepth, meandepth;
pressure_t surface_pressure;
duration_t duration;
int salinity; // kg per 10000 l
int user_salinity; // water density reflecting a user-specified type
int salinity = 0; // kg per 10000 l
int user_salinity = 0; // water density reflecting a user-specified type
struct tag_entry *tag_list;
struct tag_entry *tag_list = nullptr;
struct divecomputer dc;
int id; // unique ID for this dive
struct picture_table pictures;
unsigned char git_id[20];
bool notrip; /* Don't autogroup this dive to a trip */
bool selected;
bool hidden_by_filter;
struct full_text_cache *full_text; /* word cache for full text search */
bool invalid;
int id = 0; // unique ID for this dive
struct picture_table pictures = { };
unsigned char git_id[20] = {};
bool notrip = false; /* Don't autogroup this dive to a trip */
bool selected = false;
bool hidden_by_filter = false;
struct full_text_cache *full_text = nullptr; /* word cache for full text search */
bool invalid = false;
dive();
~dive();
};
/* For the top-level list: an entry is either a dive or a trip */
@ -161,13 +164,11 @@ extern void subsurface_console_init();
extern void subsurface_console_exit();
extern bool subsurface_user_is_root();
extern struct dive *alloc_dive();
extern void free_dive(struct dive *);
extern void record_dive_to_table(struct dive *dive, struct dive_table *table);
extern void clear_dive(struct dive *dive);
extern void copy_dive(const struct dive *s, struct dive *d);
extern void selective_copy_dive(const struct dive *s, struct dive *d, struct dive_components what, bool clear);
extern struct dive *move_dive(struct dive *s);
extern struct std::unique_ptr<dive> move_dive(struct dive *s);
extern int legacy_format_o2pressures(const struct dive *dive, const struct divecomputer *dc);

View file

@ -11,6 +11,15 @@
#include <string.h>
#include <stdlib.h>
divecomputer::divecomputer()
{
}
divecomputer::~divecomputer()
{
free_dc_contents(this);
}
/*
* Good fake dive profiles are hard.
*
@ -234,11 +243,15 @@ int get_depth_at_time(const struct divecomputer *dc, unsigned int time)
}
/* The first divecomputer is embedded in the dive structure. Free its data but not
* the structure itself. For all remainding dcs in the list, free data *and* structures. */
static void free_dc(struct divecomputer *dc)
{
delete dc;
}
/* The first divecomputer is embedded in the dive structure. Ignore it.
* For all remainding dcs in the list, free data and structures. */
void free_dive_dcs(struct divecomputer *dc)
{
free_dc_contents(dc);
STRUCTURED_LIST_FREE(struct divecomputer, dc->next, free_dc);
}
@ -545,12 +558,6 @@ void free_dc_contents(struct divecomputer *dc)
STRUCTURED_LIST_FREE(struct extra_data, dc->extra_data, free_extra_data);
}
void free_dc(struct divecomputer *dc)
{
free_dc_contents(dc);
free(dc);
}
static const char *planner_dc_name = "planned dive";
bool is_dc_planner(const struct divecomputer *dc)

View file

@ -26,25 +26,27 @@ struct sample;
* A deviceid or diveid of zero is assumed to be "no ID".
*/
struct divecomputer {
timestamp_t when;
timestamp_t when = 0;
duration_t duration, surfacetime, last_manual_time;
depth_t maxdepth, meandepth;
temperature_t airtemp, watertemp;
pressure_t surface_pressure;
enum divemode_t divemode; // dive computer type: OC(default) or CCR
uint8_t no_o2sensors; // rebreathers: number of O2 sensors used
int salinity; // kg per 10000 l
const char *model, *serial, *fw_version;
uint32_t deviceid, diveid;
int samples, alloc_samples;
struct sample *sample;
struct event *events;
struct extra_data *extra_data;
struct divecomputer *next;
enum divemode_t divemode = OC; // dive computer type: OC(default) or CCR
uint8_t no_o2sensors = 0; // rebreathers: number of O2 sensors used
int salinity = 0; // kg per 10000 l
const char *model = nullptr, *serial = nullptr, *fw_version = nullptr;
uint32_t deviceid = 0, diveid = 0;
int samples = 0, alloc_samples = 0;
struct sample *sample = nullptr;
struct event *events = nullptr;
struct extra_data *extra_data = nullptr;
struct divecomputer *next = nullptr;
divecomputer();
~divecomputer();
};
extern void fake_dc(struct divecomputer *dc);
extern void free_dc(struct divecomputer *dc);
extern void free_dc_contents(struct divecomputer *dc);
extern enum divemode_t get_current_divemode(const struct divecomputer *dc, int time, const struct event **evp, enum divemode_t *divemode);
extern int get_depth_at_time(const struct divecomputer *dc, unsigned int time);

View file

@ -687,6 +687,10 @@ int comp_dives(const struct dive *a, const struct dive *b)
}
/* Dive table functions */
static void free_dive(dive *d)
{
delete d;
}
static MAKE_GROW_TABLE(dive_table, struct dive *, dives)
MAKE_GET_INSERTION_INDEX(dive_table, struct dive *, dives, dive_less_than)
MAKE_ADD_TO(dive_table, struct dive *, dives)
@ -735,7 +739,7 @@ static void autogroup_dives(struct dive_table *table, struct trip_table *trip_ta
* It simply shrinks the table and frees the trip */
void delete_dive_from_table(struct dive_table *table, int idx)
{
free_dive(table->dives[idx]);
delete table->dives[idx];
remove_from_dive_table(table, idx);
}
@ -818,7 +822,7 @@ static void merge_imported_dives(struct dive_table *table)
unregister_dive_from_trip(dive);
/* Overwrite the first of the two dives and remove the second */
free_dive(prev);
delete prev;
table->dives[i - 1] = merged;
delete_dive_from_table(table, i);
@ -909,7 +913,7 @@ static bool merge_dive_tables(struct dive_table *dives_from, struct dive_table *
dive_endtime(dives_to->dives[j - 1]) > dive_to_add->when) {
if (try_to_merge_into(dive_to_add, j - 1, dives_to, prefer_imported,
dives_to_add, dives_to_remove)) {
free_dive(dive_to_add);
delete dive_to_add;
last_merged_into = j - 1;
(*num_merged)++;
continue;
@ -922,7 +926,7 @@ static bool merge_dive_tables(struct dive_table *dives_from, struct dive_table *
dive_endtime(dive_to_add) > dives_to->dives[j]->when) {
if (try_to_merge_into(dive_to_add, j, dives_to, prefer_imported,
dives_to_add, dives_to_remove)) {
free_dive(dive_to_add);
delete dive_to_add;
last_merged_into = j;
(*num_merged)++;
continue;

View file

@ -181,7 +181,7 @@ static int cobalt_dive(void *param, int, char **data, char **)
if (location && location_site) {
std::string tmp = std::string(location) + " / " + location_site;
state->log->sites->find_or_create(tmp)->add_dive(state->cur_dive);
state->log->sites->find_or_create(tmp)->add_dive(state->cur_dive.get());
}
free(location);
free(location_site);

View file

@ -401,7 +401,6 @@ int try_to_open_csv(std::string &mem, enum csv_format type, struct divelog *log)
char *header[8];
int i, time;
timestamp_t date;
struct dive *dive;
struct divecomputer *dc;
for (i = 0; i < 8; i++) {
@ -416,7 +415,7 @@ int try_to_open_csv(std::string &mem, enum csv_format type, struct divelog *log)
if (!date)
return 0;
dive = alloc_dive();
auto dive = std::make_unique<struct dive>();
dive->when = date;
dive->number = atoi(header[1]);
dc = &dive->dc;
@ -445,7 +444,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.get());
record_dive_to_table(dive.release(), log->dives.get());
return 1;
}
@ -498,7 +497,6 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
int prev_time = 0;
cylinder_t cyl;
struct dive *dive;
struct divecomputer *dc;
struct tm cur_tm;
@ -512,7 +510,7 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
cur_tm.tm_min = mm;
cur_tm.tm_sec = ss;
dive = alloc_dive();
auto dive = std::make_unique<struct dive>();
dive->when = utc_mktime(&cur_tm);;
dive->dc.model = strdup("Poseidon MkVI Discovery");
value = parse_mkvi_value(memtxt.data(), "Rig Serial number");
@ -572,10 +570,8 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
*/
auto [memcsv, err] = readfile(csv);
if (err < 0) {
free_dive(dive);
if (err < 0)
return report_error(translate("gettextFromC", "Poseidon import failed: unable to read '%s'"), csv);
}
lineptr = memcsv.data();
for (;;) {
struct sample *sample;
@ -750,7 +746,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.get());
record_dive_to_table(dive.release(), log->dives.get());
return 1;
} else {
return 0;

View file

@ -131,7 +131,7 @@ static int divinglog_profile(void *param, int, char **data, char **)
state->cur_sample->pressure[0].mbar = pressure * 100;
state->cur_sample->rbt.seconds = rbt;
if (oldcyl != tank && tank >= 0 && tank < state->cur_dive->cylinders.nr) {
struct gasmix mix = get_cylinder(state->cur_dive, tank)->gasmix;
struct gasmix mix = get_cylinder(state->cur_dive.get(), tank)->gasmix;
int o2 = get_o2(mix);
int he = get_he(mix);
@ -276,7 +276,7 @@ static int divinglog_dive(void *param, int, char **data, char **)
state->cur_dive->when = (time_t)(atol(data[1]));
if (data[2])
state->log->sites->find_or_create(std::string(data[2]))->add_dive(state->cur_dive);
state->log->sites->find_or_create(std::string(data[2]))->add_dive(state->cur_dive.get());
if (data[3])
utf8_string(data[3], &state->cur_dive->buddy);

View file

@ -70,7 +70,7 @@ static int seac_dive(void *param, int, char **data, char **)
state->cur_dive->number = atoi(data[0]);
// Create first cylinder
cylinder_t *curcyl = get_or_create_cylinder(state->cur_dive, 0);
cylinder_t *curcyl = get_or_create_cylinder(state->cur_dive.get(), 0);
// Get time and date
sscanf(data[2], "%d/%d/%2d", &day, &month, &year);
@ -241,7 +241,7 @@ static int seac_dive(void *param, int, char **data, char **)
seac_gaschange(state, sqlstmt);
lastgas = curgas;
cylnum ^= 1; // Only need to toggle between two cylinders
curcyl = get_or_create_cylinder(state->cur_dive, cylnum);
curcyl = get_or_create_cylinder(state->cur_dive.get(), cylnum);
curcyl->gasmix.o2.permille = 10 * sqlite3_column_int(sqlstmt, 4);
}
state->cur_sample->stopdepth.mm = 10 * sqlite3_column_int(sqlstmt, 5);

View file

@ -61,7 +61,7 @@ static int shearwater_changes(void *param, int columns, char **data, char **)
int index;
bool found = false;
for (index = 0; index < state->cur_dive->cylinders.nr; ++index) {
const cylinder_t *cyl = get_cylinder(state->cur_dive, index);
const cylinder_t *cyl = get_cylinder(state->cur_dive.get(), index);
if (cyl->gasmix.o2.permille == o2 && cyl->gasmix.he.permille == he) {
found = true;
break;
@ -75,7 +75,7 @@ static int shearwater_changes(void *param, int columns, char **data, char **)
cylinder_end(state);
}
add_gas_switch_event(state->cur_dive, get_dc(state), state->sample_rate ? atoi(data[0]) / state->sample_rate * 10 : atoi(data[0]), index);
add_gas_switch_event(state->cur_dive.get(), get_dc(state), state->sample_rate ? atoi(data[0]) / state->sample_rate * 10 : atoi(data[0]), index);
return 0;
}
@ -239,7 +239,7 @@ static int shearwater_dive(void *param, int, char **data, char **)
long int dive_id = atol(data[11]);
if (data[2])
add_dive_site(data[2], state->cur_dive, state);
add_dive_site(data[2], state->cur_dive.get(), state);
if (data[3])
utf8_string(data[3], &state->cur_dive->buddy);
if (data[4])
@ -369,7 +369,7 @@ static int shearwater_cloud_dive(void *param, int, char **data, char **)
state->sample_rate = 0;
if (data[2])
add_dive_site(data[2], state->cur_dive, state);
add_dive_site(data[2], state->cur_dive.get(), state);
if (data[3])
utf8_string(data[3], &state->cur_dive->buddy);
if (data[4])

View file

@ -809,7 +809,6 @@ static int dive_cb(const unsigned char *data, unsigned int size,
dc_status_t rc;
dc_parser_t *parser = NULL;
device_data_t *devdata = (device_data_t *)userdata;
struct dive *dive = NULL;
/* reset static data, that is only valid per dive */
stoptime = stopdepth = po2 = cns = heartbeat = 0;
@ -825,14 +824,14 @@ static int dive_cb(const unsigned char *data, unsigned int size,
return true;
}
dive = alloc_dive();
auto dive = std::make_unique<struct dive>();
// Fill in basic fields
dive->dc.model = strdup(devdata->model.c_str());
dive->dc.diveid = calculate_diveid(fingerprint, fsize);
// Parse the dive's header data
rc = libdc_header_parser (parser, devdata, dive);
rc = libdc_header_parser (parser, devdata, dive.get());
if (rc != DC_STATUS_SUCCESS) {
download_error(translate("getextFromC", "Error parsing the header: %s"), errmsg(rc));
goto error_exit;
@ -867,7 +866,6 @@ static int dive_cb(const unsigned char *data, unsigned int size,
if (!devdata->force_download && find_dive(&dive->dc)) {
std::string date_string = get_dive_date_c_string(dive->when);
dev_info(devdata, translate("gettextFromC", "Already downloaded dive at %s"), date_string.c_str());
free_dive(dive);
return false;
}
@ -885,14 +883,12 @@ 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.get());
record_dive_to_table(dive.release(), devdata->log->dives.get());
return true;
error_exit:
dc_parser_destroy(parser);
free_dive(dive);
return true;
}
#ifndef O_BINARY

View file

@ -136,20 +136,19 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
unsigned int ptr = 0;
unsigned char model;
struct dive *dive;
struct divecomputer *dc;
struct sample *sample;
while (ptr < buf_size) {
int i;
dive = alloc_dive();
auto dive = std::make_unique<struct dive>();
memset(&sensor_ids, 0, sizeof(sensor_ids));
dc = &dive->dc;
/* Just the main cylinder until we can handle the buddy cylinder porperly */
for (i = 0; i < 1; i++) {
cylinder_t cyl;
fill_default_cylinder(dive, &cyl);
fill_default_cylinder(dive.get(), &cyl);
add_cylinder(&dive->cylinders, i, cyl);
}
@ -190,7 +189,7 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
/* Store the location only if we have one */
if (!location.empty())
sites.find_or_create(location)->add_dive(dive);
sites.find_or_create(location)->add_dive(dive.get());
ptr += len + 4 + place_len;
@ -414,17 +413,12 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
}
// End dive
record_dive_to_table(dive, table);
record_dive_to_table(dive.release(), table);
dive = NULL;
// Advance ptr for next dive
ptr += ps_ptr + 4;
} // while
//DEBUG save_dives("/tmp/test.xml");
// if we bailed out of the loop, the dive hasn't been recorded and dive hasn't been set to NULL
free_dive(dive);
}
int try_to_open_liquivision(const char *, std::string &mem, struct divelog *log)

View file

@ -37,7 +37,7 @@ std::string saved_git_id;
struct git_parser_state {
git_repository *repo = nullptr;
struct divecomputer *active_dc = nullptr;
struct dive *active_dive = nullptr;
std::unique_ptr<dive> active_dive;
dive_trip_t *active_trip = nullptr;
std::string fulltext_mode;
std::string fulltext_query;
@ -171,14 +171,14 @@ static int get_hex(const char *line)
static void parse_dive_gps(char *line, struct git_parser_state *state)
{
location_t location;
struct dive_site *ds = get_dive_site_for_dive(state->active_dive);
struct dive_site *ds = get_dive_site_for_dive(state->active_dive.get());
parse_location(line, &location);
if (!ds) {
ds = state->log->sites->get_by_gps(&location);
if (!ds)
ds = state->log->sites->create(std::string(), location);
ds->add_dive(state->active_dive);
ds->add_dive(state->active_dive.get());
} else {
if (dive_site_has_gps_location(ds) && ds->location != location) {
std::string coords = printGPSCoordsC(&location);
@ -219,12 +219,12 @@ static char *get_first_converted_string_c(struct git_parser_state *state)
static void parse_dive_location(char *, struct git_parser_state *state)
{
std::string name = get_first_converted_string(state);
struct dive_site *ds = get_dive_site_for_dive(state->active_dive);
struct dive_site *ds = get_dive_site_for_dive(state->active_dive.get());
if (!ds) {
ds = state->log->sites->get_by_name(name);
if (!ds)
ds = state->log->sites->create(name);
ds->add_dive(state->active_dive);
ds->add_dive(state->active_dive.get());
} else {
// we already had a dive site linked to the dive
if (ds->name.empty()) {
@ -252,7 +252,7 @@ static void parse_dive_notes(char *, struct git_parser_state *state)
{ state->active_dive->notes = get_first_converted_string_c(state); }
static void parse_dive_divesiteid(char *line, struct git_parser_state *state)
{ state->log->sites->get_by_uuid(get_hex(line))->add_dive(state->active_dive); }
{ state->log->sites->get_by_uuid(get_hex(line))->add_dive(state->active_dive.get()); }
/*
* We can have multiple tags.
@ -684,8 +684,8 @@ static struct sample *new_sample(struct git_parser_state *state)
sample->pressure[0].mbar = 0;
sample->pressure[1].mbar = 0;
} else {
sample->sensor[0] = sanitize_sensor_id(state->active_dive, !state->o2pressure_sensor);
sample->sensor[1] = sanitize_sensor_id(state->active_dive, state->o2pressure_sensor);
sample->sensor[0] = sanitize_sensor_id(state->active_dive.get(), !state->o2pressure_sensor);
sample->sensor[1] = sanitize_sensor_id(state->active_dive.get(), state->o2pressure_sensor);
}
return sample;
}
@ -1392,23 +1392,19 @@ static void finish_active_trip(struct git_parser_state *state)
static void finish_active_dive(struct git_parser_state *state)
{
struct dive *dive = state->active_dive;
if (dive) {
state->active_dive = NULL;
record_dive_to_table(dive, state->log->dives.get());
}
if (state->active_dive)
record_dive_to_table(state->active_dive.release(), state->log->dives.get());
}
static void create_new_dive(timestamp_t when, struct git_parser_state *state)
{
state->active_dive = alloc_dive();
state->active_dive = std::make_unique<dive>();
/* We'll fill in more data from the dive file */
state->active_dive->when = when;
if (state->active_trip)
add_dive_to_trip(state->active_dive, state->active_trip);
add_dive_to_trip(state->active_dive.get(), state->active_trip);
}
static bool validate_date(int yyyy, int mm, int dd)
@ -1654,9 +1650,7 @@ static struct divecomputer *create_new_dc(struct dive *dive)
dc = dc->next;
/* Did we already fill that in? */
if (dc->samples || dc->model || dc->when) {
struct divecomputer *newdc = (divecomputer *)calloc(1, sizeof(*newdc));
if (!newdc)
return NULL;
struct divecomputer *newdc = new divecomputer;
dc->next = newdc;
dc = newdc;
}
@ -1678,7 +1672,7 @@ static int parse_divecomputer_entry(struct git_parser_state *state, const git_tr
if (!blob)
return report_error("Unable to read divecomputer file");
state->active_dc = create_new_dc(state->active_dive);
state->active_dc = create_new_dc(state->active_dive.get());
for_each_line(blob, divecomputer_parser, state);
git_blob_free(blob);
state->active_dc = NULL;
@ -1693,12 +1687,11 @@ static int parse_divecomputer_entry(struct git_parser_state *state, const git_tr
*/
static int parse_dive_entry(struct git_parser_state *state, const git_tree_entry *entry, const char *suffix)
{
struct dive *dive = state->active_dive;
git_blob *blob = git_tree_entry_blob(state->repo, entry);
if (!blob)
return report_error("Unable to read dive file");
if (*suffix)
dive->number = atoi(suffix + 1);
state->active_dive->number = atoi(suffix + 1);
clear_weightsystem_table(&state->active_dive->weightsystems);
state->o2pressure_sensor = 1;
for_each_line(blob, dive_parser, state);
@ -1795,7 +1788,7 @@ static int parse_filter_preset(struct git_parser_state *state, const git_tree_en
static int walk_tree_file(const char *root, const git_tree_entry *entry, struct git_parser_state *state)
{
struct dive *dive = state->active_dive;
auto &dive = state->active_dive;
dive_trip_t *trip = state->active_trip;
const char *name = git_tree_entry_name(entry);
if (verbose > 1)
@ -1826,7 +1819,7 @@ static int walk_tree_file(const char *root, const git_tree_entry *entry, struct
return parse_settings_entry(state, entry);
break;
}
report_error("Unknown file %s%s (%p %p)", root, name, dive, trip);
report_error("Unknown file %s%s (%p %p)", root, name, dive.get(), trip);
return GIT_WALK_SKIP;
}

View file

@ -48,7 +48,7 @@ void ostctools_import(const char *file, struct divelog *log)
dc_family_t dc_fam;
std::vector<unsigned char> buffer(65536, 0);
unsigned char uc_tmp[2];
OwningDivePtr ostcdive(alloc_dive());
auto ostcdive = std::make_unique<dive>();
dc_status_t rc = DC_STATUS_SUCCESS;
int model, ret, i = 0, c;
unsigned int serial;

View file

@ -9,24 +9,16 @@
#include <memory>
#include <cstdlib>
struct dive;
struct dive_trip;
struct dive_site;
struct event;
void free_dive(struct dive *);
void free_trip(struct dive_trip *);
// Classes used to automatically call the appropriate free_*() function for owning pointers that go out of scope.
struct DiveDeleter {
void operator()(dive *d) { free_dive(d); }
};
struct TripDeleter {
void operator()(dive_trip *t) { free_trip(t); }
};
// Owning pointers to dive, dive_trip, dive_site and event objects.
using OwningDivePtr = std::unique_ptr<dive, DiveDeleter>;
using OwningTripPtr = std::unique_ptr<dive_trip, TripDeleter>;
#endif

View file

@ -657,10 +657,9 @@ static void uddf_gasswitch(const char *buffer, struct sample *sample, struct par
{
int idx = atoi(buffer);
int seconds = sample->time.seconds;
struct dive *dive = state->cur_dive;
struct divecomputer *dc = get_dc(state);
add_gas_switch_event(dive, dc, seconds, idx);
add_gas_switch_event(state->cur_dive.get(), dc, seconds, idx);
}
static int uddf_fill_sample(struct sample *sample, const char *name, char *buf, struct parser_state *state)
@ -696,7 +695,7 @@ static void get_cylinderindex(const char *buffer, int16_t *i, struct parser_stat
{
*i = atoi(buffer);
if (state->lastcylinderindex != *i) {
add_gas_switch_event(state->cur_dive, get_dc(state), state->cur_sample->time.seconds, *i);
add_gas_switch_event(state->cur_dive.get(), get_dc(state), state->cur_sample->time.seconds, *i);
state->lastcylinderindex = *i;
}
}
@ -1526,7 +1525,7 @@ static bool entry(const char *name, char *buf, struct parser_state *state)
return true;
}
if (state->cur_dive) {
try_to_fill_dive(state->cur_dive, name, buf, state);
try_to_fill_dive(state->cur_dive.get(), name, buf, state);
return true;
}
if (state->cur_trip) {
@ -1863,7 +1862,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log)
state.cur_dc->surface_pressure.mbar = ((ptr[25] << 8) + ptr[24]) / 10;
// Declare initial mix as first cylinder
cyl = get_or_create_cylinder(state.cur_dive, 0);
cyl = get_or_create_cylinder(state.cur_dive.get(), 0);
cyl->gasmix.o2.permille = ptr[26] * 10;
cyl->gasmix.he.permille = ptr[27] * 10;
@ -1974,7 +1973,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log)
found = false;
for (i = 0; i < state.cur_dive->cylinders.nr; ++i) {
const cylinder_t *cyl = get_cylinder(state.cur_dive, i);
const cylinder_t *cyl = get_cylinder(state.cur_dive.get(), i);
if (cyl->gasmix.o2.permille == ptr[6] * 10 && cyl->gasmix.he.permille == ptr[7] * 10) {
found = true;
break;
@ -2225,7 +2224,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log)
/* Measure GPS */
state.cur_location.lat.udeg = (int)((ptr[7] << 24) + (ptr[6] << 16) + (ptr[5] << 8) + (ptr[4] << 0));
state.cur_location.lon.udeg = (int)((ptr[11] << 24) + (ptr[10] << 16) + (ptr[9] << 8) + (ptr[8] << 0));
state.log->sites->create("DLF imported"s, state.cur_location)->add_dive(state.cur_dive);
state.log->sites->create("DLF imported"s, state.cur_location)->add_dive(state.cur_dive.get());
break;
default:
break;

View file

@ -25,7 +25,6 @@ parser_state::parser_state()
parser_state::~parser_state()
{
free_dive(cur_dive);
free_trip(cur_trip);
}
@ -264,7 +263,7 @@ void dive_start(struct parser_state *state)
{
if (state->cur_dive)
return;
state->cur_dive = alloc_dive();
state->cur_dive = std::make_unique<dive>();
reset_dc_info(&state->cur_dive->dc, state);
memset(&state->cur_tm, 0, sizeof(state->cur_tm));
state->o2pressure_sensor = 1;
@ -274,14 +273,12 @@ void dive_end(struct parser_state *state)
{
if (!state->cur_dive)
return;
if (!is_dive(state)) {
free_dive(state->cur_dive);
} else {
record_dive_to_table(state->cur_dive, state->log->dives.get());
if (is_dive(state)) {
if (state->cur_trip)
add_dive_to_trip(state->cur_dive, state->cur_trip);
add_dive_to_trip(state->cur_dive.get(), state->cur_trip);
record_dive_to_table(state->cur_dive.release(), state->log->dives.get());
}
state->cur_dive = NULL;
state->cur_dive.reset();
state->cur_dc = NULL;
state->cur_location.lat.udeg = 0;
state->cur_location.lon.udeg = 0;
@ -369,8 +366,8 @@ void sample_start(struct parser_state *state)
sample->pressure[0].mbar = 0;
sample->pressure[1].mbar = 0;
} else {
sample->sensor[0] = sanitize_sensor_id(state->cur_dive, !state->o2pressure_sensor);
sample->sensor[1] = sanitize_sensor_id(state->cur_dive, state->o2pressure_sensor);
sample->sensor[0] = sanitize_sensor_id(state->cur_dive.get(), !state->o2pressure_sensor);
sample->sensor[1] = sanitize_sensor_id(state->cur_dive.get(), state->o2pressure_sensor);
}
state->cur_sample = sample;
state->next_o2_sensor = 0;
@ -396,7 +393,7 @@ void divecomputer_start(struct parser_state *state)
/* Did we already fill that in? */
if (dc->samples || dc->model || dc->when) {
struct divecomputer *newdc = (divecomputer *)calloc(1, sizeof(*newdc));
struct divecomputer *newdc = new divecomputer;
if (newdc) {
dc->next = newdc;
dc = newdc;

View file

@ -54,7 +54,7 @@ struct parser_state {
enum import_source import_source = UNKNOWN;
struct divecomputer *cur_dc = nullptr; /* non-owning */
struct dive *cur_dive = nullptr; /* owning */
std::unique_ptr<dive> cur_dive; /* owning */
std::unique_ptr<dive_site> cur_dive_site; /* owning */
location_t cur_location;
struct dive_trip *cur_trip = nullptr; /* owning */

View file

@ -185,9 +185,9 @@ static void uemis_get_weight(std::string_view buffer, weightsystem_t &weight, in
weight.description = translate("gettextFromC", "unknown");
}
static struct dive *uemis_start_dive(uint32_t deviceid)
static std::unique_ptr<dive> uemis_start_dive(uint32_t deviceid)
{
struct dive *dive = alloc_dive();
auto dive = std::make_unique<struct dive>();
dive->dc.model = strdup("Uemis Zurich");
dive->dc.deviceid = deviceid;
return dive;
@ -788,7 +788,7 @@ static bool uemis_delete_dive(device_data_t *devdata, uint32_t diveid)
}
if (dive) {
devdata->log->dives->dives[--devdata->log->dives->nr] = NULL;
free_dive(dive);
delete dive;
return true;
}
@ -810,9 +810,10 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
{
using namespace std::string_literals;
bool done = false;
bool is_log = false, is_dive = false;
bool is_log = false;
std::vector<std::string_view> sections;
struct dive *dive = NULL;
std::unique_ptr<dive> owned_dive; // in log mode
struct dive *non_owned_dive = nullptr; // in dive (non-log) mode
int dive_no = 0;
#if UEMIS_DEBUG & 8
@ -831,7 +832,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
return false;
} else if (tp == "dive") {
/* this is dive detail */
is_dive = true;
is_log = false;
tp = next_token(bp);
if (tp != "1.0")
return false;
@ -840,7 +841,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
return false;
}
if (is_log) {
dive = uemis_start_dive(deviceid);
owned_dive = uemis_start_dive(deviceid);
} else {
/* remember, we don't know if this is the right entry,
* so first test if this is even a valid entry */
@ -897,57 +898,63 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
std::string(type).c_str(),
std::string(val).c_str());
#endif
if (is_log && tag == "object_id") {
from_chars(val, max_divenr);
dive->dc.diveid = max_divenr;
if (is_log) {
// Is log
if (tag == "object_id") {
from_chars(val, max_divenr);
owned_dive->dc.diveid = max_divenr;
#if UEMIS_DEBUG % 2
report_info("Adding new dive from log with object_id %d.\n", max_divenr);
report_info("Adding new dive from log with object_id %d.\n", max_divenr);
#endif
} else if (is_dive && tag == "logfilenr") {
/* this one tells us which dive we are adding data to */
int diveid = 0;
from_chars(val, diveid);
dive = get_dive_by_uemis_diveid(devdata, diveid);
if (dive_no != 0)
dive->number = dive_no;
if (for_dive)
*for_dive = diveid;
} else if (!is_log && dive && tag == "divespot_id") {
int divespot_id;
if (from_chars(val, divespot_id).ec != std::errc::invalid_argument) {
struct dive_site *ds = devdata->log->sites->create("from Uemis"s);
unregister_dive_from_dive_site(dive);
ds->add_dive(dive);
uemis_obj.mark_divelocation(dive->dc.diveid, divespot_id, ds);
}
parse_tag(owned_dive.get(), tag, val);
if (tag == "file_content")
done = true;
/* done with one dive (got the file_content tag), but there could be more:
* a '{' indicates the end of the record - but we need to see another "{{"
* later in the buffer to know that the next record is complete (it could
* be a short read because of some error */
if (done && bp.size() > 3) {
bp = bp.substr(1);
if (bp[0] != '{' && bp.find("{{") != std::string::npos) {
done = false;
record_dive_to_table(owned_dive.release(), devdata->log->dives.get());
owned_dive = uemis_start_dive(deviceid);
}
}
} else {
// Is dive
if (tag == "logfilenr") {
/* this one tells us which dive we are adding data to */
int diveid = 0;
from_chars(val, diveid);
non_owned_dive = get_dive_by_uemis_diveid(devdata, diveid);
if (dive_no != 0)
non_owned_dive->number = dive_no;
if (for_dive)
*for_dive = diveid;
} else if (non_owned_dive && tag == "divespot_id") {
int divespot_id;
if (from_chars(val, divespot_id).ec != std::errc::invalid_argument) {
struct dive_site *ds = devdata->log->sites->create("from Uemis"s);
unregister_dive_from_dive_site(non_owned_dive);
ds->add_dive(non_owned_dive);
uemis_obj.mark_divelocation(non_owned_dive->dc.diveid, divespot_id, ds);
}
#if UEMIS_DEBUG & 2
report_info("Created divesite %d for diveid : %d\n", dive->dive_site->uuid, dive->dc.diveid);
report_info("Created divesite %d for diveid : %d\n", non_owned_dive->dive_site->uuid, non_owned_dive->dc.diveid);
#endif
} else if (dive) {
parse_tag(dive, tag, val);
}
if (is_log && tag == "file_content")
done = true;
/* done with one dive (got the file_content tag), but there could be more:
* a '{' indicates the end of the record - but we need to see another "{{"
* later in the buffer to know that the next record is complete (it could
* be a short read because of some error */
if (done && bp.size() > 3) {
bp = bp.substr(1);
if (bp[0] != '{' && bp.find("{{") != std::string::npos) {
done = false;
record_dive_to_table(dive, devdata->log->dives.get());
dive = uemis_start_dive(deviceid);
} else if (non_owned_dive) {
parse_tag(non_owned_dive, tag, val);
}
}
}
if (is_log) {
if (dive->dc.diveid) {
record_dive_to_table(dive, devdata->log->dives.get());
} else { /* partial dive */
free_dive(dive);
if (owned_dive->dc.diveid)
record_dive_to_table(owned_dive.release(), devdata->log->dives.get());
else /* partial dive */
return false;
}
}
return true;
}

View file

@ -537,7 +537,7 @@ void PlannerDetails::setPlanNotes(QString plan)
}
PlannerWidgets::PlannerWidgets() :
planned_dive(alloc_dive()),
planned_dive(std::make_unique<dive>()),
dcNr(0),
plannerWidget(*planned_dive, dcNr, this),
plannerSettingsWidget(this)

View file

@ -3,8 +3,8 @@
#define DIVEPLANNER_H
#include "core/divemode.h"
#include "core/owning_ptrs.h"
#include <memory>
#include <QAbstractTableModel>
#include <QAbstractButton>
#include <QDateTime>
@ -91,7 +91,7 @@ public
slots:
void printDecoPlan();
private:
OwningDivePtr planned_dive;
std::unique_ptr<dive> planned_dive;
int dcNr;
public:
DivePlannerWidget plannerWidget;

View file

@ -209,7 +209,6 @@ MainWindow::MainWindow() :
#ifdef NO_USERMANUAL
ui.menuHelp->removeAction(ui.actionUserManual);
#endif
memset(&copyPasteDive, 0, sizeof(copyPasteDive));
memset(&what, 0, sizeof(what));
updateManager = new UpdateManager(this);
@ -703,7 +702,7 @@ void MainWindow::on_actionAddDive_triggered()
// create a dive an hour from now with a default depth (15m/45ft) and duration (40 minutes)
// as a starting point for the user to edit
struct dive d = { 0 };
struct dive d;
d.id = dive_getUniqID();
d.when = QDateTime::currentMSecsSinceEpoch() / 1000L + gettimezoneoffset() + 3600;
d.dc.duration.seconds = 40 * 60;

View file

@ -324,7 +324,7 @@ void ProfileWidget::unsetProfTissues()
void ProfileWidget::editDive()
{
editedDive.reset(alloc_dive());
editedDive = std::make_unique<dive>();
copy_dive(d, editedDive.get()); // Work on a copy of the dive
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::EDIT);
DivePlannerPointsModel::instance()->loadFromDive(editedDive.get(), dc);

View file

@ -48,7 +48,7 @@ private:
void editDive();
void exitEditMode();
void rotateDC(int dir);
OwningDivePtr editedDive;
std::unique_ptr<dive> editedDive;
bool placingCommand;
};

View file

@ -1191,7 +1191,7 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt
report_info("state :'%s'", qPrintable(state));
}
OwningDivePtr d_ptr(alloc_dive()); // Automatically delete dive if we exit early!
auto d_ptr = std::make_unique<dive>(); // Automatically delete dive if we exit early!
dive *d = d_ptr.get();
copy_dive(orig, d);
@ -1728,7 +1728,7 @@ int QMLManager::addDive()
// TODO: Duplicate code with desktop-widgets/mainwindow.cpp
// create a dive an hour from now with a default depth (15m/45ft) and duration (40 minutes)
// as a starting point for the user to edit
struct dive d = { 0 };
struct dive d;
int diveId = d.id = dive_getUniqID();
d.when = QDateTime::currentMSecsSinceEpoch() / 1000L + gettimezoneoffset() + 3600;
d.dc.duration.seconds = 40 * 60;

View file

@ -1185,8 +1185,8 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
if (!original_plan)
return;
struct dive *dive = alloc_dive();
copy_dive(d, dive);
auto dive = std::make_unique<struct dive>();
copy_dive(d, dive.get());
struct decostop original[60], deeper[60], shallower[60], shorter[60], longer[60];
deco_state_cache cache, save;
struct diveplan plan_copy;
@ -1214,7 +1214,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
goto finish;
if (my_instance != instanceCounter)
goto finish;
plan(&ds, &plan_copy, dive, dcNr, 1, original, cache, true, false);
plan(&ds, &plan_copy, dive.get(), dcNr, 1, original, cache, true, false);
free_dps(&plan_copy);
save.restore(&ds, false);
@ -1223,7 +1223,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
last_segment->next->depth.mm += delta_depth.mm;
if (my_instance != instanceCounter)
goto finish;
plan(&ds, &plan_copy, dive, dcNr, 1, deeper, cache, true, false);
plan(&ds, &plan_copy, dive.get(), dcNr, 1, deeper, cache, true, false);
free_dps(&plan_copy);
save.restore(&ds, false);
@ -1232,7 +1232,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
last_segment->next->depth.mm -= delta_depth.mm;
if (my_instance != instanceCounter)
goto finish;
plan(&ds, &plan_copy, dive, dcNr, 1, shallower, cache, true, false);
plan(&ds, &plan_copy, dive.get(), dcNr, 1, shallower, cache, true, false);
free_dps(&plan_copy);
save.restore(&ds, false);
@ -1240,7 +1240,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
last_segment->next->time += delta_time.seconds;
if (my_instance != instanceCounter)
goto finish;
plan(&ds, &plan_copy, dive, dcNr, 1, longer, cache, true, false);
plan(&ds, &plan_copy, dive.get(), dcNr, 1, longer, cache, true, false);
free_dps(&plan_copy);
save.restore(&ds, false);
@ -1248,7 +1248,7 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
last_segment->next->time -= delta_time.seconds;
if (my_instance != instanceCounter)
goto finish;
plan(&ds, &plan_copy, dive, dcNr, 1, shorter, cache, true, false);
plan(&ds, &plan_copy, dive.get(), dcNr, 1, shorter, cache, true, false);
free_dps(&plan_copy);
save.restore(&ds, false);
@ -1265,7 +1265,6 @@ void DivePlannerPointsModel::computeVariations(struct diveplan *original_plan, c
finish:
free_dps(original_plan);
free(original_plan);
free_dive(dive);
}
void DivePlannerPointsModel::computeVariationsDone(QString variations)

View file

@ -926,7 +926,7 @@ void smartrak_import(const char *file, struct divelog *log)
device_data_t devdata;
dc_family_t dc_fam = DC_FAMILY_NULL;
unsigned char *prf_buffer, *hdr_buffer;
struct dive *smtkdive = alloc_dive();
auto smtkdive = std::make_unique<dive>();
struct tm tm_date;
size_t hdr_length, prf_length;
dc_status_t rc = DC_STATUS_SUCCESS;
@ -956,7 +956,7 @@ void smartrak_import(const char *file, struct divelog *log)
if (rc != DC_STATUS_SUCCESS) {
report_error("[Error][smartrak_import]\t- %s - for dive %d", errmsg(rc), smtkdive->number);
} else {
rc = libdc_buffer_parser(smtkdive, &devdata, compl_buffer.data(), hdr_length + prf_length);
rc = libdc_buffer_parser(smtkdive.get(), &devdata, compl_buffer.data(), hdr_length + prf_length);
if (rc != DC_STATUS_SUCCESS)
report_error("[Error][libdc]\t\t- %s - for dive %d", errmsg(rc), smtkdive->number);
}
@ -985,7 +985,7 @@ void smartrak_import(const char *file, struct divelog *log)
int tankidxcol = coln(TANKIDX);
for (i = 0; i < tanks; i++) {
cylinder_t *tmptank = get_or_create_cylinder(smtkdive, i);
cylinder_t *tmptank = get_or_create_cylinder(smtkdive.get(), i);
if (!tmptank)
break;
if (tmptank->start.mbar == 0)
@ -1008,7 +1008,7 @@ void smartrak_import(const char *file, struct divelog *log)
smtk_build_tank_info(mdb_clon, tmptank, (char *)col[i + tankidxcol]->bind_ptr);
}
/* Check for duplicated cylinders and clean them */
smtk_clean_cylinders(smtkdive);
smtk_clean_cylinders(smtkdive.get());
/* Date issues with libdc parser - Take date time from mdb */
smtk_date_to_tm((char *)col[coln(_DATE)]->bind_ptr, &tm_date);
@ -1031,17 +1031,17 @@ void smartrak_import(const char *file, struct divelog *log)
smtkdive->suit = strdup(get(suit_list, atoi((char *)col[coln(SUITIDX)]->bind_ptr) - 1).c_str());
smtk_build_location(mdb_clon, (char *)col[coln(SITEIDX)]->bind_ptr, &smtkdive->dive_site, log);
smtkdive->buddy = strdup(smtk_locate_buddy(mdb_clon, (char *)col[0]->bind_ptr, buddy_list).c_str());
smtk_parse_relations(mdb_clon, smtkdive, (char *)col[0]->bind_ptr, "Type", "TypeRelation", type_list, true);
smtk_parse_relations(mdb_clon, smtkdive, (char *)col[0]->bind_ptr, "Activity", "ActivityRelation", activity_list, false);
smtk_parse_relations(mdb_clon, smtkdive, (char *)col[0]->bind_ptr, "Gear", "GearRelation", gear_list, false);
smtk_parse_relations(mdb_clon, smtkdive, (char *)col[0]->bind_ptr, "Fish", "FishRelation", fish_list, false);
smtk_parse_other(smtkdive, weather_list, "Weather", (char *)col[coln(WEATHERIDX)]->bind_ptr, false);
smtk_parse_other(smtkdive, underwater_list, "Underwater", (char *)col[coln(UNDERWATERIDX)]->bind_ptr, false);
smtk_parse_other(smtkdive, surface_list, "Surface", (char *)col[coln(SURFACEIDX)]->bind_ptr, false);
smtk_parse_bookmarks(mdb_clon, smtkdive, (char *)col[0]->bind_ptr);
smtk_parse_relations(mdb_clon, smtkdive.get(), (char *)col[0]->bind_ptr, "Type", "TypeRelation", type_list, true);
smtk_parse_relations(mdb_clon, smtkdive.get(), (char *)col[0]->bind_ptr, "Activity", "ActivityRelation", activity_list, false);
smtk_parse_relations(mdb_clon, smtkdive.get(), (char *)col[0]->bind_ptr, "Gear", "GearRelation", gear_list, false);
smtk_parse_relations(mdb_clon, smtkdive.get(), (char *)col[0]->bind_ptr, "Fish", "FishRelation", fish_list, false);
smtk_parse_other(smtkdive.get(), weather_list, "Weather", (char *)col[coln(WEATHERIDX)]->bind_ptr, false);
smtk_parse_other(smtkdive.get(), underwater_list, "Underwater", (char *)col[coln(UNDERWATERIDX)]->bind_ptr, false);
smtk_parse_other(smtkdive.get(), surface_list, "Surface", (char *)col[coln(SURFACEIDX)]->bind_ptr, false);
smtk_parse_bookmarks(mdb_clon, smtkdive.get(), (char *)col[0]->bind_ptr);
concat(&smtkdive->notes, "\n", std::string((char *)col[coln(REMARKS)]->bind_ptr));
record_dive_to_table(smtkdive, log->dives.get());
record_dive_to_table(smtkdive.release(), log->dives.get());
}
mdb_free_catalog(mdb_clon);
mdb->catalog = NULL;

View file

@ -9,14 +9,14 @@ void TestformatDiveGasString::init()
void TestformatDiveGasString::test_empty()
{
struct dive dive = {0};
struct dive dive;
QCOMPARE(formatDiveGasString(&dive), "air");
}
void TestformatDiveGasString::test_air()
{
struct dive dive = {0};
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->start.mbar = 230000;
@ -25,8 +25,9 @@ void TestformatDiveGasString::test_air()
QCOMPARE(formatDiveGasString(&dive), "air");
}
void TestformatDiveGasString::test_nitrox() {
struct dive dive = {0};
void TestformatDiveGasString::test_nitrox()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 320;
@ -36,8 +37,9 @@ void TestformatDiveGasString::test_nitrox() {
QCOMPARE(formatDiveGasString(&dive), "32%");
}
void TestformatDiveGasString::test_nitrox_not_use() {
struct dive dive = {0};
void TestformatDiveGasString::test_nitrox_not_use()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 320;
@ -54,8 +56,9 @@ void TestformatDiveGasString::test_nitrox_not_use() {
QCOMPARE(formatDiveGasString(&dive), "32%");
}
void TestformatDiveGasString::test_nitrox_deco() {
struct dive dive = {0};
void TestformatDiveGasString::test_nitrox_deco()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 320;
@ -71,8 +74,9 @@ void TestformatDiveGasString::test_nitrox_deco() {
QCOMPARE(formatDiveGasString(&dive), "32…100%");
}
void TestformatDiveGasString::test_reverse_nitrox_deco() {
struct dive dive = {0};
void TestformatDiveGasString::test_reverse_nitrox_deco()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 1000;
@ -88,8 +92,9 @@ void TestformatDiveGasString::test_reverse_nitrox_deco() {
QCOMPARE(formatDiveGasString(&dive), "27…100%");
}
void TestformatDiveGasString::test_trimix() {
struct dive dive = {0};
void TestformatDiveGasString::test_trimix()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 210;
@ -100,8 +105,9 @@ void TestformatDiveGasString::test_trimix() {
QCOMPARE(formatDiveGasString(&dive), "21/35");
}
void TestformatDiveGasString::test_trimix_deco() {
struct dive dive = {0};
void TestformatDiveGasString::test_trimix_deco()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 210;
@ -125,8 +131,9 @@ void TestformatDiveGasString::test_trimix_deco() {
QCOMPARE(formatDiveGasString(&dive), "21/35…100%");
}
void TestformatDiveGasString::test_reverse_trimix_deco() {
struct dive dive = {0};
void TestformatDiveGasString::test_reverse_trimix_deco()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 1000;
@ -150,8 +157,9 @@ void TestformatDiveGasString::test_reverse_trimix_deco() {
QCOMPARE(formatDiveGasString(&dive), "21/35…100%");
}
void TestformatDiveGasString::test_trimix_and_nitrox_same_o2() {
struct dive dive = {0};
void TestformatDiveGasString::test_trimix_and_nitrox_same_o2()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 250;
@ -169,8 +177,9 @@ void TestformatDiveGasString::test_trimix_and_nitrox_same_o2() {
QCOMPARE(formatDiveGasString(&dive), "25/25");
}
void TestformatDiveGasString::test_trimix_and_nitrox_lower_o2() {
struct dive dive = {0};
void TestformatDiveGasString::test_trimix_and_nitrox_lower_o2()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 220;
@ -188,8 +197,9 @@ void TestformatDiveGasString::test_trimix_and_nitrox_lower_o2() {
QCOMPARE(formatDiveGasString(&dive), "25/25");
}
void TestformatDiveGasString::test_ccr() {
struct dive dive = {0};
void TestformatDiveGasString::test_ccr()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 1000;
@ -208,8 +218,9 @@ void TestformatDiveGasString::test_ccr() {
QCOMPARE(formatDiveGasString(&dive), "21/35");
}
void TestformatDiveGasString::test_ccr_bailout() {
struct dive dive = {0};
void TestformatDiveGasString::test_ccr_bailout()
{
struct dive dive;
cylinder_t *cylinder = get_or_create_cylinder(&dive, 0);
cylinder->gasmix.o2.permille = 1000;

View file

@ -12,7 +12,7 @@
#define DEBUG 1
// testing the dive plan algorithm
static struct dive dive = { 0 };
static struct dive dive;
static struct decostop stoptable[60];
static struct deco_state test_deco_state;
extern bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, int dcNr, int timestep, struct decostop *decostoptable, deco_state_cache &cache, bool is_planner, bool show_disclaimer);