#include <string.h>
#include <stdlib.h>
#include <errno.h>
+#define __USE_XOPEN
#include <time.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include "dive.h"
+#include "uemis.h"
int verbose;
*/
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,
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.
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)
{
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))
/*
* 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) ||
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) ||
#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;
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) ||
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;
}
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) ||
}
/* 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);
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;
break;
}
+ struct dive *dive = *divep;
+
if (MATCH(".number", get_index, &dive->number))
return;
if (MATCH(".date", divedate, &dive->when))
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 */
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;
}
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)
static void sample_start(void)
{
sample = prepare_sample(&dive);
- event_index = 0;
}
static void sample_end(void)
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;
}
}
{ "SUUNTO", suunto_importer },
{ "Divinglog", DivingLog_importer },
{ "pre_dive", uemis_importer },
+ { "dives", uemis_importer },
{ "uddf", uddf_importer },
{ NULL, }