Provide for a dive_computer_type variable within dc structure

This patch lays the foundation for differentiating
 between open-circuit(OC)dives and rebreather dives
 (CCR). The following were done:
 1) In dive.h add an enum type dive_computer_type
 2) In dive.h add two more fields to the dc structure:
    a) dctype  (an enum field indicating dc type)
    b) no_o2sensor (indicating number of o2 sensors for this dc)
 3) In parse-xml.c add a function trimspace that strips any
    whitespace from a string. This is used by two functions:
    utf8_string as well as by get_dc_type, described below.
    The pointer to buffer is not changed in order to ensure
    consistency when the buffer is freed.
 4) In parse-xml.c add a function get_dc_type. This parses the
    dc_type string from xml and assigns an enum value which will
    later be returned to the function that parses
    the dc variables.

Signed-off-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Willem Ferguson 2014-06-11 19:48:48 +02:00 committed by Dirk Hohndel
parent 6a9c4097c0
commit a0f5a74847
2 changed files with 73 additions and 43 deletions

6
dive.h
View file

@ -41,6 +41,8 @@ extern "C" {
#include <stdbool.h>
#endif
enum dive_comp_type {OC, CCR}; // Flags (Open-circuit and Closed-circuit-rebreather) for setting dive computer type
struct gasmix {
fraction_t o2;
fraction_t he;
@ -217,7 +219,9 @@ struct divecomputer {
depth_t maxdepth, meandepth;
temperature_t airtemp, watertemp;
pressure_t surface_pressure;
int salinity; // kg per 10000 l
enum dive_comp_type dctype; // dive computer type: OC(default) or CCR
uint8_t no_o2sensors; // rebreathers: number of O2 sensors used
int salinity; // kg per 10000 l
const char *model;
uint32_t deviceid, diveid;
int samples, alloc_samples;

View file

@ -483,23 +483,46 @@ static void cylindersize(char *buffer, volume_t *volume)
}
}
/* Trim a character string by removing leading and trailing white space characters.
* Parameter: a pointer to a null-terminated character string (buffer);
* Return value: length of the trimmed string, excluding the terminal 0x0 byte
* The original pointer (buffer) remains valid after this function has been called
* and points to the trimmed string */
int trimspace(char *buffer) {
int i, size, start, end;
size = strlen(buffer);
for(start = 0; isspace(buffer[start]); start++)
if (start >= size) return 0; // Find 1st character following leading whitespace
for(end = size - 1; isspace(buffer[end]); end--) // Find last character before trailing whitespace
if (end <= 0) return 0;
for(i = start; i <= end; i++) // Move the nonspace characters to the start of the string
buffer[i-start] = buffer[i];
size = end - start + 1;
buffer[size] = 0x0; // then terminate the string
return size; // return string length
}
static void utf8_string(char *buffer, void *_res)
{
int size;
char *res;
while (isspace(*buffer))
buffer++;
size = strlen(buffer);
while (size && isspace(buffer[size - 1]))
size--;
if (!size)
return;
res = malloc(size + 1);
memcpy(res, buffer, size);
res[size] = 0;
*(char **)_res = res;
int size;
size = trimspace(buffer);
if(size) {
res = malloc(size + 1);
memcpy(res, buffer, size);
res[size] = 0;
*(char **)_res = res;
}
}
/* Extract the dive computer type from the xml text buffer */
static void get_dc_type(char *buffer, enum dive_comp_type *i)
{
if((trimspace(buffer)) && (strcmp(buffer,"CCR") == 0))
*i = CCR; // if the xml string = "CCR", set dc-type to CCR
} // otherwise the default dc-type is used (OC)
#define MATCH(pattern, fn, dest) ({ \
/* Silly type compatibility test */ \
if (0) (fn)("test", dest); \
@ -668,6 +691,35 @@ static void try_to_match_autogroup(const char *name, char *buf)
nonmatch("autogroup", name, buf);
}
void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx)
{
/* The gas switch event format is insane. It will be fixed, I think */
int o2 = get_o2(&dive->cylinder[idx].gasmix);
int he = get_he(&dive->cylinder[idx].gasmix);
int value;
o2 = (o2 + 5) / 10;
he = (he + 5) / 10;
value = o2 + (he << 16);
add_event(dc, seconds, 25, 0, value, "gaschange"); /* SAMPLE_EVENT_GASCHANGE2 */
}
static void get_cylinderindex(char *buffer, uint8_t *i)
{
*i = atoi(buffer);
if (lastcylinderindex != *i) {
add_gas_switch_event(cur_dive, get_dc(), cur_sample->time.seconds, *i);
lastcylinderindex = *i;
}
}
static void get_sensor(char *buffer, uint8_t *i)
{
*i = atoi(buffer);
lastsensor = *i;
}
static void try_to_fill_dc_settings(const char *name, char *buf)
{
start_match("divecomputerid", name, buf);
@ -752,42 +804,16 @@ static void try_to_fill_dc(struct divecomputer *dc, const char *name, char *buf)
return;
if (MATCH("diveid", hex_value, &dc->diveid))
return;
if (MATCH("dctype", get_dc_type, &dc->dctype))
return;
if (MATCH("no_o2sensors", get_sensor, &dc->no_o2sensors))
return;
if (match_dc_data_fields(dc, name, buf))
return;
nonmatch("divecomputer", name, buf);
}
void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx)
{
/* The gas switch event format is insane. It will be fixed, I think */
int o2 = get_o2(&dive->cylinder[idx].gasmix);
int he = get_he(&dive->cylinder[idx].gasmix);
int value;
o2 = (o2 + 5) / 10;
he = (he + 5) / 10;
value = o2 + (he << 16);
add_event(dc, seconds, 25, 0, value, "gaschange"); /* SAMPLE_EVENT_GASCHANGE2 */
}
static void get_cylinderindex(char *buffer, uint8_t *i)
{
*i = atoi(buffer);
if (lastcylinderindex != *i) {
add_gas_switch_event(cur_dive, get_dc(), cur_sample->time.seconds, *i);
lastcylinderindex = *i;
}
}
static void get_sensor(char *buffer, uint8_t *i)
{
*i = atoi(buffer);
lastsensor = *i;
}
/* We're in samples - try to convert the random xml value to something useful */
static void try_to_fill_sample(struct sample *sample, const char *name, char *buf)
{