]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Integrate loading of uemis SDA files into the regular xml parsing
authorDirk Hohndel <dirk@hohndel.org>
Mon, 3 Oct 2011 04:59:54 +0000 (21:59 -0700)
committerDirk Hohndel <dirk@hohndel.org>
Mon, 3 Oct 2011 05:20:29 +0000 (22:20 -0700)
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>
parse-xml.c
uemis.c
uemis.h

index 4e68e8ee25e9ee3fa9cbc823b58d51db87a2b8b8..6a08a3845c9551c3f35b818ff5c51b468537abda 100644 (file)
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
+#define __USE_XOPEN
 #include <time.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
@@ -640,8 +641,10 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu
 /*
  * 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) ||
@@ -679,8 +682,10 @@ static void divinglog_place(char *place, void *_location)
        country = NULL;
 }
 
-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) ||
@@ -771,6 +776,21 @@ static void uemis_time_zone(char *buffer, void *_when)
 #endif
 }
 
+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;
 
@@ -835,8 +855,10 @@ static void uemis_percent(char *buffer, void *_cylinder)
                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) ||
@@ -862,7 +884,9 @@ static int uemis_dive_match(struct dive *dive, const char *name, int len, char *
                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) ||
                0;
 }
 
@@ -910,8 +934,10 @@ success:
        free(buffer);
 }
 
-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) ||
@@ -933,7 +959,7 @@ static void gps_location(char *buffer, void *_dive)
 }
 
 /* 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);
 
@@ -941,22 +967,22 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
 
        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:
-               if (uemis_dive_match(dive, name, len, buf))
+               if (uemis_dive_match(divep, name, len, buf))
                        return;
                break;
 
        case DIVINGLOG:
-               if (divinglog_dive_match(dive, name, len, buf))
+               if (divinglog_dive_match(divep, name, len, buf))
                        return;
                break;
 
        case UDDF:
-               if (uddf_dive_match(dive, name, len, buf))
+               if (uddf_dive_match(divep, name, len, buf))
                        return;
                break;
 
@@ -964,6 +990,8 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
                break;
        }
 
+       struct dive *dive = *divep;
+
        if (MATCH(".number", get_index, &dive->number))
                return;
        if (MATCH(".date", divedate, &dive->when))
@@ -1224,7 +1252,7 @@ static void entry(const char *name, int size, const char *raw)
                return;
        }
        if (dive) {
-               try_to_fill_dive(dive, name, buf);
+               try_to_fill_dive(&dive, name, buf);
                return;
        }
 }
diff --git a/uemis.c b/uemis.c
index 259d30c53758f9d8ad3e8f2868ef47fa30534efa..769752915edb1f93e645645a8097af56d79b71c8 100644 (file)
--- a/uemis.c
+++ b/uemis.c
@@ -180,11 +180,12 @@ bail:
 /*
  * 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;
+       struct dive **divep = datap;
        struct dive *dive = *divep;
        int template, gasoffset;
 
diff --git a/uemis.h b/uemis.h
index 62aeb54225abf3a00a1186064132656baf96d2ad..99cf444454d07b370cbcad5a85cca23ec19c71b7 100644 (file)
--- a/uemis.h
+++ b/uemis.h
@@ -9,6 +9,6 @@
 #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);
 
 #endif /* DIVE_H */