Cache the parser data internally.
The code to calculate parameters like maximum depth and divetime is duplicated in multiple places. Move this code to a single place, and cache the data in the parser instead.
This commit is contained in:
parent
134da18190
commit
3bf73253bc
@ -56,6 +56,62 @@ static const dc_parser_vtable_t suunto_vyper_parser_vtable = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static dc_status_t
|
||||||
|
suunto_vyper_parser_cache (suunto_vyper_parser_t *parser)
|
||||||
|
{
|
||||||
|
dc_parser_t *abstract = (dc_parser_t *) parser;
|
||||||
|
const unsigned char *data = parser->base.data;
|
||||||
|
unsigned int size = parser->base.size;
|
||||||
|
|
||||||
|
if (parser->cached) {
|
||||||
|
return DC_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 18) {
|
||||||
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the samples.
|
||||||
|
unsigned int interval = data[3];
|
||||||
|
unsigned int nsamples = 0;
|
||||||
|
unsigned int depth = 0, maxdepth = 0;
|
||||||
|
unsigned int offset = 14;
|
||||||
|
while (offset < size && data[offset] != 0x80) {
|
||||||
|
unsigned char value = data[offset++];
|
||||||
|
if (value < 0x79 || value > 0x87) {
|
||||||
|
// Delta depth.
|
||||||
|
depth += (signed char) value;
|
||||||
|
if (depth > maxdepth)
|
||||||
|
maxdepth = depth;
|
||||||
|
nsamples++;
|
||||||
|
} else if (value == 0x87) {
|
||||||
|
// Gas change event.
|
||||||
|
if (offset + 1 > size) {
|
||||||
|
ERROR (abstract->context, "Buffer overflow detected!");
|
||||||
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the end marker.
|
||||||
|
unsigned int marker = offset;
|
||||||
|
if (marker + 4 >= size || data[marker] != 0x80) {
|
||||||
|
ERROR (abstract->context, "No valid end marker found!");
|
||||||
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache the data for later use.
|
||||||
|
parser->divetime = nsamples * interval;
|
||||||
|
parser->maxdepth = maxdepth;
|
||||||
|
parser->marker = marker;
|
||||||
|
parser->cached = 1;
|
||||||
|
|
||||||
|
return DC_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
dc_status_t
|
dc_status_t
|
||||||
suunto_vyper_parser_create (dc_parser_t **out, dc_context_t *context)
|
suunto_vyper_parser_create (dc_parser_t **out, dc_context_t *context)
|
||||||
{
|
{
|
||||||
@ -138,38 +194,13 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
|||||||
const unsigned char *data = abstract->data;
|
const unsigned char *data = abstract->data;
|
||||||
unsigned int size = abstract->size;
|
unsigned int size = abstract->size;
|
||||||
|
|
||||||
if (size < 18)
|
|
||||||
return DC_STATUS_DATAFORMAT;
|
|
||||||
|
|
||||||
|
|
||||||
if (!parser->cached) {
|
|
||||||
unsigned int interval = data[3];
|
|
||||||
unsigned int nsamples = 0;
|
|
||||||
unsigned int depth = 0, maxdepth = 0;
|
|
||||||
unsigned int offset = 14;
|
|
||||||
while (offset < size && data[offset] != 0x80) {
|
|
||||||
unsigned char value = data[offset++];
|
|
||||||
if (value < 0x79 || value > 0x87) {
|
|
||||||
depth += (signed char) value;
|
|
||||||
if (depth > maxdepth)
|
|
||||||
maxdepth = depth;
|
|
||||||
nsamples++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the offset to the end marker.
|
|
||||||
unsigned int marker = offset;
|
|
||||||
if (marker + 4 >= size || data[marker] != 0x80)
|
|
||||||
return DC_STATUS_DATAFORMAT;
|
|
||||||
|
|
||||||
parser->cached = 1;
|
|
||||||
parser->divetime = nsamples * interval;
|
|
||||||
parser->maxdepth = maxdepth;
|
|
||||||
parser->marker = marker;
|
|
||||||
}
|
|
||||||
|
|
||||||
dc_gasmix_t *gas = (dc_gasmix_t *) value;
|
dc_gasmix_t *gas = (dc_gasmix_t *) value;
|
||||||
|
|
||||||
|
// Cache the data.
|
||||||
|
dc_status_t rc = suunto_vyper_parser_cache (parser);
|
||||||
|
if (rc != DC_STATUS_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DC_FIELD_DIVETIME:
|
case DC_FIELD_DIVETIME:
|
||||||
@ -216,37 +247,18 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
|||||||
static dc_status_t
|
static dc_status_t
|
||||||
suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
|
suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
|
||||||
{
|
{
|
||||||
|
suunto_vyper_parser_t *parser = (suunto_vyper_parser_t *) abstract;
|
||||||
const unsigned char *data = abstract->data;
|
const unsigned char *data = abstract->data;
|
||||||
unsigned int size = abstract->size;
|
unsigned int size = abstract->size;
|
||||||
|
|
||||||
if (size < 18)
|
|
||||||
return DC_STATUS_DATAFORMAT;
|
|
||||||
|
|
||||||
// Find the maximum depth.
|
|
||||||
unsigned int depth = 0, maxdepth = 0;
|
|
||||||
unsigned int offset = 14;
|
|
||||||
while (offset < size && data[offset] != 0x80) {
|
|
||||||
unsigned char value = data[offset++];
|
|
||||||
if (value < 0x79 || value > 0x87) {
|
|
||||||
depth += (signed char) value;
|
|
||||||
if (depth > maxdepth)
|
|
||||||
maxdepth = depth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the offset to the end marker.
|
|
||||||
unsigned int marker = offset;
|
|
||||||
if (marker + 4 >= size || data[marker] != 0x80)
|
|
||||||
return DC_STATUS_DATAFORMAT;
|
|
||||||
|
|
||||||
unsigned int time = 0;
|
|
||||||
unsigned int interval = data[3];
|
|
||||||
unsigned int complete = 1;
|
|
||||||
|
|
||||||
dc_sample_value_t sample = {0};
|
dc_sample_value_t sample = {0};
|
||||||
|
|
||||||
|
// Cache the data.
|
||||||
|
dc_status_t rc = suunto_vyper_parser_cache (parser);
|
||||||
|
if (rc != DC_STATUS_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
|
||||||
// Time
|
// Time
|
||||||
sample.time = time;
|
sample.time = 0;
|
||||||
if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
|
if (callback) callback (DC_SAMPLE_TIME, sample, userdata);
|
||||||
|
|
||||||
// Temperature (°C)
|
// Temperature (°C)
|
||||||
@ -262,8 +274,11 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
|
|||||||
sample.depth = 0;
|
sample.depth = 0;
|
||||||
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
|
if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata);
|
||||||
|
|
||||||
depth = 0;
|
unsigned int depth = 0;
|
||||||
offset = 14;
|
unsigned int time = 0;
|
||||||
|
unsigned int interval = data[3];
|
||||||
|
unsigned int complete = 1;
|
||||||
|
unsigned int offset = 14;
|
||||||
while (offset < size && data[offset] != 0x80) {
|
while (offset < size && data[offset] != 0x80) {
|
||||||
unsigned char value = data[offset++];
|
unsigned char value = data[offset++];
|
||||||
|
|
||||||
@ -280,8 +295,8 @@ suunto_vyper_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t
|
|||||||
depth += (signed char) value;
|
depth += (signed char) value;
|
||||||
|
|
||||||
// Temperature at maximum depth (°C)
|
// Temperature at maximum depth (°C)
|
||||||
if (depth == maxdepth) {
|
if (depth == parser->maxdepth) {
|
||||||
sample.temperature = (signed char) data[marker + 1];
|
sample.temperature = (signed char) data[parser->marker + 1];
|
||||||
if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
|
if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user