+static int parse_gasmixes(struct dive *dive, parser_t *parser, int ngases)
+{
+ int i;
+
+ for (i = 0; i < ngases; i++) {
+ int rc;
+ gasmix_t gasmix = {0};
+ int o2, he;
+
+ rc = parser_get_field(parser, FIELD_TYPE_GASMIX, i, &gasmix);
+ if (rc != PARSER_STATUS_SUCCESS && rc != PARSER_STATUS_UNSUPPORTED)
+ return rc;
+
+ if (i >= MAX_CYLINDERS)
+ continue;
+
+ o2 = gasmix.oxygen * 1000 + 0.5;
+ he = gasmix.helium * 1000 + 0.5;
+
+ /* Ignore bogus data - libdivecomputer does some crazy stuff */
+ if (o2 < 210 || o2 >= 1000)
+ o2 = 0;
+ if (he < 0 || he >= 800 || o2+he >= 1000)
+ he = 0;
+
+ dive->cylinder[i].gasmix.o2.permille = o2;
+ dive->cylinder[i].gasmix.he.permille = he;
+ }
+ return PARSER_STATUS_SUCCESS;
+}
+
+void
+sample_cb(parser_sample_type_t type, parser_sample_value_t value, void *userdata)
+{
+ int i;
+ static const char *events[] = {
+ "none", "deco", "rbt", "ascent", "ceiling", "workload", "transmitter",
+ "violation", "bookmark", "surface", "safety stop", "gaschange",
+ "safety stop (voluntary)", "safety stop (mandatory)", "deepstop",
+ "ceiling (safety stop)", "unknown", "divetime", "maxdepth",
+ "OLF", "PO2", "airtime", "rgbm", "heading", "tissue level warning"};
+ struct dive **divep = userdata;
+ struct dive *dive = *divep;
+ struct sample *sample;
+
+ /*
+ * We fill in the "previous" sample - except for SAMPLE_TYPE_TIME,
+ * which creates a new one.
+ */
+ sample = dive->samples ? dive->sample+dive->samples-1 : NULL;
+
+ switch (type) {
+ case SAMPLE_TYPE_TIME:
+ sample = prepare_sample(divep);
+ sample->time.seconds = value.time;
+ finish_sample(*divep, sample);
+ break;
+ case SAMPLE_TYPE_DEPTH:
+ sample->depth.mm = value.depth * 1000 + 0.5;
+ break;
+ case SAMPLE_TYPE_PRESSURE:
+ sample->cylinderindex = value.pressure.tank;
+ sample->cylinderpressure.mbar = value.pressure.value * 1000 + 0.5;
+ break;
+ case SAMPLE_TYPE_TEMPERATURE:
+ sample->temperature.mkelvin = (value.temperature + 273.15) * 1000 + 0.5;
+ break;
+ case SAMPLE_TYPE_EVENT:
+ printf(" <event type=\"%u\" time=\"%u\" flags=\"%u\" value=\"%u\">%s</event>\n",
+ value.event.type, value.event.time, value.event.flags, value.event.value, events[value.event.type]);
+ break;
+ case SAMPLE_TYPE_RBT:
+ printf(" <rbt>%u</rbt>\n", value.rbt);
+ break;
+ case SAMPLE_TYPE_HEARTBEAT:
+ printf(" <heartbeat>%u</heartbeat>\n", value.heartbeat);
+ break;
+ case SAMPLE_TYPE_BEARING:
+ printf(" <bearing>%u</bearing>\n", value.bearing);
+ break;
+ case SAMPLE_TYPE_VENDOR:
+ printf(" <vendor type=\"%u\" size=\"%u\">", value.vendor.type, value.vendor.size);
+ for (i = 0; i < value.vendor.size; ++i)
+ printf("%02X", ((unsigned char *) value.vendor.data)[i]);
+ printf("</vendor>\n");
+ break;
+ default:
+ break;
+ }
+}
+
+
+static int parse_samples(struct dive **divep, parser_t *parser)
+{
+ // Parse the sample data.
+ printf("Parsing the sample data.\n");
+ return parser_samples_foreach(parser, sample_cb, divep);
+}
+