Remove disabled gas mixes
Returning disabled gas mixes to the application mainly results in lots of unnecessary information. Therefore, remove all disabled gas mixes, unless they are actively used. Many other dive computers do not even include disabled gas mixes in the data. The removal of the disabled gas mixes requires a two pass approach for parsing the profile data. The first pass is only used to discover which gas mixes are actively used during the dive. Next, all disabled and not actively used gas mixes are removed from the list. Since removing one or more gas mixes also invalidates the index of the remaining gas mixes, the profile needs to be parsed again to report the new index in the gas switch samples. The original one based index is used as the stable gas mix id, used for looking up the new gas mix index.
This commit is contained in:
parent
993283d1c8
commit
5d36cc0798
@ -124,6 +124,7 @@ typedef struct hw_ostc_parser_t {
|
||||
const hw_ostc_layout_t *layout;
|
||||
unsigned int ngasmixes;
|
||||
unsigned int nfixed;
|
||||
unsigned int ndisabled;
|
||||
unsigned int initial;
|
||||
unsigned int initial_setpoint;
|
||||
unsigned int initial_cns;
|
||||
@ -134,6 +135,8 @@ static dc_status_t hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_dateti
|
||||
static dc_status_t hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value);
|
||||
static dc_status_t hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata);
|
||||
|
||||
static dc_status_t hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t callback, void *userdata);
|
||||
|
||||
static const dc_parser_vtable_t hw_ostc_parser_vtable = {
|
||||
sizeof(hw_ostc_parser_t),
|
||||
DC_FAMILY_HW_OSTC,
|
||||
@ -194,7 +197,7 @@ static const hw_ostc_layout_t hw_ostc_layout_ostc3 = {
|
||||
static unsigned int
|
||||
hw_ostc_find_gasmix_manual (hw_ostc_parser_t *parser, unsigned int o2, unsigned int he, unsigned int dil)
|
||||
{
|
||||
unsigned int offset = parser->nfixed;
|
||||
unsigned int offset = parser->nfixed - parser->ndisabled;
|
||||
unsigned int count = parser->ngasmixes;
|
||||
|
||||
unsigned int i = offset;
|
||||
@ -207,6 +210,22 @@ hw_ostc_find_gasmix_manual (hw_ostc_parser_t *parser, unsigned int o2, unsigned
|
||||
return i;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hw_ostc_find_gasmix_fixed (hw_ostc_parser_t *parser, unsigned int id)
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
unsigned int count = parser->nfixed - parser->ndisabled;
|
||||
|
||||
unsigned int i = offset;
|
||||
while (i < count) {
|
||||
if (id == parser->gasmix[i].id)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hw_ostc_is_ccr (unsigned int divemode, unsigned int version)
|
||||
{
|
||||
@ -341,7 +360,6 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
|
||||
ERROR(abstract->context, "Invalid initial gas mix.");
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
initial--; /* Convert to a zero based index. */
|
||||
} else {
|
||||
WARNING(abstract->context, "No initial gas mix available.");
|
||||
}
|
||||
@ -352,6 +370,7 @@ hw_ostc_parser_cache (hw_ostc_parser_t *parser)
|
||||
parser->layout = layout;
|
||||
parser->ngasmixes = ngasmixes;
|
||||
parser->nfixed = ngasmixes;
|
||||
parser->ndisabled = 0;
|
||||
parser->initial = initial;
|
||||
parser->initial_setpoint = initial_setpoint;
|
||||
parser->initial_cns = initial_cns;
|
||||
@ -387,6 +406,7 @@ hw_ostc_parser_create_internal (dc_parser_t **out, dc_context_t *context, const
|
||||
parser->layout = NULL;
|
||||
parser->ngasmixes = 0;
|
||||
parser->nfixed = 0;
|
||||
parser->ndisabled = 0;
|
||||
parser->initial = 0;
|
||||
parser->initial_setpoint = 0;
|
||||
parser->initial_cns = 0;
|
||||
@ -491,7 +511,7 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
|
||||
|
||||
// Cache the profile data.
|
||||
if (parser->cached < PROFILE) {
|
||||
rc = hw_ostc_parser_samples_foreach (abstract, NULL, NULL);
|
||||
rc = hw_ostc_parser_internal_foreach (parser, NULL, NULL);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
}
|
||||
@ -679,17 +699,12 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
|
||||
|
||||
|
||||
static dc_status_t
|
||||
hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
|
||||
hw_ostc_parser_internal_foreach (hw_ostc_parser_t *parser, dc_sample_callback_t callback, void *userdata)
|
||||
{
|
||||
hw_ostc_parser_t *parser = (hw_ostc_parser_t *) abstract;
|
||||
dc_parser_t *abstract = (dc_parser_t *) parser;
|
||||
const unsigned char *data = abstract->data;
|
||||
unsigned int size = abstract->size;
|
||||
|
||||
// Cache the parser data.
|
||||
dc_status_t rc = hw_ostc_parser_cache (parser);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
|
||||
unsigned int version = parser->version;
|
||||
unsigned int header = parser->header;
|
||||
const hw_ostc_layout_t *layout = parser->layout;
|
||||
@ -795,7 +810,7 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
||||
|
||||
unsigned int time = 0;
|
||||
unsigned int nsamples = 0;
|
||||
unsigned int tank = parser->initial != UNDEFINED ? parser->initial : 0;
|
||||
unsigned int tank = parser->initial != UNDEFINED ? parser->initial - 1 : 0;
|
||||
|
||||
unsigned int offset = header;
|
||||
if (version == 0x23 || version == 0x24)
|
||||
@ -812,8 +827,9 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
||||
|
||||
// Initial gas mix.
|
||||
if (time == samplerate && parser->initial != UNDEFINED) {
|
||||
parser->gasmix[parser->initial].active = 1;
|
||||
sample.gasmix = parser->initial;
|
||||
unsigned int idx = hw_ostc_find_gasmix_fixed (parser, parser->initial);
|
||||
parser->gasmix[idx].active = 1;
|
||||
sample.gasmix = idx;
|
||||
if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
|
||||
}
|
||||
|
||||
@ -929,20 +945,20 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
||||
ERROR (abstract->context, "Buffer overflow detected!");
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
unsigned int idx = data[offset];
|
||||
if (parser->model == OSTC4 && ccr && idx > parser->nfixed) {
|
||||
unsigned int id = data[offset];
|
||||
if (parser->model == OSTC4 && ccr && id > parser->nfixed) {
|
||||
// Fix the OSTC4 diluent index.
|
||||
idx -= parser->nfixed;
|
||||
id -= parser->nfixed;
|
||||
}
|
||||
if (idx < 1 || idx > parser->nfixed) {
|
||||
ERROR(abstract->context, "Invalid gas mix (%u).", idx);
|
||||
if (id < 1 || id > parser->nfixed) {
|
||||
ERROR(abstract->context, "Invalid gas mix (%u).", id);
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
idx--; /* Convert to a zero based index. */
|
||||
unsigned int idx = hw_ostc_find_gasmix_fixed (parser, id);
|
||||
parser->gasmix[idx].active = 1;
|
||||
sample.gasmix = idx;
|
||||
if (callback) callback (DC_SAMPLE_GASMIX, &sample, userdata);
|
||||
tank = idx;
|
||||
tank = id - 1;
|
||||
offset++;
|
||||
length--;
|
||||
}
|
||||
@ -1141,7 +1157,50 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call
|
||||
return DC_STATUS_DATAFORMAT;
|
||||
}
|
||||
|
||||
// Remove the disabled gas mixes from the fixed gas mixes.
|
||||
unsigned int ndisabled = 0, nenabled = 0;
|
||||
unsigned int count = parser->nfixed - parser->ndisabled;
|
||||
for (unsigned int i = 0; i < count; ++i) {
|
||||
if (parser->gasmix[i].enabled || parser->gasmix[i].active) {
|
||||
// Move the fixed gas mix.
|
||||
parser->gasmix[nenabled] = parser->gasmix[i];
|
||||
nenabled++;
|
||||
} else {
|
||||
ndisabled++;
|
||||
}
|
||||
}
|
||||
|
||||
// Move all the manual gas mixes.
|
||||
memmove (parser->gasmix + nenabled, parser->gasmix + count,
|
||||
(parser->ngasmixes - count) * sizeof (hw_ostc_gasmix_t));
|
||||
memset (parser->gasmix + parser->ngasmixes - ndisabled, 0,
|
||||
ndisabled * sizeof (hw_ostc_gasmix_t));
|
||||
|
||||
// Adjust the counts.
|
||||
parser->ngasmixes -= ndisabled;
|
||||
parser->ndisabled += ndisabled;
|
||||
|
||||
parser->cached = PROFILE;
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static dc_status_t
|
||||
hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata)
|
||||
{
|
||||
hw_ostc_parser_t *parser = (hw_ostc_parser_t *) abstract;
|
||||
|
||||
// Cache the header data.
|
||||
dc_status_t rc = hw_ostc_parser_cache (parser);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
|
||||
// Cache the profile data.
|
||||
if (parser->cached < PROFILE) {
|
||||
rc = hw_ostc_parser_internal_foreach (parser, NULL, NULL);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return hw_ostc_parser_internal_foreach (parser, callback, userdata);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user