X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=parse-xml.c;h=5eabc353c17c47e4e68db5e0db2ded912f2b1437;hb=93d07f631aec470fb9f920f66ccb03ce699942b5;hp=22ab8458e1f5871d932d4d5666c5df7ccc1a94dc;hpb=5804c2970eaaf0215b9862f767cf7aa745083744;p=ext%2Fsubsurface.git diff --git a/parse-xml.c b/parse-xml.c index 22ab845..5eabc35 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -3,11 +3,13 @@ #include #include #include +#define __USE_XOPEN #include #include #include #include "dive.h" +#include "uemis.h" int verbose; @@ -92,8 +94,14 @@ const struct units IMPERIAL_units = { */ static struct dive *dive; static struct sample *sample; +static struct { + int active; + duration_t time; + int type, flags, value; + const char *name; +} event; static struct tm tm; -static int event_index, cylinder_index; +static int cylinder_index; static enum import_source { UNKNOWN, @@ -417,7 +425,7 @@ static void water_pressure(char *buffer, void *_depth) if (!val.fp) break; /* cbar to atm */ - atm = (val.fp / 100) / 1.01325; + atm = bar_to_atm(val.fp * 10); /* * atm to cm. Why not mm? The precision just isn't * there. @@ -558,6 +566,34 @@ static int uddf_fill_sample(struct sample *sample, const char *name, int len, ch 0; } +static void eventtime(char *buffer, void *_duration) +{ + duration_t *duration = _duration; + sampletime(buffer, duration); + if (sample) + duration->seconds += sample->time.seconds; +} + +static void try_to_fill_event(const char *name, char *buf) +{ + int len = strlen(name); + + start_match("event", name, buf); + if (MATCH(".event", utf8_string, &event.name)) + return; + if (MATCH(".name", utf8_string, &event.name)) + return; + if (MATCH(".time", eventtime, &event.time)) + return; + if (MATCH(".type", get_index, &event.type)) + return; + if (MATCH(".flags", get_index, &event.flags)) + return; + if (MATCH(".value", get_index, &event.value)) + return; + nonmatch("event", name, buf); +} + /* We're in samples - try to convert the random xml value to something useful */ static void try_to_fill_sample(struct sample *sample, const char *name, char *buf) { @@ -568,6 +604,8 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu return; if (MATCH(".sample.cylpress", pressure, &sample->cylinderpressure)) return; + if (MATCH(".sample.cylinderindex", get_index, &sample->cylinderindex)) + return; if (MATCH(".sample.depth", depth, &sample->depth)) return; if (MATCH(".sample.temp", temperature, &sample->temperature)) @@ -605,8 +643,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) || @@ -644,8 +684,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) || @@ -736,6 +778,27 @@ 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; + + memset(&tm, 0, sizeof(tm)); + sscanf(buffer,"%d-%d-%dT%d:%d:%d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + *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; @@ -800,8 +863,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) || @@ -827,6 +892,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.float", uemis_duration, &dive->duration) || + MATCH(".dive.val.ts", uemis_ts, &dive->when) || + MATCH(".dive.val.bin", uemis_parse_divelog_binary, divep) || 0; } @@ -874,8 +942,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) || @@ -897,7 +967,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); @@ -905,22 +975,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; @@ -928,6 +998,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)) @@ -1050,9 +1122,9 @@ static void match_standard_cylinder(cylinder_type_t *type) if (type->description) return; - cuft = type->size.mliter / 28317.0; - cuft *= type->workingpressure.mbar / 1013.25; - psi = type->workingpressure.mbar / 68.95; + cuft = ml_to_cuft(type->size.mliter); + cuft *= to_ATM(type->workingpressure); + psi = to_PSI(type->workingpressure); switch (psi) { case 2300 ... 2500: /* 2400 psi: LP tank */ @@ -1105,8 +1177,9 @@ static void sanitize_cylinder_type(cylinder_type_t *type) return; if (input_units.volume == CUFT || import_source == SUUNTO) { - volume_of_air = type->size.mliter * 28.317; /* milli-cu ft to milliliter */ - atm = type->workingpressure.mbar / 1013.25; /* working pressure in atm */ + /* confusing - we don't really start from ml but millicuft !*/ + volume_of_air = cuft_to_l(type->size.mliter); + atm = to_ATM(type->workingpressure); /* working pressure in atm */ volume = volume_of_air / atm; /* milliliters at 1 atm: "true size" */ type->size.mliter = volume + 0.5; } @@ -1137,11 +1210,15 @@ static void dive_end(void) static void event_start(void) { + memset(&event, 0, sizeof(event)); + event.active = 1; } static void event_end(void) { - event_index++; + if (event.name && strcmp(event.name, "surface") != 0) + add_event(dive, event.time.seconds, event.type, event.flags, event.value, event.name); + event.active = 0; } static void cylinder_start(void) @@ -1156,7 +1233,6 @@ static void cylinder_end(void) static void sample_start(void) { sample = prepare_sample(&dive); - event_index = 0; } static void sample_end(void) @@ -1176,12 +1252,16 @@ static void entry(const char *name, int size, const char *raw) return; memcpy(buf, raw, size); buf[size] = 0; + if (event.active) { + try_to_fill_event(name, buf); + return; + } if (sample) { try_to_fill_sample(sample, name, buf); return; } if (dive) { - try_to_fill_dive(dive, name, buf); + try_to_fill_dive(&dive, name, buf); return; } } @@ -1324,6 +1404,7 @@ static struct nesting { { "SUUNTO", suunto_importer }, { "Divinglog", DivingLog_importer }, { "pre_dive", uemis_importer }, + { "dives", uemis_importer }, { "uddf", uddf_importer }, { NULL, } @@ -1380,7 +1461,9 @@ void parse_xml_file(const char *filename, GError **error) } return; } - + /* we assume that the last (or only) filename passed as argument is a + * great filename to use as default when saving the dives */ + set_filename(filename); reset_all(); dive_start(); traverse(xmlDocGetRootElement(doc));