diff options
author | Salvador Cuñat <salvador.cunat@gmail.com> | 2015-04-04 00:44:01 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2015-04-04 10:30:16 -0700 |
commit | 0fe21637ad753a87dc0dc4d44564a613b2b693d2 (patch) | |
tree | de030a01ab9fc9d21f57e2c5e8b738c870410cc0 | |
parent | e276ec65ba17e9eeea9625796ae5df96e654f65a (diff) | |
download | subsurface-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.c | 98 |
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) { |