mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									bfb54aa581
								
							
						
					
					
						commit
						cc39f709ce
					
				
					 35 changed files with 289 additions and 308 deletions
				
			
		|  | @ -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.
 | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ namespace Command { | |||
| 
 | ||||
| // This helper structure describes a dive that we want to add.
 | ||||
| struct DiveToAdd { | ||||
| 	OwningDivePtr	 dive;		// Dive to add
 | ||||
| 	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
 | ||||
| }; | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
| } | ||||
|  |  | |||
|  | @ -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++; | ||||
| 	} | ||||
|  |  | |||
|  | @ -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...
 | ||||
|  |  | |||
							
								
								
									
										53
									
								
								core/dive.h
									
										
									
									
									
								
							
							
						
						
									
										53
									
								
								core/dive.h
									
										
									
									
									
								
							|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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]) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 */ | ||||
|  |  | |||
|  | @ -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,36 +898,18 @@ 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") { | ||||
| 		if (is_log) { | ||||
| 			// Is log
 | ||||
| 			if (tag == "object_id") { | ||||
| 				from_chars(val, max_divenr); | ||||
| 			dive->dc.diveid = 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); | ||||
| #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); | ||||
| 			} | ||||
| #if UEMIS_DEBUG & 2 | ||||
| 			report_info("Created divesite %d for diveid : %d\n", dive->dive_site->uuid, dive->dc.diveid); | ||||
| #endif | ||||
| 		} else if (dive) { | ||||
| 			parse_tag(dive, tag, val); | ||||
| 		} | ||||
| 		if (is_log && tag == "file_content") | ||||
| 			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 "{{" | ||||
|  | @ -936,19 +919,43 @@ 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.get()); | ||||
| 				dive = uemis_start_dive(deviceid); | ||||
| 					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", non_owned_dive->dive_site->uuid, non_owned_dive->dc.diveid); | ||||
| #endif | ||||
| 			} 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; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -209,7 +209,6 @@ MainWindow::MainWindow() : | |||
| #ifdef NO_USERMANUAL | ||||
| 	ui.menuHelp->removeAction(ui.actionUserManual); | ||||
| #endif | ||||
| 	memset(©PasteDive, 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; | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ private: | |||
| 	void editDive(); | ||||
| 	void exitEditMode(); | ||||
| 	void rotateDC(int dir); | ||||
| 	OwningDivePtr editedDive; | ||||
| 	std::unique_ptr<dive> editedDive; | ||||
| 	bool placingCommand; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue