There are a few interesting issues with this:
- this requires a change to the SDA file format; thankfully I control that
format, too (the default files are not valid XML files)
- once again, the fact that adding samples can change the dive pointer
messes with me - I decided to change the interface of ALL of the
XXX_dive_match functions to take a struct dive**
I know this is not ideal as all the other functions don't need that -
but I would have hated the inconsistency
- there is the issue that we now overload two _different_ uemis formats in
the same function - that's certainly a potential point of confusion
- a minor detail is the problem that the SDA format is kinda odd to parse
and that we trigger on the duration field by it being the only float.
Yeah, that's not ideal - but again, I control the format, so I _know_
this is true.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <time.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
/*
* Crazy suunto xml. Look at how those o2/he things match up.
*/
/*
* Crazy suunto xml. Look at how those o2/he things match up.
*/
-static int suunto_dive_match(struct dive *dive, const char *name, int len, char *buf)
+static int suunto_dive_match(struct dive **divep, const char *name, int len, char *buf)
+ struct dive *dive = *divep;
+
return MATCH(".o2pct", percent, &dive->cylinder[0].gasmix.o2) ||
MATCH(".hepct_0", percent, &dive->cylinder[0].gasmix.he) ||
MATCH(".o2pct_2", percent, &dive->cylinder[1].gasmix.o2) ||
return MATCH(".o2pct", percent, &dive->cylinder[0].gasmix.o2) ||
MATCH(".hepct_0", percent, &dive->cylinder[0].gasmix.he) ||
MATCH(".o2pct_2", percent, &dive->cylinder[1].gasmix.o2) ||
-static int divinglog_dive_match(struct dive *dive, const char *name, int len, char *buf)
+static int divinglog_dive_match(struct dive **divep, const char *name, int len, char *buf)
+ struct dive *dive = *divep;
+
return MATCH(".divedate", divedate, &dive->when) ||
MATCH(".entrytime", divetime, &dive->when) ||
MATCH(".depth", depth, &dive->maxdepth) ||
return MATCH(".divedate", divedate, &dive->when) ||
MATCH(".entrytime", divetime, &dive->when) ||
MATCH(".depth", depth, &dive->maxdepth) ||
+static void uemis_ts(char *buffer, void *_when)
+{
+ struct tm tm;
+ time_t *when = _when;
+
+ strptime(buffer, "%Y-%m-%dT%H:%M:%S", &tm);
+ *when = utc_mktime(&tm);
+}
+
+static void uemis_duration(char *buffer, void *_duration)
+{
+ duration_t *duration = _duration;
+ duration->seconds = atof(buffer) * 60 + 0.5;
+}
+
/* 0 - air ; 1 - nitrox1 ; 2 - nitrox2 ; 3 = nitrox3 */
static int uemis_gas_template;
/* 0 - air ; 1 - nitrox1 ; 2 - nitrox2 ; 3 = nitrox3 */
static int uemis_gas_template;
percent(buffer, &dive->cylinder[index].gasmix.o2);
}
percent(buffer, &dive->cylinder[index].gasmix.o2);
}
-static int uemis_dive_match(struct dive *dive, const char *name, int len, char *buf)
+static int uemis_dive_match(struct dive **divep, const char *name, int len, char *buf)
+ struct dive *dive = *divep;
+
return MATCH(".units.length", uemis_length_unit, &input_units) ||
MATCH(".units.volume", uemis_volume_unit, &input_units) ||
MATCH(".units.pressure", uemis_pressure_unit, &input_units) ||
return MATCH(".units.length", uemis_length_unit, &input_units) ||
MATCH(".units.volume", uemis_volume_unit, &input_units) ||
MATCH(".units.pressure", uemis_pressure_unit, &input_units) ||
MATCH(".nitrox_3.deco_tank.oxygen", uemis_percent, dive->cylinder + 5) ||
MATCH(".nitrox_3.travel_tank.size", uemis_cylindersize, dive->cylinder + 6) ||
MATCH(".nitrox_3.travel_tank.oxygen", uemis_percent, dive->cylinder + 6) ||
MATCH(".nitrox_3.deco_tank.oxygen", uemis_percent, dive->cylinder + 5) ||
MATCH(".nitrox_3.travel_tank.size", uemis_cylindersize, dive->cylinder + 6) ||
MATCH(".nitrox_3.travel_tank.oxygen", uemis_percent, dive->cylinder + 6) ||
- MATCH(".dive.val.bin", uemis_parse_divelog_binary, &dive) ||
+ MATCH(".dive.val.float", uemis_duration, &dive->duration) ||
+ MATCH(".dive.val.ts", uemis_ts, &dive->when) ||
+ MATCH(".dive.val.bin", uemis_parse_divelog_binary, divep) ||
-static int uddf_dive_match(struct dive *dive, const char *name, int len, char *buf)
+static int uddf_dive_match(struct dive **divep, const char *name, int len, char *buf)
+ struct dive *dive = *divep;
+
return MATCH(".datetime", uddf_datetime, &dive->when) ||
MATCH(".diveduration", duration, &dive->duration) ||
MATCH(".greatestdepth", depth, &dive->maxdepth) ||
return MATCH(".datetime", uddf_datetime, &dive->when) ||
MATCH(".diveduration", duration, &dive->duration) ||
MATCH(".greatestdepth", depth, &dive->maxdepth) ||
}
/* We're in the top-level dive xml. Try to convert whatever value to a dive value */
}
/* We're in the top-level dive xml. Try to convert whatever value to a dive value */
-static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
+static void try_to_fill_dive(struct dive **divep, const char *name, char *buf)
{
int len = strlen(name);
{
int len = strlen(name);
switch (import_source) {
case SUUNTO:
switch (import_source) {
case SUUNTO:
- if (suunto_dive_match(dive, name, len, buf))
+ if (suunto_dive_match(divep, name, len, buf))
return;
break;
case UEMIS:
return;
break;
case UEMIS:
- if (uemis_dive_match(dive, name, len, buf))
+ if (uemis_dive_match(divep, name, len, buf))
return;
break;
case DIVINGLOG:
return;
break;
case DIVINGLOG:
- if (divinglog_dive_match(dive, name, len, buf))
+ if (divinglog_dive_match(divep, name, len, buf))
return;
break;
case UDDF:
return;
break;
case UDDF:
- if (uddf_dive_match(dive, name, len, buf))
+ if (uddf_dive_match(divep, name, len, buf))
+ struct dive *dive = *divep;
+
if (MATCH(".number", get_index, &dive->number))
return;
if (MATCH(".date", divedate, &dive->when))
if (MATCH(".number", get_index, &dive->number))
return;
if (MATCH(".date", divedate, &dive->when))
- try_to_fill_dive(dive, name, buf);
+ try_to_fill_dive(&dive, name, buf);
/*
* parse uemis base64 data blob into struct dive
*/
/*
* parse uemis base64 data blob into struct dive
*/
-void uemis_parse_divelog_binary(char *base64, struct dive **divep) {
+void uemis_parse_divelog_binary(char *base64, void *datap) {
int datalen;
int i;
uint8_t *data;
struct sample *sample;
int datalen;
int i;
uint8_t *data;
struct sample *sample;
+ struct dive **divep = datap;
struct dive *dive = *divep;
int template, gasoffset;
struct dive *dive = *divep;
int template, gasoffset;
#define DEVICE_TYPE_UEMIS (-1)
void uemis_import();
#define DEVICE_TYPE_UEMIS (-1)
void uemis_import();
-void uemis_parse_divelog_binary(char *base64, struct dive **divep);
+void uemis_parse_divelog_binary(char *base64, void *divep);