Skip to content

Commit

Permalink
Convert over to fully heap based
Browse files Browse the repository at this point in the history
  • Loading branch information
scheibo committed Feb 28, 2014
1 parent 138c957 commit b45ff68
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 40 deletions.
20 changes: 19 additions & 1 deletion activity.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
#include <stdlib.h>
#include <string.h>

#include "activity.h"

Activity *activity_new(void) {
Activity *a;
if (!(a = malloc(sizeof(*a)))) {
return NULL;
}
a->sport = UnknownSport;
a->laps = NULL; /* TODO */
a->data_points = a->last_point = NULL;
a->has_data = calloc(1, sizeof(*(a->has_data)));

return a;
}

void activity_destroy(Activity *a) {
DataPoint *d, *next;

Expand All @@ -18,6 +32,10 @@ void activity_destroy(Activity *a) {
a->laps = NULL;
}

free(a->has_data);
a->has_data = NULL;

free(a);
a = NULL;
}

Expand All @@ -26,7 +44,7 @@ int activity_add_point(Activity *a, DataPoint *point) {

/* TODO (don't malloc one point at a time...), also check return */
DataPoint *d;
if (!(d = malloc(sizeof(d)))) {
if (!(d = malloc(sizeof(*d)))) {
return 1;
}
/* TODO fill in inferred missing values a la gpx/tcx */
Expand Down
16 changes: 3 additions & 13 deletions activity.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,7 @@ typedef struct DataPoint {
struct DataPoint *next;
} DataPoint;

#define UNSET_DATA_POINT \
{ \
UNSET_TIMESTAMP, UNSET_LATITUDE, UNSET_LONGITUDE, UNSET_ALTITUDE, \
UNSET_DISTANCE, UNSET_SPEED, UNSET_POWER, UNSET_GRADE, \
UNSET_HEART_RATE, UNSET_CADENCE, UNSET_LR_BALANCE, UNSET_TEMPERATURE, \
NULL \
}

#define CLEAR_DATA_POINT(d) \
#define UNSET_DATA_POINT(d) \
do { \
(d).timestamp = UNSET_TIMESTAMP; \
(d).latitude = UNSET_LATITUDE; \
Expand Down Expand Up @@ -112,17 +104,15 @@ typedef struct {
uint32_t *laps; /* TODO array of timestamps, always at least one */
DataPoint *data_points;
DataPoint *last_point;
DataPoint has_data;
DataPoint *has_data;
/*
//Summary summary; // can include derived statistics (totalAscent, NP, avg)
//Summary * lap_summaries; // can include derived statistics (totalAscent, NP,
avg)
*/
} Activity;

#define activity_new() \
{ UnknownSport, NULL, NULL, NULL, {0} }

Activity *activity_new(void);
void activity_destroy(Activity *a);
int activity_add_point(Activity *a, DataPoint *point);
int activity_add_lap(Activity *a, uint32_t lap);
Expand Down
4 changes: 2 additions & 2 deletions fix.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ int fix_gps(Activity *a) {
double delta_latitude, delta_longitude;

// ignore null or files without GPS data
if (!a || !a->data_points || !a->has_data.latitude ||
!a->has_data.longitude) { /* TODO add has_data */
if (!a || !a->data_points || !a->has_data->latitude ||
!a->has_data->longitude) { /* TODO add has_data */
return -1;
}

Expand Down
74 changes: 50 additions & 24 deletions gpx.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ typedef struct {
bool metadata;
bool first_element;
bool first_time;
DataPoint data;
DataPoint *data;
} State;

int allspace(const char *str) {
Expand Down Expand Up @@ -45,13 +45,13 @@ static int sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *sax_data) {
} else if (!strcmp(name, "trkpt")) {
attr = mxmlElementGetAttr(node, "lat");
if (attr) {
state->data.latitude = strtod(attr, &end);
if (*end) state->data.latitude = UNSET_LATITUDE;
state->data->latitude = strtod(attr, &end);
if (*end) state->data->latitude = UNSET_LATITUDE;
}
attr = mxmlElementGetAttr(node, "lon");
if (attr) {
state->data.longitude = strtod(attr, &end);
if (*end) state->data.longitude = UNSET_LONGITUDE;
state->data->longitude = strtod(attr, &end);
if (*end) state->data->longitude = UNSET_LONGITUDE;
}
}
state->first_element = false;
Expand All @@ -64,26 +64,26 @@ static int sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *sax_data) {
} else if (state->metadata) {
return 0;
} else if (!strcmp(name, "time")) {
state->data.timestamp = parse_timestamp(data);
state->data->timestamp = parse_timestamp(data);
} else if (!strcmp(name, "ele")) {
state->data.altitude = (int32_t)(strtod(data, &end) * 1000);
if (*end) state->data.altitude = UNSET_ALTITUDE;
state->data->altitude = (int32_t)(strtod(data, &end) * 1000);
if (*end) state->data->altitude = UNSET_ALTITUDE;
} else if (!strcmp(name, "gpxdata:hr") || !strcmp(name, "gpxtpx:hr")) {
state->data.heart_rate = (uint8_t) strtod(data, &end);
if (*end) state->data.heart_rate = UNSET_HEART_RATE;
state->data->heart_rate = (uint8_t) strtod(data, &end);
if (*end) state->data->heart_rate = UNSET_HEART_RATE;
} else if (!strcmp(name, "gpxdata:temp") || !strcmp(name, "gpxtpx:atemp")) {
state->data.temperature = (int8_t) strtod(data, &end);
if (*end) state->data.temperature = UNSET_TEMPERATURE;
state->data->temperature = (int8_t) strtod(data, &end);
if (*end) state->data->temperature = UNSET_TEMPERATURE;
} else if (!strcmp(name, "gpxdata:cadence") || !strcmp(name, "gpxtpx:cad")) {
state->data.cadence = (uint8_t) strtod(data, &end);
if (*end) state->data.cadence = UNSET_CADENCE;
state->data->cadence = (uint8_t) strtod(data, &end);
if (*end) state->data->cadence = UNSET_CADENCE;
} else if (!strcmp(name, "gpxdata:bikepower")) {
state->data.power = (uint16_t) strtod(data, &end);
if (*end) state->data.power = UNSET_POWER;
state->data->power = (uint16_t) strtod(data, &end);
if (*end) state->data->power = UNSET_POWER;
} else if (!strcmp(name, "trkpt")) {
/* TODO */
print_data_point(&(state->data));
CLEAR_DATA_POINT(state->data);
print_data_point(state->data);
UNSET_DATA_POINT(*(state->data));
}
} else if (event == MXML_SAX_DATA) {
mxmlRetain(node);
Expand All @@ -92,22 +92,48 @@ static int sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *sax_data) {
return 0;
}

static State *create_state(void) {
State *state;
if (!(state = malloc(sizeof(*state)))) {
return NULL;
}
state->metadata = false;
state->first_element = true;
state->first_time = true;
if (!(state->data = malloc(sizeof(*(state->data))))) {
return NULL;
}
UNSET_DATA_POINT(*(state->data));
return state;
}

static void destroy_state(State *state) {
free(state->data);
free(state);
}

int gpx_read(char *filename, Activity *activity) {
FILE *f = NULL;
State state = { false /* metadata */, true /* first_element */,
true /* first_time */, UNSET_DATA_POINT };
State *state;
if (!(state = create_state())) {
return 1;
}

if (!(f = fopen(filename, "r"))) {
destroy_state(state);
return 1;
}

if (!mxmlSAXLoadFile(NULL, f, MXML_OPAQUE_CALLBACK, sax_cb, (void *)&state)) {
fprintf(stderr, "failed\n"); /* TODO */
destroy_state(state);
fclose(f);
return 1;
}

fprintf(stderr, "Made it\n"); /* TODO */

destroy_state(state);
fclose(f);
return 0;
}
Expand Down Expand Up @@ -146,11 +172,11 @@ int gpx_write(char *filename, Activity *activity) {

/* TODO */
int main(int argc, char *argv[]) {
Activity activity = activity_new();
int err = gpx_read(argv[1], &activity);
Activity *activity = activity_new();
int err = gpx_read(argv[1], activity);
if (!err && argc > 2) {
err = gpx_write(argv[2], &activity);
err = gpx_write(argv[2], activity);
}
activity_destroy(&activity);
activity_destroy(activity);
return err;
}

0 comments on commit b45ff68

Please sign in to comment.