mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	Merge extra_data list when merging two dives of the same dive computer
When merging two dives into a longer one, merge the dive computer extra_data list too. We just pick all the extra-data (but avoid entirely duplicate key/value entries). Note that this can cause confusing extra-data, in that both dives migth have things like "battery percentage at beginning/end of dive" keys, and if the values are different, you'll now get *both* of those values, but that's better than randomly just taking one of them. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									3184830f51
								
							
						
					
					
						commit
						baeb0ba280
					
				
					 1 changed files with 53 additions and 0 deletions
				
			
		
							
								
								
									
										53
									
								
								core/dive.c
									
										
									
									
									
								
							
							
						
						
									
										53
									
								
								core/dive.c
									
										
									
									
									
								
							|  | @ -2009,6 +2009,58 @@ static void merge_samples(struct divecomputer *res, | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Does the extradata key/value pair already exist in the | ||||
|  * supplied dive computer data? | ||||
|  * | ||||
|  * This is not hugely efficient (with the whole "do this for | ||||
|  * every value you merge" it's O(n**2)) but it's not like we | ||||
|  * have very many extra_data entries per dive computer anyway. | ||||
|  */ | ||||
| static bool extra_data_exists(const struct extra_data *ed, const struct divecomputer *dc) | ||||
| { | ||||
| 	const struct extra_data *p; | ||||
| 
 | ||||
| 	for (p = dc->extra_data; p; p = p->next) { | ||||
| 		if (strcmp(p->key, ed->key)) | ||||
| 			continue; | ||||
| 		if (strcmp(p->value, ed->value)) | ||||
| 			continue; | ||||
| 		return true; | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Merge extra_data. | ||||
|  * | ||||
|  * The extra data from 'a' has already been copied into 'res'. So | ||||
|  * we really should just copy over the data from 'b' too. | ||||
|  */ | ||||
| static void merge_extra_data(struct divecomputer *res, | ||||
| 			  const struct divecomputer *a, const struct divecomputer *b) | ||||
| { | ||||
| 	struct extra_data **ed, *src; | ||||
| 
 | ||||
| 	// Find the place to add things in the result
 | ||||
| 	ed = &res->extra_data; | ||||
| 	while (*ed) | ||||
| 		ed = &(*ed)->next; | ||||
| 
 | ||||
| 	for (src = b->extra_data; src; src = src->next) { | ||||
| 		if (extra_data_exists(src, a)) | ||||
| 			continue; | ||||
| 		*ed = malloc(sizeof(struct extra_data)); | ||||
| 		if (!*ed) | ||||
| 			break; | ||||
| 		copy_extra_data(src, *ed); | ||||
| 		ed = &(*ed)->next; | ||||
| 	} | ||||
| 
 | ||||
| 	// Terminate the result list
 | ||||
| 	*ed = NULL; | ||||
| } | ||||
| 
 | ||||
| static char *merge_text(const char *a, const char *b, const char *sep) | ||||
| { | ||||
| 	char *res; | ||||
|  | @ -3110,6 +3162,7 @@ static void interleave_dive_computers(struct dive *d, struct divecomputer *res, | |||
| 		if (match) { | ||||
| 			merge_events(d, res, a, match, cylinders_map_a, cylinders_map_b, offset); | ||||
| 			merge_samples(res, a, match, cylinders_map_a, cylinders_map_b, offset); | ||||
| 			merge_extra_data(res, a, match); | ||||
| 			/* Use the diveid of the later dive! */ | ||||
| 			if (offset > 0) | ||||
| 				res->diveid = match->diveid; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue