summaryrefslogtreecommitdiffstats
path: root/parse-xml.c
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2012-10-10 18:14:55 +0900
committerGravatar Dirk Hohndel <dirk@hohndel.org>2012-10-11 15:13:39 +0900
commit94c98865a7a9de833e8ebb593d3db1058246e410 (patch)
treedcdbb6fccf8c6b4ea5183d2db9ee62783d56a55e /parse-xml.c
parenta2afe4128082b603add2b2be83f97ff78e0d0169 (diff)
downloadsubsurface-94c98865a7a9de833e8ebb593d3db1058246e410.tar.gz
Improve on the DivingLog importer a bit
This adds a few fields that we parse, but more importantly it also tries to dynamically decide if the sample temperatures and pressures are in imperial or metric units. Dirk suspects that DivingLog generally always does everything in metric, and the reason why he has crazy sample data in imperial units (both for pressure and temperature) may be due to a bug in the early Uemis importer for DivingLog. Which would actually make a lot more sense than DivingLog really being so insane on purpose. Anyway, Dirk's brother Jurgen seems to have everything in metric units, which would be much saner. Maybe we should throw away the support for insane DivingLog files entirely, since it is possible that the only use ever of the possible source of that bug was Dirk's use of the Uemis importer. But for now, we end up just guessing. Current guesses: - water temperature is below 32 dgC, so 32+ degrees is in Fahrenheit. - tank pressures are below 400 bar, so higher values than that must be psi. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'parse-xml.c')
-rw-r--r--parse-xml.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/parse-xml.c b/parse-xml.c
index 698fe2a2f..2c47f81e6 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -573,6 +573,14 @@ static int uemis_fill_sample(struct sample *sample, const char *name, int len, c
* what Diving Log uses for "no temperature".
*
* So throw away crap like that.
+ *
+ * It gets worse. Sometimes the sample temperatures are in
+ * Celsius, which apparently happens if you are in a SI
+ * locale. So we now do:
+ *
+ * - temperatures < 32.0 == Celsius
+ * - temperature == 32.0 -> garbage, it's a missing temperature (zero converted from C to F)
+ * - temperatures > 32.0 == Fahrenheit
*/
static void fahrenheit(char *buffer, void *_temperature)
{
@@ -584,7 +592,10 @@ static void fahrenheit(char *buffer, void *_temperature)
/* Floating point equality is evil, but works for small integers */
if (val.fp == 32.0)
break;
- temperature->mkelvin = (val.fp + 459.67) * 5000/9;
+ if (val.fp < 32.0)
+ temperature->mkelvin = C_to_mkelvin(val.fp);
+ else
+ temperature->mkelvin = F_to_mkelvin(val.fp);
break;
default:
fprintf(stderr, "Crazy Diving Log temperature reading %s\n", buffer);
@@ -601,15 +612,28 @@ static void fahrenheit(char *buffer, void *_temperature)
* these inconvenient typed structures, and you have to say
* "pressure->mbar" to get the actual value. Exactly so that
* you can never have unit confusion.
+ *
+ * It gets worse: sometimes apparently the pressures are in
+ * bar, sometimes in psi. Dirk suspects that this may be a
+ * DivingLog Uemis importer bug, and that they are always
+ * supposed to be in bar, but that the importer got the
+ * sample importing wrong.
+ *
+ * Sadly, there's no way to really tell. So I think we just
+ * have to have some arbitrary cut-off point where we assume
+ * that smaller values mean bar.. Not good.
*/
-static void psi(char *buffer, void *_pressure)
+static void psi_or_bar(char *buffer, void *_pressure)
{
pressure_t *pressure = _pressure;
union int_or_float val;
switch (integer_or_float(buffer, &val)) {
case FLOAT:
- pressure->mbar = val.fp * 68.95 + 0.5;
+ if (val.fp > 400)
+ pressure->mbar = psi_to_mbar(val.fp);
+ else
+ pressure->mbar = val.fp * 1000 + 0.5;
break;
default:
fprintf(stderr, "Crazy Diving Log PSI reading %s\n", buffer);
@@ -622,7 +646,7 @@ static int divinglog_fill_sample(struct sample *sample, const char *name, int le
return MATCH(".p.time", sampletime, &sample->time) ||
MATCH(".p.depth", depth, &sample->depth) ||
MATCH(".p.temp", fahrenheit, &sample->temperature) ||
- MATCH(".p.press1", psi, &sample->cylinderpressure) ||
+ MATCH(".p.press1", psi_or_bar, &sample->cylinderpressure) ||
0;
}
@@ -740,8 +764,11 @@ static int divinglog_dive_match(struct dive **divep, const char *name, int len,
return MATCH(".divedate", divedate, &dive->when) ||
MATCH(".entrytime", divetime, &dive->when) ||
MATCH(".depth", depth, &dive->maxdepth) ||
+ MATCH(".tanktype", utf8_string, &dive->cylinder[0].type.description) ||
MATCH(".tanksize", cylindersize, &dive->cylinder[0].type.size) ||
MATCH(".presw", pressure, &dive->cylinder[0].type.workingpressure) ||
+ MATCH(".press", pressure, &dive->cylinder[0].start) ||
+ MATCH(".prese", pressure, &dive->cylinder[0].end) ||
MATCH(".comments", utf8_string, &dive->notes) ||
MATCH(".buddy.names", utf8_string, &dive->buddy) ||
MATCH(".country.name", utf8_string, &country) ||