* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#define _GNU_SOURCE
-
#include <config.h>
#include <unistd.h>
#include <stdlib.h>
#include "utils.h"
#include "gps.h"
#include "mapper-types.h"
+#include "latlon.h"
+#include "map.h"
#include "gpx.h"
+#include "dialogs.h"
#define XML_DATE_FORMAT "%FT%T"
+#define WRITE_STRING(string) { \
+ GnomeVFSResult vfs_result; \
+ GnomeVFSFileSize size; \
+ if(GNOME_VFS_OK != (vfs_result = gnome_vfs_write(handle, (string), strlen((string)), &size))) \
+ { \
+ gchar buffer[BUFFER_SIZE]; \
+ g_snprintf(buffer, sizeof(buffer), \
+ "%s:\n%s\n%s", _("Error while writing to file"), _("File is incomplete."), \
+ gnome_vfs_result_to_string(vfs_result)); \
+ popup_error(_window, buffer); \
+ return FALSE; \
+ } \
+}
+
/** This enum defines the states of the SAX parsing state machine. */
typedef enum {
- START,
- INSIDE_GPX,
+ START=1,
+ INSIDE_GPX=100,
+ INSIDE_METADATA,
INSIDE_PATH,
INSIDE_PATH_SEGMENT,
INSIDE_PATH_POINT,
INSIDE_PATH_POINT_ELE,
INSIDE_PATH_POINT_TIME,
INSIDE_PATH_POINT_DESC,
- FINISH,
- UNKNOWN,
- ERROR,
+ INSIDE_PATH_POINT_NAME,
+ FINISH=5000,
+ UNKNOWN=6666,
+ ERROR=9999,
} SaxState;
/** Data used during the SAX parsing operation. */
struct tm time2;
time1 = time(NULL);
localtime_r(&time1, &time2);
-snprintf(XML_TZONE, sizeof(XML_TZONE), "%+03ld:%02ld",
+g_snprintf(XML_TZONE, sizeof(XML_TZONE), "%+03ld:%02ld",
(time2.tm_gmtoff / 60 / 60), (time2.tm_gmtoff / 60) % 60);
}
data->prev_state = data->state; \
data->state = UNKNOWN; \
data->unknown_depth = 1; \
-}
+ g_debug("GPX: unknown tag"); }
static void
gpx_start_element(SaxData * data, const xmlChar * name, const xmlChar ** attrs)
{
-
+ g_debug("GPX-START: %s (%d)", name, data->state);
switch (data->state) {
case ERROR:
- break;
+ break;
case START:
if (!strcmp((gchar *) name, "gpx"))
data->state = INSIDE_GPX;
else
MACRO_SET_UNKNOWN();
- break;
+ break;
case INSIDE_GPX:
if (!strcmp((gchar *) name, "trk"))
data->state = INSIDE_PATH;
+ else if (!strcmp((gchar *) name, "metadata"))
+ data->state = INSIDE_METADATA;
else
MACRO_SET_UNKNOWN();
- break;
+ break;
+ case INSIDE_METADATA:
+
+ break;
case INSIDE_PATH:
if (!strcmp((gchar *) name, "trkseg")) {
data->state = INSIDE_PATH_SEGMENT;
data->at_least_one_trkpt = FALSE;
} else
MACRO_SET_UNKNOWN();
- break;
+ break;
case INSIDE_PATH_SEGMENT:
if (!strcmp((gchar *) name, "trkpt")) {
const xmlChar **curr_attr;
data->state = ERROR;
} else
MACRO_SET_UNKNOWN();
- break;
+ break;
case INSIDE_PATH_POINT:
if (!strcmp((gchar *) name, "time"))
data->state = INSIDE_PATH_POINT_TIME;
data->state = INSIDE_PATH_POINT_ELE;
else if (!strcmp((gchar *) name, "desc"))
data->state = INSIDE_PATH_POINT_DESC;
-
+ else if (!strcmp((gchar *) name, "name"))
+ data->state = INSIDE_PATH_POINT_NAME;
else
MACRO_SET_UNKNOWN();
- break;
+ break;
case UNKNOWN:
data->unknown_depth++;
- break;
+ break;
default:
;
}
static void
gpx_end_element(SaxData * data, const xmlChar * name)
{
+ g_debug("GPX-END: %s", name);
switch (data->state) {
case ERROR:
- break;
+
+ break;
case START:
data->state = ERROR;
- break;
+ break;
case INSIDE_GPX:
if (!strcmp((gchar *) name, "gpx"))
data->state = FINISH;
else
data->state = ERROR;
- break;
+ break;
+ case INSIDE_METADATA:
+ if (!strcmp((gchar *) name, "metadata"))
+ data->state = INSIDE_GPX;
+ break;
case INSIDE_PATH:
if (!strcmp((gchar *) name, "trk"))
data->state = INSIDE_GPX;
else
data->state = ERROR;
- break;
+ break;
case INSIDE_PATH_SEGMENT:
if (!strcmp((gchar *) name, "trkseg")) {
if (data->at_least_one_trkpt) {
data->state = INSIDE_PATH;
} else
data->state = ERROR;
- break;
+ break;
case INSIDE_PATH_POINT:
if (!strcmp((gchar *) name, "trkpt")) {
data->state = INSIDE_PATH_SEGMENT;
data->at_least_one_trkpt = TRUE;
} else
data->state = ERROR;
- break;
+ break;
case INSIDE_PATH_POINT_ELE:
if (!strcmp((gchar *) name, "ele")) {
gchar *error_check;
data->chars = g_string_new("");
} else
data->state = ERROR;
- break;
+ break;
case INSIDE_PATH_POINT_TIME:
if (!strcmp((gchar *) name, "time")) {
struct tm time;
gchar *ptr;
- if (NULL == (ptr = strptime(data->chars->str,
- XML_DATE_FORMAT, &time)))
+ if (NULL == (ptr = strptime(data->chars->str, XML_DATE_FORMAT, &time)))
/* Failed to parse dateTime format. */
data->state = ERROR;
else {
data->path.tail->time = (mktime(&time));
/* Now, skip inconsequential characters */
- while (*ptr && *ptr != 'Z' && *ptr != '-'
- && *ptr != '+')
+ while (*ptr && *ptr != 'Z' && *ptr != '-' && *ptr != '+')
ptr++;
/* Check if we ran to the end of the string. */
if (*ptr) {
/* Next character is either 'Z', '-', or '+' */
if (*ptr == 'Z')
- /* Zulu (UTC) time. Undo the local time zone's
- * offset. */
+ /* Zulu (UTC) time. Undo the local time zone's offset. */
data->path.tail->time += time.tm_gmtoff;
else {
/* Not Zulu (UTC). Must parse hours and minutes. */
- gint offhours =
- strtol(ptr, &error_check,
- 10);
- if (error_check != ptr
- && *(ptr =
- error_check) == ':') {
+ gint offhours = strtol(ptr, &error_check, 10);
+ if (error_check != ptr && *(ptr = error_check) == ':') {
/* Parse of hours worked. Check minutes. */
- gint offmins =
- strtol(ptr + 1,
- &error_check,
- 10);
- if (error_check !=
- (ptr + 1)) {
+ gint offmins = strtol(ptr + 1, &error_check, 10);
+ if (error_check != (ptr + 1)) {
/* Parse of minutes worked. Calculate. */
- data->path.tail->time +=
- (time.tm_gmtoff -
- (offhours * 60 * 60 + offmins * 60));
+ data->path.tail->time += (time.tm_gmtoff - (offhours * 60 * 60 + offmins * 60));
}
}
}
data->chars = g_string_new("");
} else
data->state = ERROR;
- break;
+ break;
case INSIDE_PATH_POINT_DESC:
/* only parse description for routes */
if (!strcmp((gchar *) name, "desc")) {
MACRO_PATH_INCREMENT_WTAIL(data->path);
data->path.wtail->point = data->path.tail;
- data->path.wtail->desc
- = g_string_free(data->chars, FALSE);
+ data->path.wtail->desc = g_string_free(data->chars, FALSE);
data->chars = g_string_new("");
data->state = INSIDE_PATH_POINT;
} else
data->state = ERROR;
- break;
+ break;
+ case INSIDE_PATH_POINT_NAME:
+ /* Just ignore these for now */
+ g_string_free(data->chars, FALSE);
+ data->chars = g_string_new("");
+ data->state = INSIDE_PATH_POINT;
+ break;
case UNKNOWN:
if (!--data->unknown_depth)
data->state = data->prev_state;
else
data->state = ERROR;
- break;
+ break;
default:
;
}
case INSIDE_PATH_POINT_ELE:
case INSIDE_PATH_POINT_TIME:
case INSIDE_PATH_POINT_DESC:
+ case INSIDE_PATH_POINT_NAME:
for (i = 0; i < len; i++)
data->chars = g_string_append_c(data->chars, ch[i]);
- vprintf("%s\n", data->chars->str);
+ g_debug("GPXC: %s", data->chars->str);
break;
default:
break;
g_string_free(data.chars, TRUE);
if (data.state != FINISH) {
+ g_debug("GPX: Parser stopped in error state %d", data.state);
return FALSE;
}
* plus room for more route data. */
path_resize(dest, num_dest_points + num_src_points);
- memcpy(dest->tail + 1, src_first,
- num_src_points * sizeof(Point));
+ memcpy(dest->tail + 1, src_first, num_src_points * sizeof(Point));
dest->tail += num_src_points;
/* Append waypoints from src to dest->. */
- path_wresize(dest, (dest->wtail - dest->whead)
- + (src->wtail - src->whead) + 2);
+ path_wresize(dest, (dest->wtail - dest->whead) + (src->wtail - src->whead) + 2);
for (curr = src->whead - 1; curr++ != src->wtail;) {
- (++(dest->wtail))->point =
- dest->head + num_dest_points +
- (curr->point - src_first);
+ (++(dest->wtail))->point = dest->head + num_dest_points + (curr->point - src_first);
dest->wtail->desc = curr->desc;
}
MACRO_PATH_FREE((*to_replace));
/* Overwrite with data.route. */
(*to_replace) = data.path;
- path_resize(to_replace,
- to_replace->tail - to_replace->head + 1);
- path_wresize(to_replace,
- to_replace->wtail - to_replace->whead + 1);
+ path_resize(to_replace, to_replace->tail - to_replace->head + 1);
+ path_wresize(to_replace, to_replace->wtail - to_replace->whead + 1);
}
return TRUE;