]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Start handling dive events
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 23 Sep 2011 01:02:54 +0000 (18:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 23 Sep 2011 01:02:54 +0000 (18:02 -0700)
Parse them, save them, take them from libdivecomputer.

This doesn't merge them or show them in the profile yet, though.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
dive.c
dive.h
libdivecomputer.c
parse-xml.c
save-xml.c

diff --git a/dive.c b/dive.c
index 1de3759d1bd9b76bc481b13e6f98d4d21cb4c906..67a78cc8ad309189dc14419501e1209b1997e637 100644 (file)
--- a/dive.c
+++ b/dive.c
@@ -5,6 +5,29 @@
 
 #include "dive.h"
 
+void add_event(struct dive *dive, int time, int type, int flags, int value, const char *name)
+{
+       struct event *ev, **p;
+       unsigned int size, len = strlen(name);
+
+       size = sizeof(*ev) + len + 1;
+       ev = malloc(size);
+       if (!ev)
+               return;
+       memset(ev, 0, size);
+       memcpy(ev->name, name, len);
+       ev->time.seconds = time;
+       ev->type = type;
+       ev->flags = flags;
+       ev->value = value;
+       ev->next = NULL;
+
+       p = &dive->events;
+       while (*p)
+               p = &(*p)->next;
+       *p = ev;
+}
+
 double get_depth_units(unsigned int mm, int *frac, const char **units)
 {
        int decimals;
diff --git a/dive.h b/dive.h
index e1a5bc007e69fe76d032a2c81ce80dcb80897034..b121892e9296de5e8e2844124123fa0d728db9ea 100644 (file)
--- a/dive.h
+++ b/dive.h
@@ -142,6 +142,21 @@ struct sample {
        int cylinderindex;
 };
 
+/*
+ * Events are currently pretty meaningless. This is
+ * just based on the random data that libdivecomputer
+ * gives us. I'm not sure what a real "architected"
+ * event model would actually look like, but right
+ * now you can associate a list of events with a dive,
+ * and we'll do something about it.
+ */
+struct event {
+       struct event *next;
+       duration_t time;
+       int type, flags, value;
+       char name[];
+};
+
 #define MAX_CYLINDERS (8)
 
 struct dive {
@@ -156,6 +171,7 @@ struct dive {
        depth_t visibility;
        temperature_t airtemp, watertemp;
        cylinder_t cylinder[MAX_CYLINDERS];
+       struct event *events;
        int samples, alloc_samples;
        struct sample sample[];
 };
@@ -227,6 +243,8 @@ extern struct dive *try_to_merge(struct dive *a, struct dive *b);
 
 extern void renumber_dives(int nr);
 
+extern void add_event(struct dive *dive, int time, int type, int flags, int value, const char *name);
+
 /* UI related protopypes */
 
 extern void init_ui(int argc, char **argv);
index b20acdbecd0ebf41cc32b2244488d4ad82dcf8a5..806ea651f108497f748e4b56f6d6252fdc821817 100644 (file)
@@ -118,7 +118,7 @@ static int parse_gasmixes(struct dive *dive, parser_t *parser, int ngases)
        return PARSER_STATUS_SUCCESS;
 }
 
-static void handle_event(struct dive **divep, struct sample *sample, parser_sample_value_t value)
+static void handle_event(struct dive *dive, struct sample *sample, parser_sample_value_t value)
 {
        int type, time;
        static const char *events[] = {
@@ -152,9 +152,7 @@ static void handle_event(struct dive **divep, struct sample *sample, parser_samp
        if (sample)
                time += sample->time.seconds;
 
-       printf("   <event type=\"%u\" time=\"%u:%02u\" flags=\"%u\" value=\"%u\" name=\"%s\" />\n",
-               type, time / 60, time % 60,
-               value.event.flags, value.event.value, name);
+       add_event(dive, time, type, value.event.flags, value.event.value, name);
 }
 
 void
@@ -188,7 +186,7 @@ sample_cb(parser_sample_type_t type, parser_sample_value_t value, void *userdata
                sample->temperature.mkelvin = (value.temperature + 273.15) * 1000 + 0.5;
                break;
        case SAMPLE_TYPE_EVENT:
-               handle_event(divep, sample, value);
+               handle_event(dive, sample, value);
                break;
        case SAMPLE_TYPE_RBT:
                printf("   <rbt>%u</rbt>\n", value.rbt);
index 1eb6e95fdd1007aff73d326c7d6b073c7fe36f36..e6472735dcdd40ca91bf69daebcb035ac7ed9be7 100644 (file)
@@ -92,8 +92,14 @@ const struct units IMPERIAL_units = {
  */
 static struct dive *dive;
 static struct sample *sample;
+static struct {
+       int active;
+       duration_t time;
+       int type, flags, value;
+       const char *name;
+} event;
 static struct tm tm;
-static int event_index, cylinder_index;
+static int cylinder_index;
 
 static enum import_source {
        UNKNOWN,
@@ -558,6 +564,32 @@ static int uddf_fill_sample(struct sample *sample, const char *name, int len, ch
                0;
 }
 
+static void eventtime(char *buffer, void *_duration)
+{
+       duration_t *duration = _duration;
+       sampletime(buffer, duration);
+       if (sample)
+               duration->seconds += sample->time.seconds;
+}
+
+static void try_to_fill_event(const char *name, char *buf)
+{
+       int len = strlen(name);
+
+       start_match("event", name, buf);
+       if (MATCH(".event", utf8_string, &event.name))
+               return;
+       if (MATCH(".name", utf8_string, &event.name))
+               return;
+       if (MATCH(".time", eventtime, &event.time))
+               return;
+       if (MATCH(".type", get_index, &event.type))
+               return;
+       if (MATCH(".flags", get_index, &event.flags))
+               return;
+       nonmatch("event", name, buf);
+}
+
 /* 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)
 {
@@ -1137,11 +1169,15 @@ static void dive_end(void)
 
 static void event_start(void)
 {
+       memset(&event, 0, sizeof(event));
+       event.active = 1;
 }
 
 static void event_end(void)
 {
-       event_index++;
+       if (event.name)
+               add_event(dive, event.time.seconds, event.type, event.flags, event.value, event.name);
+       event.active = 0;
 }
 
 static void cylinder_start(void)
@@ -1156,7 +1192,6 @@ static void cylinder_end(void)
 static void sample_start(void)
 {
        sample = prepare_sample(&dive);
-       event_index = 0;
 }
 
 static void sample_end(void)
@@ -1176,6 +1211,10 @@ static void entry(const char *name, int size, const char *raw)
                return;
        memcpy(buf, raw, size);
        buf[size] = 0;
+       if (event.active) {
+               try_to_fill_event(name, buf);
+               return;
+       }
        if (sample) {
                try_to_fill_sample(sample, name, buf);
                return;
index e64b380a48076ccbee46a0f7075b14c93675133f..d6774b5c7f880bb425f9e43209038b13568756f7 100644 (file)
@@ -218,6 +218,12 @@ static void save_cylinder_info(FILE *f, struct dive *dive)
        }
 }
 
+static void show_index(FILE *f, int value, const char *pre, const char *post)
+{
+       if (value)
+               fprintf(f, " %s%d%s", pre, value, post);
+}
+
 static void save_sample(FILE *f, struct sample *sample)
 {
        fprintf(f, "  <sample time='%u:%02u min'", FRACTION(sample->time.seconds,60));
@@ -229,6 +235,25 @@ static void save_sample(FILE *f, struct sample *sample)
        fprintf(f, " />\n");
 }
 
+static void save_one_event(FILE *f, struct event *ev)
+{
+       fprintf(f, "  <event time='%d:%02d min'", FRACTION(ev->time.seconds,60));
+       show_index(f, ev->type, "type='", "'");
+       show_index(f, ev->flags, "flags='", "'");
+       show_index(f, ev->value, "value='", "'");
+       show_utf8(f, ev->name, " name='", "'");
+       fprintf(f, " />\n");
+}
+
+
+static void save_events(FILE *f, struct event *ev)
+{
+       while (ev) {
+               save_one_event(f, ev);
+               ev = ev->next;
+       }
+}
+
 static void save_dive(FILE *f, struct dive *dive)
 {
        int i;
@@ -245,6 +270,7 @@ static void save_dive(FILE *f, struct dive *dive)
                FRACTION(dive->duration.seconds, 60));
        save_overview(f, dive);
        save_cylinder_info(f, dive);
+       save_events(f, dive->events);
        for (i = 0; i < dive->samples; i++)
                save_sample(f, dive->sample+i);
        fprintf(f, "</dive>\n");