Cache the parser data internally.

This commit is contained in:
Jef Driesen 2015-03-07 11:50:24 +01:00
parent fb417ee5b5
commit 8b64ce0edc

View File

@ -49,6 +49,8 @@
#define UNSUPPORTED 0xFFFFFFFF
#define NGASMIXES 3
typedef enum {
PRESSURE_DEPTH,
RBT,
@ -93,6 +95,11 @@ struct uwatec_smart_parser_t {
const uwatec_smart_header_info_t *header;
unsigned int headersize;
unsigned int nsamples;
// Cached fields.
unsigned int cached;
unsigned int trimix;
unsigned int ngasmixes;
unsigned int oxygen[NGASMIXES];
};
static dc_status_t uwatec_smart_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
@ -254,6 +261,45 @@ uwatec_smart_sample_info_t uwatec_smart_tec_samples[] = {
};
static dc_status_t
uwatec_smart_parser_cache (uwatec_smart_parser_t *parser)
{
const unsigned char *data = parser->base.data;
unsigned int size = parser->base.size;
if (parser->cached) {
return DC_STATUS_SUCCESS;
}
unsigned int trimix = 0;
if (parser->model == GALILEO || parser->model == GALILEOTRIMIX) {
if (size < 44)
return DC_STATUS_DATAFORMAT;
if (data[43] & 0x80) {
trimix = 1;
}
}
// Get the gas mixes.
unsigned int oxygen[NGASMIXES] = {0};
unsigned int ngasmixes = (trimix ? 0 : parser->header->ngases);
for (unsigned int i = 0; i < ngasmixes; ++i) {
oxygen[i] = data[parser->header->gasmix + i * 2];
}
// Cache the data for later use.
parser->trimix = trimix;
parser->ngasmixes = ngasmixes;
for (unsigned int i = 0; i < ngasmixes; ++i) {
parser->oxygen[i] = oxygen[i];
}
parser->cached = 1;
return DC_STATUS_SUCCESS;
}
dc_status_t
uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned int model, unsigned int devtime, dc_ticks_t systime)
{
@ -321,6 +367,13 @@ uwatec_smart_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i
return DC_STATUS_INVALIDARGS;
}
parser->cached = 0;
parser->trimix = 0;
parser->ngasmixes = 0;
for (unsigned int i = 0; i < NGASMIXES; ++i) {
parser->oxygen[i] = 0;
}
*out = (dc_parser_t*) parser;
return DC_STATUS_SUCCESS;
@ -340,6 +393,16 @@ uwatec_smart_parser_destroy (dc_parser_t *abstract)
static dc_status_t
uwatec_smart_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
{
uwatec_smart_parser_t *parser = (uwatec_smart_parser_t *) abstract;
// Reset the cache.
parser->cached = 0;
parser->trimix = 0;
parser->ngasmixes = 0;
for (unsigned int i = 0; i < NGASMIXES; ++i) {
parser->oxygen[i] = 0;
}
return DC_STATUS_SUCCESS;
}
@ -369,24 +432,12 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
uwatec_smart_parser_t *parser = (uwatec_smart_parser_t *) abstract;
const unsigned char *data = abstract->data;
unsigned int size = abstract->size;
const uwatec_smart_header_info_t *table = parser->header;
unsigned int header = parser->headersize;
unsigned int trimix = 0;
if (parser->model == GALILEO || parser->model == GALILEOTRIMIX) {
if (size < 44)
return DC_STATUS_DATAFORMAT;
if (data[43] & 0x80) {
header = 0xB1;
trimix = 1;
}
}
if (size < header)
return DC_STATUS_DATAFORMAT;
// Cache the parser data.
dc_status_t rc = uwatec_smart_parser_cache (parser);
if (rc != DC_STATUS_SUCCESS)
return rc;
dc_gasmix_t *gasmix = (dc_gasmix_t *) value;
@ -399,15 +450,15 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
*((double *) value) = array_uint16_le (data + table->maxdepth) / 100.0;
break;
case DC_FIELD_GASMIX_COUNT:
if (trimix)
if (parser->trimix)
return DC_STATUS_UNSUPPORTED;
*((unsigned int *) value) = table->ngases;
*((unsigned int *) value) = parser->ngasmixes;
break;
case DC_FIELD_GASMIX:
if (trimix)
if (parser->trimix)
return DC_STATUS_UNSUPPORTED;
gasmix->helium = 0.0;
gasmix->oxygen = data[table->gasmix + flags * 2] / 100.0;
gasmix->oxygen = parser->oxygen[flags] / 100.0;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
break;
case DC_FIELD_TEMPERATURE_MINIMUM:
@ -497,19 +548,16 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
const unsigned char *data = abstract->data;
unsigned int size = abstract->size;
// Cache the parser data.
dc_status_t rc = uwatec_smart_parser_cache (parser);
if (rc != DC_STATUS_SUCCESS)
return rc;
const uwatec_smart_sample_info_t *table = parser->samples;
unsigned int entries = parser->nsamples;
unsigned int header = parser->headersize;
unsigned int trimix = 0;
if (parser->model == GALILEO || parser->model == GALILEOTRIMIX) {
if (size < 44)
return DC_STATUS_DATAFORMAT;
if (data[43] & 0x80) {
header = 0xB1;
trimix = 1;
}
if (parser->trimix) {
header = 0xB1;
}
// Get the maximum number of alarm bytes.
@ -522,13 +570,6 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
}
}
// Get all the gas mixes.
unsigned int oxygen[3] = {0};
unsigned int ngasmix = (trimix ? 0 : parser->header->ngases);
for (unsigned int i = 0; i < ngasmix; ++i) {
oxygen[i] = data[parser->header->gasmix + i * 2];
}
int complete = 0;
int calibrated = 0;
@ -630,7 +671,7 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
break;
case PRESSURE:
if (table[id].absolute) {
if (trimix) {
if (parser->trimix) {
tank = (value & 0xF000) >> 24;
pressure = (value & 0x0FFF) / 4.0;
} else {
@ -705,13 +746,15 @@ uwatec_smart_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
sample.time = time;
if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
if (ngasmix && gasmix != gasmix_previous) {
if (gasmix >= ngasmix)
if (parser->ngasmixes && gasmix != gasmix_previous) {
if (gasmix >= parser->ngasmixes) {
ERROR (abstract->context, "Invalid gas mix index.");
return DC_STATUS_DATAFORMAT;
}
sample.event.type = SAMPLE_EVENT_GASCHANGE;
sample.event.time = 0;
sample.event.flags = 0;
sample.event.value = oxygen[gasmix];
sample.event.value = parser->oxygen[gasmix];
if (callback) callback (DC_SAMPLE_EVENT, sample, userdata);
gasmix_previous = gasmix;
}