aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Salvador Cuñat <salvador.cunat@gmail.com>2015-04-04 00:44:01 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-04-04 10:30:16 -0700
commit0fe21637ad753a87dc0dc4d44564a613b2b693d2 (patch)
treede030a01ab9fc9d21f57e2c5e8b738c870410cc0
parente276ec65ba17e9eeea9625796ae5df96e654f65a (diff)
downloadsubsurface-0fe21637ad753a87dc0dc4d44564a613b2b693d2.tar.gz
libdivecomputer.c: Split dive_cb() callback in two
dive_cb() needs a defined device to work as it's built for DC download tasks. Move part of the functionality of dive_cb() to a new function libdc_header_parser() which can be used to parse headers from raw data buffers with no device set. Obviously dive_cb() will call the new funtion for header parsing too. Two changes in logic: 1- In parse_gasmixes() set data pointer to NULL. This pointer is passed to the function, but it's not used. While this data pointer exists in DC import, via dive_cb(), it doesn't in file import as data has previously been set in the parser. 2- While parsing gas mixes do not return on rc = DC_STATUS_UNSUPORTED because it would end our dive parsing just if the device doesn't support gases, which seems undesirable in both, DC or file import. Signed-off-by: Salvador Cuñat <salvador.cunat@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--libdivecomputer.c98
1 files changed, 59 insertions, 39 deletions
diff --git a/libdivecomputer.c b/libdivecomputer.c
index 27e3dbd10..690cde09f 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -434,45 +434,19 @@ static void parse_string_field(struct dive *dive, dc_field_string_t *str)
}
#endif
-/* returns true if we want libdivecomputer's dc_device_foreach() to continue,
- * false otherwise */
-static int dive_cb(const unsigned char *data, unsigned int size,
- const unsigned char *fingerprint, unsigned int fsize,
- void *userdata)
+static dc_status_t libdc_header_parser(dc_parser_t *parser, struct device_data_t *devdata, struct dive *dive)
{
- int rc;
- dc_parser_t *parser = NULL;
- device_data_t *devdata = userdata;
+ dc_status_t rc = 0;
dc_datetime_t dt = { 0 };
struct tm tm;
- struct dive *dive = NULL;
- /* reset the deco / ndl data */
- ndl = stoptime = stopdepth = 0;
- in_deco = false;
-
- rc = create_parser(devdata, &parser);
- if (rc != DC_STATUS_SUCCESS) {
- dev_info(devdata, translate("gettextFromC", "Unable to create parser for %s %s"), devdata->vendor, devdata->product);
- return false;
- }
-
- rc = dc_parser_set_data(parser, data, size);
- if (rc != DC_STATUS_SUCCESS) {
- dev_info(devdata, translate("gettextFromC", "Error registering the data"));
- goto error_exit;
- }
-
- import_dive_number++;
- dive = alloc_dive();
rc = dc_parser_get_datetime(parser, &dt);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC", "Error parsing the datetime"));
- goto error_exit;
+ return rc;
}
- dive->dc.model = strdup(devdata->model);
+
dive->dc.deviceid = devdata->deviceid;
- dive->dc.diveid = calculate_diveid(fingerprint, fsize);
if (rc == DC_STATUS_SUCCESS) {
tm.tm_year = dt.year;
@@ -483,13 +457,14 @@ static int dive_cb(const unsigned char *data, unsigned int size,
tm.tm_sec = dt.second;
dive->when = dive->dc.when = utc_mktime(&tm);
}
+
// Parse the divetime.
dev_info(devdata, translate("gettextFromC", "Dive %d: %s"), import_dive_number, get_dive_date_c_string(dive->when));
unsigned int divetime = 0;
rc = dc_parser_get_field(parser, DC_FIELD_DIVETIME, 0, &divetime);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC", "Error parsing the divetime"));
- goto error_exit;
+ return rc;
}
if (rc == DC_STATUS_SUCCESS)
dive->dc.duration.seconds = divetime;
@@ -499,7 +474,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
rc = dc_parser_get_field(parser, DC_FIELD_MAXDEPTH, 0, &maxdepth);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC", "Error parsing the maxdepth"));
- goto error_exit;
+ return rc;
}
if (rc == DC_STATUS_SUCCESS)
dive->dc.maxdepth.mm = rint(maxdepth * 1000);
@@ -518,7 +493,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
rc = dc_parser_get_field(parser, temp_fields[i], 0, &temperature);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC", "Error parsing temperature"));
- goto error_exit;
+ return rc;
}
if (rc == DC_STATUS_SUCCESS)
switch(i) {
@@ -538,7 +513,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
rc = dc_parser_get_field(parser, DC_FIELD_GASMIX_COUNT, 0, &ngases);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC", "Error parsing the gas mix count"));
- goto error_exit;
+ return rc;
}
#if DC_VERSION_CHECK(0, 3, 0)
@@ -550,7 +525,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
rc = dc_parser_get_field(parser, DC_FIELD_SALINITY, 0, &salinity);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC", "Error obtaining water salinity"));
- goto error_exit;
+ return rc;
}
if (rc == DC_STATUS_SUCCESS)
dive->dc.salinity = rint(salinity.density * 10.0);
@@ -559,7 +534,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
rc = dc_parser_get_field(parser, DC_FIELD_ATMOSPHERIC, 0, &surface_pressure);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC", "Error obtaining surface pressure"));
- goto error_exit;
+ return rc;
}
if (rc == DC_STATUS_SUCCESS)
dive->dc.surface_pressure.mbar = rint(surface_pressure * 1000.0);
@@ -584,7 +559,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
rc = dc_parser_get_field(parser, DC_FIELD_DIVEMODE, 0, &divemode);
if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC", "Error obtaining divemode"));
- goto error_exit;
+ return rc;
}
if (rc == DC_STATUS_SUCCESS)
switch(divemode) {
@@ -601,12 +576,57 @@ static int dive_cb(const unsigned char *data, unsigned int size,
}
#endif
- rc = parse_gasmixes(devdata, dive, parser, ngases, data);
- if (rc != DC_STATUS_SUCCESS) {
+ rc = parse_gasmixes(devdata, dive, parser, ngases, NULL);
+ if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED) {
dev_info(devdata, translate("gettextFromC", "Error parsing the gas mix"));
+ return rc;
+ }
+
+ return DC_STATUS_SUCCESS;
+}
+
+/* returns true if we want libdivecomputer's dc_device_foreach() to continue,
+ * false otherwise */
+static int dive_cb(const unsigned char *data, unsigned int size,
+ const unsigned char *fingerprint, unsigned int fsize,
+ void *userdata)
+{
+ int rc;
+ dc_parser_t *parser = NULL;
+ device_data_t *devdata = userdata;
+ dc_datetime_t dt = { 0 };
+ struct tm tm;
+ struct dive *dive = NULL;
+
+ /* reset the deco / ndl data */
+ ndl = stoptime = stopdepth = 0;
+ in_deco = false;
+
+ rc = create_parser(devdata, &parser);
+ if (rc != DC_STATUS_SUCCESS) {
+ dev_info(devdata, translate("gettextFromC", "Unable to create parser for %s %s"), devdata->vendor, devdata->product);
+ return false;
+ }
+
+ rc = dc_parser_set_data(parser, data, size);
+ if (rc != DC_STATUS_SUCCESS) {
+ dev_info(devdata, translate("gettextFromC", "Error registering the data"));
goto error_exit;
}
+ import_dive_number++;
+ dive = alloc_dive();
+
+ // Parse the dive's header data
+ rc = libdc_header_parser (parser, devdata, dive);
+ if (rc != DC_STATUS_SUCCESS) {
+ dev_info(devdata, translate("getextFromC", "Error parsing the header"));
+ goto error_exit;
+ }
+
+ dive->dc.model = strdup(devdata->model);
+ dive->dc.diveid = calculate_diveid(fingerprint, fsize);
+
// Initialize the sample data.
rc = parse_samples(devdata, &dive->dc, parser);
if (rc != DC_STATUS_SUCCESS) {