From 4f5e3a06ab9ea8dea656b07bff9d0f4022c5b6ba Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 5 Sep 2011 10:53:00 -0700 Subject: [PATCH] Parse Uemis cylinder data correctly. There's a big comment there now about what is going on. It took me a while to understand how the crazy seven-tank uemis dive computer information actually works. So the Uemis computer has 4 different "tank profiles": - single tank air (0) - single tank nitrox (1) - two-tank nitrox (2) - three-tank nitrox (3) and the computer always lists all seven tank cases (because that's how you fill them in). Depending on the "gas.template" you are supposed to then *use* just one particular profile. Why the computer doesn't just give you the tanks for that one profile, who knows? It seems to be more of the same "Uemis dive data isn't so much about the dive, it's about dive computer state" mentality. So we first get the profile information, and then based on that we need to pick the right tanks from the set of seven that we're presented with. All clear? Signed-off-by: Linus Torvalds --- parse-xml.c | 94 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 15 deletions(-) diff --git a/parse-xml.c b/parse-xml.c index 393ee00..700f0d8 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -587,7 +587,70 @@ static void uemis_time_zone(char *buffer, void *_when) *when += tz * 3600; } -/* Christ. Uemis tank data is a total mess. */ +/* 0 - air ; 1 - nitrox1 ; 2 - nitrox2 ; 3 = nitrox3 */ +static int uemis_gas_template; + +/* + * Christ. Uemis tank data is a total mess. + * + * We're passed a "virtual cylinder" (0 - 6) for the different + * Uemis tank cases ("air", "nitrox_1", "nitrox_2.{bottom,deco}" + * and "nitrox_3.{bottom,deco,travel}". We need to turn that + * into the actual cylinder data depending on the gas template, + * and ignore the ones that are irrelevant for that template. + * + * So for "template 2" (nitrox_2), we ignore virtual tanks 0-1 + * (which are "air" and "nitrox_1" respectively), and tanks 4-6 + * (which are the three "nitrox_3" tanks), and we turn virtual + * tanks 2/3 into actual tanks 0/1. + * + * Confused yet? + */ +static int uemis_cylinder_index(void *_cylinder) +{ + cylinder_t *cylinder = _cylinder; + unsigned int index = cylinder - dive->cylinder; + + if (index > 6) { + fprintf(stderr, "Uemis cylinder pointer calculations broken\n"); + return -1; + } + switch(uemis_gas_template) { + case 1: /* Dive uses tank 1 */ + index -= 1; + /* Fallthrough */ + case 0: /* Dive uses tank 0 */ + if (index) + index = -1; + break; + case 2: /* Dive uses tanks 2-3 */ + index -= 2; + if (index > 1) + index = -1; + break; + case 3: /* Dive uses tanks 4-6 */ + index -= 4; + if (index > 2) + index = -1; + break; + } + return index; +} + +static void uemis_cylindersize(char *buffer, void *_cylinder) +{ + int index = uemis_cylinder_index(_cylinder); + if (index >= 0) + cylindersize(buffer, &dive->cylinder[index].type.size); +} + +static void uemis_percent(char *buffer, void *_cylinder) +{ + int index = uemis_cylinder_index(_cylinder); + if (index >= 0) + percent(buffer, &dive->cylinder[index].gasmix.o2); +} + static int uemis_dive_match(struct dive *dive, const char *name, int len, char *buf) { return MATCH(".units.length", uemis_length_unit, &units) || @@ -600,20 +663,21 @@ static int uemis_dive_match(struct dive *dive, const char *name, int len, char * MATCH(".date_time", uemis_date_time, &dive->when) || MATCH(".time_zone", uemis_time_zone, &dive->when) || MATCH(".ambient.temperature", decicelsius, &dive->airtemp) || - MATCH(".air.bottom_tank.size", cylindersize, &dive->cylinder[0].type.size) || - MATCH(".air.bottom_tank.oxygen", percent, &dive->cylinder[0].gasmix.o2) || - MATCH(".nitrox_1.bottom_tank.size", cylindersize, &dive->cylinder[1].type.size) || - MATCH(".nitrox_1.bottom_tank.oxygen", percent, &dive->cylinder[1].gasmix.o2) || - MATCH(".nitrox_2.bottom_tank.size", cylindersize, &dive->cylinder[2].type.size) || - MATCH(".nitrox_2.bottom_tank.oxygen", percent, &dive->cylinder[2].gasmix.o2) || - MATCH(".nitrox_2.deco_tank.size", cylindersize, &dive->cylinder[3].type.size) || - MATCH(".nitrox_2.deco_tank.oxygen", percent, &dive->cylinder[3].gasmix.o2) || - MATCH(".nitrox_3.bottom_tank.size", cylindersize, &dive->cylinder[4].type.size) || - MATCH(".nitrox_3.bottom_tank.oxygen", percent, &dive->cylinder[4].gasmix.o2) || - MATCH(".nitrox_3.deco_tank.size", cylindersize, &dive->cylinder[5].type.size) || - MATCH(".nitrox_3.deco_tank.oxygen", percent, &dive->cylinder[5].gasmix.o2) || - MATCH(".nitrox_3.travel_tank.size", cylindersize, &dive->cylinder[6].type.size) || - MATCH(".nitrox_3.travel_tank.oxygen", percent, &dive->cylinder[6].gasmix.o2) || + MATCH(".gas.template", get_index, &uemis_gas_template) || + MATCH(".air.bottom_tank.size", uemis_cylindersize, dive->cylinder + 0) || + MATCH(".air.bottom_tank.oxygen", uemis_percent, dive->cylinder + 0) || + MATCH(".nitrox_1.bottom_tank.size", uemis_cylindersize, dive->cylinder + 1) || + MATCH(".nitrox_1.bottom_tank.oxygen", uemis_percent, dive->cylinder + 1) || + MATCH(".nitrox_2.bottom_tank.size", uemis_cylindersize, dive->cylinder + 2) || + MATCH(".nitrox_2.bottom_tank.oxygen", uemis_percent, dive->cylinder + 2) || + MATCH(".nitrox_2.deco_tank.size", uemis_cylindersize, dive->cylinder + 3) || + MATCH(".nitrox_2.deco_tank.oxygen", uemis_percent, dive->cylinder + 3) || + MATCH(".nitrox_3.bottom_tank.size", uemis_cylindersize, dive->cylinder + 4) || + MATCH(".nitrox_3.bottom_tank.oxygen", uemis_percent, dive->cylinder + 4) || + MATCH(".nitrox_3.deco_tank.size", uemis_cylindersize, dive->cylinder + 5) || + 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) || 0; } -- 2.43.0