core: use std::vector<> to store divecomputer samples

This is a hairy one, because the sample code is rather tricky.

There was a pattern of looping through pairs of adjacent samples,
for interpolation purposes. Add an range adapter to generalize
such loops.

Removes the finish_sample() function: The code would call
prepare_sample() to start parsing of samples and then
finish_sample() to actuall add it. I.e. a kind of commit().

Since, with one exception, all users of prepare_sample()
called finish_sample() in all code paths, we might just add
the sample in the first place. The exception was sample_end()
in parse.cpp. This brings a small change: samples are now
added, even if they could only be parsed partially. I doubt
that this makes any difference, since it will only happen
for broken divelogs anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-19 12:38:38 +02:00 committed by bstoeger
parent bc761344d4
commit f120fecccb
28 changed files with 588 additions and 715 deletions

View file

@ -232,15 +232,15 @@ static void show_index(struct membuffer *b, int value, const char *pre, const ch
show_integer(b, value, pre, post);
}
static void save_sample(struct membuffer *b, struct sample *sample, struct sample *old, int o2sensor)
static void save_sample(struct membuffer *b, const struct sample &sample, struct sample &old, int o2sensor)
{
int idx;
put_format(b, " <sample time='%u:%02u min'", FRACTION_TUPLE(sample->time.seconds, 60));
put_milli(b, " depth='", sample->depth.mm, " m'");
if (sample->temperature.mkelvin && sample->temperature.mkelvin != old->temperature.mkelvin) {
put_temperature(b, sample->temperature, " temp='", " C'");
old->temperature = sample->temperature;
put_format(b, " <sample time='%u:%02u min'", FRACTION_TUPLE(sample.time.seconds, 60));
put_milli(b, " depth='", sample.depth.mm, " m'");
if (sample.temperature.mkelvin && sample.temperature.mkelvin != old.temperature.mkelvin) {
put_temperature(b, sample.temperature, " temp='", " C'");
old.temperature = sample.temperature;
}
/*
@ -248,8 +248,8 @@ static void save_sample(struct membuffer *b, struct sample *sample, struct sampl
* changed from the previous sensor we showed.
*/
for (idx = 0; idx < MAX_SENSORS; idx++) {
pressure_t p = sample->pressure[idx];
int sensor = sample->sensor[idx];
pressure_t p = sample.pressure[idx];
int sensor = sample.sensor[idx];
if (sensor == NO_SENSOR)
continue;
@ -264,9 +264,9 @@ static void save_sample(struct membuffer *b, struct sample *sample, struct sampl
continue;
}
put_pressure(b, p, " pressure='", " bar'");
if (sensor != old->sensor[0]) {
if (sensor != old.sensor[0]) {
put_format(b, " sensor='%d'", sensor);
old->sensor[0] = sensor;
old.sensor[0] = sensor;
}
continue;
}
@ -277,78 +277,78 @@ static void save_sample(struct membuffer *b, struct sample *sample, struct sampl
}
/* the deco/ndl values are stored whenever they change */
if (sample->ndl.seconds != old->ndl.seconds) {
put_format(b, " ndl='%u:%02u min'", FRACTION_TUPLE(sample->ndl.seconds, 60));
old->ndl = sample->ndl;
if (sample.ndl.seconds != old.ndl.seconds) {
put_format(b, " ndl='%u:%02u min'", FRACTION_TUPLE(sample.ndl.seconds, 60));
old.ndl = sample.ndl;
}
if (sample->tts.seconds != old->tts.seconds) {
put_format(b, " tts='%u:%02u min'", FRACTION_TUPLE(sample->tts.seconds, 60));
old->tts = sample->tts;
if (sample.tts.seconds != old.tts.seconds) {
put_format(b, " tts='%u:%02u min'", FRACTION_TUPLE(sample.tts.seconds, 60));
old.tts = sample.tts;
}
if (sample->rbt.seconds != old->rbt.seconds) {
put_format(b, " rbt='%u:%02u min'", FRACTION_TUPLE(sample->rbt.seconds, 60));
old->rbt = sample->rbt;
if (sample.rbt.seconds != old.rbt.seconds) {
put_format(b, " rbt='%u:%02u min'", FRACTION_TUPLE(sample.rbt.seconds, 60));
old.rbt = sample.rbt;
}
if (sample->in_deco != old->in_deco) {
put_format(b, " in_deco='%d'", sample->in_deco ? 1 : 0);
old->in_deco = sample->in_deco;
if (sample.in_deco != old.in_deco) {
put_format(b, " in_deco='%d'", sample.in_deco ? 1 : 0);
old.in_deco = sample.in_deco;
}
if (sample->stoptime.seconds != old->stoptime.seconds) {
put_format(b, " stoptime='%u:%02u min'", FRACTION_TUPLE(sample->stoptime.seconds, 60));
old->stoptime = sample->stoptime;
if (sample.stoptime.seconds != old.stoptime.seconds) {
put_format(b, " stoptime='%u:%02u min'", FRACTION_TUPLE(sample.stoptime.seconds, 60));
old.stoptime = sample.stoptime;
}
if (sample->stopdepth.mm != old->stopdepth.mm) {
put_milli(b, " stopdepth='", sample->stopdepth.mm, " m'");
old->stopdepth = sample->stopdepth;
if (sample.stopdepth.mm != old.stopdepth.mm) {
put_milli(b, " stopdepth='", sample.stopdepth.mm, " m'");
old.stopdepth = sample.stopdepth;
}
if (sample->cns != old->cns) {
put_format(b, " cns='%u%%'", sample->cns);
old->cns = sample->cns;
if (sample.cns != old.cns) {
put_format(b, " cns='%u%%'", sample.cns);
old.cns = sample.cns;
}
if ((sample->o2sensor[0].mbar) && (sample->o2sensor[0].mbar != old->o2sensor[0].mbar)) {
put_milli(b, " sensor1='", sample->o2sensor[0].mbar, " bar'");
old->o2sensor[0] = sample->o2sensor[0];
if ((sample.o2sensor[0].mbar) && (sample.o2sensor[0].mbar != old.o2sensor[0].mbar)) {
put_milli(b, " sensor1='", sample.o2sensor[0].mbar, " bar'");
old.o2sensor[0] = sample.o2sensor[0];
}
if ((sample->o2sensor[1].mbar) && (sample->o2sensor[1].mbar != old->o2sensor[1].mbar)) {
put_milli(b, " sensor2='", sample->o2sensor[1].mbar, " bar'");
old->o2sensor[1] = sample->o2sensor[1];
if ((sample.o2sensor[1].mbar) && (sample.o2sensor[1].mbar != old.o2sensor[1].mbar)) {
put_milli(b, " sensor2='", sample.o2sensor[1].mbar, " bar'");
old.o2sensor[1] = sample.o2sensor[1];
}
if ((sample->o2sensor[2].mbar) && (sample->o2sensor[2].mbar != old->o2sensor[2].mbar)) {
put_milli(b, " sensor3='", sample->o2sensor[2].mbar, " bar'");
old->o2sensor[2] = sample->o2sensor[2];
if ((sample.o2sensor[2].mbar) && (sample.o2sensor[2].mbar != old.o2sensor[2].mbar)) {
put_milli(b, " sensor3='", sample.o2sensor[2].mbar, " bar'");
old.o2sensor[2] = sample.o2sensor[2];
}
if ((sample->o2sensor[3].mbar) && (sample->o2sensor[3].mbar != old->o2sensor[3].mbar)) {
put_milli(b, " sensor4='", sample->o2sensor[3].mbar, " bar'");
old->o2sensor[3] = sample->o2sensor[3];
if ((sample.o2sensor[3].mbar) && (sample.o2sensor[3].mbar != old.o2sensor[3].mbar)) {
put_milli(b, " sensor4='", sample.o2sensor[3].mbar, " bar'");
old.o2sensor[3] = sample.o2sensor[3];
}
if ((sample->o2sensor[4].mbar) && (sample->o2sensor[4].mbar != old->o2sensor[4].mbar)) {
put_milli(b, " sensor5='", sample->o2sensor[4].mbar, " bar'");
old->o2sensor[4] = sample->o2sensor[4];
if ((sample.o2sensor[4].mbar) && (sample.o2sensor[4].mbar != old.o2sensor[4].mbar)) {
put_milli(b, " sensor5='", sample.o2sensor[4].mbar, " bar'");
old.o2sensor[4] = sample.o2sensor[4];
}
if ((sample->o2sensor[5].mbar) && (sample->o2sensor[5].mbar != old->o2sensor[5].mbar)) {
put_milli(b, " sensor6='", sample->o2sensor[5].mbar, " bar'");
old->o2sensor[5] = sample->o2sensor[5];
if ((sample.o2sensor[5].mbar) && (sample.o2sensor[5].mbar != old.o2sensor[5].mbar)) {
put_milli(b, " sensor6='", sample.o2sensor[5].mbar, " bar'");
old.o2sensor[5] = sample.o2sensor[5];
}
if (sample->setpoint.mbar != old->setpoint.mbar) {
put_milli(b, " po2='", sample->setpoint.mbar, " bar'");
old->setpoint = sample->setpoint;
if (sample.setpoint.mbar != old.setpoint.mbar) {
put_milli(b, " po2='", sample.setpoint.mbar, " bar'");
old.setpoint = sample.setpoint;
}
if (sample->heartbeat != old->heartbeat) {
show_index(b, sample->heartbeat, "heartbeat='", "'");
old->heartbeat = sample->heartbeat;
if (sample.heartbeat != old.heartbeat) {
show_index(b, sample.heartbeat, "heartbeat='", "'");
old.heartbeat = sample.heartbeat;
}
if (sample->bearing.degrees != old->bearing.degrees) {
show_index(b, sample->bearing.degrees, "bearing='", "'");
old->bearing.degrees = sample->bearing.degrees;
if (sample.bearing.degrees != old.bearing.degrees) {
show_index(b, sample.bearing.degrees, "bearing='", "'");
old.bearing.degrees = sample.bearing.degrees;
}
put_format(b, " />\n");
}
@ -423,9 +423,7 @@ static void show_date(struct membuffer *b, timestamp_t when)
static void save_samples(struct membuffer *b, struct dive *dive, struct divecomputer *dc)
{
int nr;
int o2sensor;
struct sample *s;
struct sample dummy;
/* Set up default pressure sensor indices */
@ -435,12 +433,8 @@ static void save_samples(struct membuffer *b, struct dive *dive, struct divecomp
dummy.sensor[1] = o2sensor;
}
s = dc->sample;
nr = dc->samples;
while (--nr >= 0) {
save_sample(b, s, &dummy, o2sensor);
s++;
}
for (const auto &s: dc->samples)
save_sample(b, s, dummy, o2sensor);
}
static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer *dc)