Implement the new field api for the Oceanic devices.

This commit is contained in:
Jef Driesen 2010-11-16 21:56:18 +01:00
parent 643c04eca3
commit 061e647ecf
5 changed files with 260 additions and 3 deletions

View File

@ -46,10 +46,15 @@ typedef struct oceanic_atom2_parser_t oceanic_atom2_parser_t;
struct oceanic_atom2_parser_t {
parser_t base;
unsigned int model;
// Cached fields.
unsigned int cached;
unsigned int divetime;
double maxdepth;
};
static parser_status_t oceanic_atom2_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size);
static parser_status_t oceanic_atom2_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime);
static parser_status_t oceanic_atom2_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value);
static parser_status_t oceanic_atom2_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata);
static parser_status_t oceanic_atom2_parser_destroy (parser_t *abstract);
@ -57,7 +62,7 @@ static const parser_backend_t oceanic_atom2_parser_backend = {
PARSER_TYPE_OCEANIC_ATOM2,
oceanic_atom2_parser_set_data, /* set_data */
oceanic_atom2_parser_get_datetime, /* datetime */
NULL, /* fields */
oceanic_atom2_parser_get_field, /* fields */
oceanic_atom2_parser_samples_foreach, /* samples_foreach */
oceanic_atom2_parser_destroy /* destroy */
};
@ -91,6 +96,9 @@ oceanic_atom2_parser_create (parser_t **out, unsigned int model)
// Set the default values.
parser->model = model;
parser->cached = 0;
parser->divetime = 0;
parser->maxdepth = 0.0;
*out = (parser_t*) parser;
@ -114,9 +122,16 @@ oceanic_atom2_parser_destroy (parser_t *abstract)
static parser_status_t
oceanic_atom2_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size)
{
oceanic_atom2_parser_t *parser = (oceanic_atom2_parser_t *) abstract;
if (! parser_is_oceanic_atom2 (abstract))
return PARSER_STATUS_TYPE_MISMATCH;
// Reset the cache.
parser->cached = 0;
parser->divetime = 0;
parser->maxdepth = 0.0;
return PARSER_STATUS_SUCCESS;
}
@ -208,6 +223,76 @@ oceanic_atom2_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime)
}
static parser_status_t
oceanic_atom2_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value)
{
oceanic_atom2_parser_t *parser = (oceanic_atom2_parser_t *) abstract;
const unsigned char *data = abstract->data;
unsigned int size = abstract->size;
unsigned int length = 11 * PAGESIZE / 2;
unsigned int header = 4 * PAGESIZE;
unsigned int footer = size - PAGESIZE;
if (parser->model == GEO || parser->model == DATAMASK ||
parser->model == GEO20 || parser->model == VEO20 ||
parser->model == VEO30)
{
length -= PAGESIZE;
header -= PAGESIZE;
}
if (size < length)
return PARSER_STATUS_ERROR;
if (!parser->cached) {
sample_statistics_t statistics = SAMPLE_STATISTICS_INITIALIZER;
parser_status_t rc = oceanic_atom2_parser_samples_foreach (
abstract, sample_statistics_cb, &statistics);
if (rc != PARSER_STATUS_SUCCESS)
return rc;
parser->cached = 1;
parser->divetime = statistics.divetime;
parser->maxdepth = statistics.maxdepth;
}
gasmix_t *gasmix = (gasmix_t *) value;
unsigned int nitrox = 0;
if (value) {
switch (type) {
case FIELD_TYPE_DIVETIME:
*((unsigned int *) value) = parser->divetime;
break;
case FIELD_TYPE_MAXDEPTH:
*((double *) value) = array_uint16_le (data + footer + 4) / 16.0 * FEET;
break;
case FIELD_TYPE_GASMIX_COUNT:
if (parser->model == DATAMASK)
*((unsigned int *) value) = 1;
else
*((unsigned int *) value) = 3;
break;
case FIELD_TYPE_GASMIX:
if (parser->model == DATAMASK)
nitrox = data[header + 3];
else
nitrox = data[header + 4 + flags];
gasmix->helium = 0.0;
gasmix->oxygen = (nitrox ? nitrox / 100.0 : 0.21);
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
break;
default:
return PARSER_STATUS_UNSUPPORTED;
}
}
return PARSER_STATUS_SUCCESS;
}
static parser_status_t
oceanic_atom2_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata)
{

View File

@ -33,10 +33,15 @@ typedef struct oceanic_veo250_parser_t oceanic_veo250_parser_t;
struct oceanic_veo250_parser_t {
parser_t base;
unsigned int model;
// Cached fields.
unsigned int cached;
unsigned int divetime;
double maxdepth;
};
static parser_status_t oceanic_veo250_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size);
static parser_status_t oceanic_veo250_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime);
static parser_status_t oceanic_veo250_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value);
static parser_status_t oceanic_veo250_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata);
static parser_status_t oceanic_veo250_parser_destroy (parser_t *abstract);
@ -44,7 +49,7 @@ static const parser_backend_t oceanic_veo250_parser_backend = {
PARSER_TYPE_OCEANIC_VEO250,
oceanic_veo250_parser_set_data, /* set_data */
oceanic_veo250_parser_get_datetime, /* datetime */
NULL, /* fields */
oceanic_veo250_parser_get_field, /* fields */
oceanic_veo250_parser_samples_foreach, /* samples_foreach */
oceanic_veo250_parser_destroy /* destroy */
};
@ -78,6 +83,9 @@ oceanic_veo250_parser_create (parser_t **out, unsigned int model)
// Set the default values.
parser->model = model;
parser->cached = 0;
parser->divetime = 0;
parser->maxdepth = 0.0;
*out = (parser_t*) parser;
@ -101,9 +109,16 @@ oceanic_veo250_parser_destroy (parser_t *abstract)
static parser_status_t
oceanic_veo250_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size)
{
oceanic_veo250_parser_t *parser = (oceanic_veo250_parser_t *) abstract;
if (! parser_is_oceanic_veo250 (abstract))
return PARSER_STATUS_TYPE_MISMATCH;
// Reset the cache.
parser->cached = 0;
parser->divetime = 0;
parser->maxdepth = 0.0;
return PARSER_STATUS_SUCCESS;
}
@ -133,6 +148,62 @@ oceanic_veo250_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime)
return PARSER_STATUS_SUCCESS;
}
static parser_status_t
oceanic_veo250_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value)
{
oceanic_veo250_parser_t *parser = (oceanic_veo250_parser_t *) abstract;
const unsigned char *data = abstract->data;
unsigned int size = abstract->size;
if (size < 7 * PAGESIZE / 2)
return PARSER_STATUS_ERROR;
if (!parser->cached) {
sample_statistics_t statistics = SAMPLE_STATISTICS_INITIALIZER;
parser_status_t rc = oceanic_veo250_parser_samples_foreach (
abstract, sample_statistics_cb, &statistics);
if (rc != PARSER_STATUS_SUCCESS)
return rc;
parser->cached = 1;
parser->divetime = statistics.divetime;
parser->maxdepth = statistics.maxdepth;
}
unsigned int footer = size - PAGESIZE;
gasmix_t *gasmix = (gasmix_t *) value;
if (value) {
switch (type) {
case FIELD_TYPE_DIVETIME:
*((unsigned int *) value) = data[footer + 3] * 60;
break;
case FIELD_TYPE_MAXDEPTH:
*((double *) value) = parser->maxdepth;
break;
case FIELD_TYPE_GASMIX_COUNT:
*((unsigned int *) value) = 1;
break;
case FIELD_TYPE_GASMIX:
gasmix->helium = 0.0;
if (data[footer + 6])
gasmix->oxygen = data[footer + 6] / 100.0;
else
gasmix->oxygen = 0.21;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
break;
default:
return PARSER_STATUS_UNSUPPORTED;
}
}
return PARSER_STATUS_SUCCESS;
}
static parser_status_t
oceanic_veo250_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata)
{

View File

@ -32,10 +32,15 @@ typedef struct oceanic_vtpro_parser_t oceanic_vtpro_parser_t;
struct oceanic_vtpro_parser_t {
parser_t base;
// Cached fields.
unsigned int cached;
unsigned int divetime;
double maxdepth;
};
static parser_status_t oceanic_vtpro_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size);
static parser_status_t oceanic_vtpro_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime);
static parser_status_t oceanic_vtpro_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value);
static parser_status_t oceanic_vtpro_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata);
static parser_status_t oceanic_vtpro_parser_destroy (parser_t *abstract);
@ -43,7 +48,7 @@ static const parser_backend_t oceanic_vtpro_parser_backend = {
PARSER_TYPE_OCEANIC_VTPRO,
oceanic_vtpro_parser_set_data, /* set_data */
oceanic_vtpro_parser_get_datetime, /* datetime */
NULL, /* fields */
oceanic_vtpro_parser_get_field, /* fields */
oceanic_vtpro_parser_samples_foreach, /* samples_foreach */
oceanic_vtpro_parser_destroy /* destroy */
};
@ -75,6 +80,11 @@ oceanic_vtpro_parser_create (parser_t **out)
// Initialize the base class.
parser_init (&parser->base, &oceanic_vtpro_parser_backend);
// Set the default values.
parser->cached = 0;
parser->divetime = 0;
parser->maxdepth = 0.0;
*out = (parser_t*) parser;
return PARSER_STATUS_SUCCESS;
@ -97,9 +107,16 @@ oceanic_vtpro_parser_destroy (parser_t *abstract)
static parser_status_t
oceanic_vtpro_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned int size)
{
oceanic_vtpro_parser_t *parser = (oceanic_vtpro_parser_t *) abstract;
if (! parser_is_oceanic_vtpro (abstract))
return PARSER_STATUS_TYPE_MISMATCH;
// Reset the cache.
parser->cached = 0;
parser->divetime = 0;
parser->maxdepth = 0.0;
return PARSER_STATUS_SUCCESS;
}
@ -135,6 +152,61 @@ oceanic_vtpro_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime)
}
static parser_status_t
oceanic_vtpro_parser_get_field (parser_t *abstract, parser_field_type_t type, unsigned int flags, void *value)
{
oceanic_vtpro_parser_t *parser = (oceanic_vtpro_parser_t *) abstract;
const unsigned char *data = abstract->data;
unsigned int size = abstract->size;
if (size < 7 * PAGESIZE / 2)
return PARSER_STATUS_ERROR;
if (!parser->cached) {
sample_statistics_t statistics = SAMPLE_STATISTICS_INITIALIZER;
parser_status_t rc = oceanic_vtpro_parser_samples_foreach (
abstract, sample_statistics_cb, &statistics);
if (rc != PARSER_STATUS_SUCCESS)
return rc;
parser->cached = 1;
parser->divetime = statistics.divetime;
parser->maxdepth = statistics.maxdepth;
}
unsigned int footer = size - PAGESIZE;
gasmix_t *gasmix = (gasmix_t *) value;
if (value) {
switch (type) {
case FIELD_TYPE_DIVETIME:
*((unsigned int *) value) = parser->divetime;
break;
case FIELD_TYPE_MAXDEPTH:
*((double *) value) = (data[footer + 0] + ((data[footer + 1] & 0x0F) << 8)) * 1;
break;
case FIELD_TYPE_GASMIX_COUNT:
*((unsigned int *) value) = 1;
break;
case FIELD_TYPE_GASMIX:
gasmix->helium = 0.0;
if (data[footer + 3])
gasmix->oxygen = data[footer + 3] / 100.0;
else
gasmix->oxygen = 0.21;
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
break;
default:
return PARSER_STATUS_UNSUPPORTED;
}
}
return PARSER_STATUS_SUCCESS;
}
static parser_status_t
oceanic_vtpro_parser_samples_foreach (parser_t *abstract, sample_callback_t callback, void *userdata)
{

View File

@ -56,6 +56,16 @@ struct parser_backend_t {
void
parser_init (parser_t *parser, const parser_backend_t *backend);
typedef struct sample_statistics_t {
unsigned int divetime;
double maxdepth;
} sample_statistics_t;
#define SAMPLE_STATISTICS_INITIALIZER {0, 0.0}
void
sample_statistics_cb (parser_sample_type_t type, parser_sample_value_t value, void *userdata);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -108,3 +108,22 @@ parser_destroy (parser_t *parser)
return parser->backend->destroy (parser);
}
void
sample_statistics_cb (parser_sample_type_t type, parser_sample_value_t value, void *userdata)
{
sample_statistics_t *statistics = (sample_statistics_t *) userdata;
switch (type) {
case SAMPLE_TYPE_TIME:
statistics->divetime = value.time;
break;
case SAMPLE_TYPE_DEPTH:
if (statistics->maxdepth < value.depth)
statistics->maxdepth = value.depth;
break;
default:
break;
}
}