From 51f93b0b6e1e3e6d5d5a269f25f6aed2a04edaad Mon Sep 17 00:00:00 2001 From: Guilhem Bonnefille Date: Sun, 6 Dec 2009 23:57:50 +0100 Subject: [PATCH] Add generic XML earch code --- src/Makefile.am | 1 + src/vikxmlsearchtool.c | 348 +++++++++++++++++++++++++++++++++++++++++++++++++ src/vikxmlsearchtool.h | 34 +++++ 3 files changed, 383 insertions(+) create mode 100644 src/vikxmlsearchtool.c create mode 100644 src/vikxmlsearchtool.h diff --git a/src/Makefile.am b/src/Makefile.am index 790b807d..1846df5b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,6 +66,7 @@ libviking_a_SOURCES = \ vikgeoreflayer.c vikgeoreflayer.h \ vikfileentry.c vikfileentry.h \ viksearchtool.c viksearchtool.h \ + vikxmlsearchtool.c vikxmlsearchtool.h \ viksearch.c viksearch.h \ viktrwlayer_tpwin.c viktrwlayer_tpwin.h \ viktrwlayer_propwin.c viktrwlayer_propwin.h \ diff --git a/src/vikxmlsearchtool.c b/src/vikxmlsearchtool.c new file mode 100644 index 00000000..a38b3403 --- /dev/null +++ b/src/vikxmlsearchtool.c @@ -0,0 +1,348 @@ +/* + * viking -- GPS Data and Topo Analyzer, Explorer, and Manager + * + * Copyright (C) 2003-2005, Evan Battaglia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Created by Quy Tonthat + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#include +#include +#include +#include +#include + +#include "viking.h" +#include "util.h" +#include "curl_download.h" + +#include "vikxmlsearchtool.h" + + +static void vik_xml_search_tool_class_init ( VikXmlSearchToolClass *klass ); +static void vik_xml_search_tool_init ( VikXmlSearchTool *vwd ); + +static void vik_xml_search_tool_finalize ( GObject *gob ); + +static int vik_xml_search_tool_get_coord ( VikSearchTool *self, VikWindow *vw, VikViewport *vvp, gchar *srch_str, VikCoord *coord ); + +typedef struct _VikXmlSearchToolPrivate VikXmlSearchToolPrivate; + +struct _VikXmlSearchToolPrivate +{ + gchar *url_format; + gchar *lat_path; + gchar *lon_path; + + struct LatLon ll; +}; + +#define XML_SEARCH_TOOL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + VIK_XML_SEARCH_TOOL_TYPE, \ + VikXmlSearchToolPrivate)) + +GType vik_xml_search_tool_get_type() +{ + static GType w_type = 0; + + if (!w_type) + { + static const GTypeInfo w_info = + { + sizeof (VikXmlSearchToolClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) vik_xml_search_tool_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (VikXmlSearchTool), + 0, + (GInstanceInitFunc) vik_xml_search_tool_init, + }; + w_type = g_type_register_static ( VIK_SEARCH_TOOL_TYPE, "VikXmlSearchTool", &w_info, 0 ); + } + + return w_type; +} + +enum +{ + PROP_0, + + PROP_URL_FORMAT, + PROP_LAT_PATH, + PROP_LON_PATH, +}; + +static void +xml_search_tool_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (object); + VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self); + + switch (property_id) + { + case PROP_URL_FORMAT: + g_free (priv->url_format); + priv->url_format = g_value_dup_string (value); + break; + + case PROP_LAT_PATH: + g_free (priv->lat_path); + priv->lat_path = g_value_dup_string (value); + break; + + case PROP_LON_PATH: + g_free (priv->lon_path); + priv->lon_path = g_value_dup_string (value); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +xml_search_tool_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (object); + VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self); + + switch (property_id) + { + case PROP_URL_FORMAT: + g_value_set_string (value, priv->url_format); + break; + + case PROP_LAT_PATH: + g_value_set_string (value, priv->lat_path); + break; + + case PROP_LON_PATH: + g_value_set_string (value, priv->lon_path); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void vik_xml_search_tool_class_init ( VikXmlSearchToolClass *klass ) +{ + GObjectClass *object_class; + VikSearchToolClass *parent_class; + GParamSpec *pspec; + + object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = vik_xml_search_tool_finalize; + object_class->set_property = xml_search_tool_set_property; + object_class->get_property = xml_search_tool_get_property; + + + pspec = g_param_spec_string ("url-format", + "URL format", + "The format of the URL", + "" /* default value */, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + g_object_class_install_property (object_class, + PROP_URL_FORMAT, + pspec); + + pspec = g_param_spec_string ("lat-path", + "Lat path", + "XPath of the latitude", + "" /* default value */, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + g_object_class_install_property (object_class, + PROP_LAT_PATH, + pspec); + + pspec = g_param_spec_string ("lon-path", + "Lon path", + "XPath of the longitude", + "" /* default value */, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + g_object_class_install_property (object_class, + PROP_LON_PATH, + pspec); + + parent_class = VIK_SEARCH_TOOL_CLASS (klass); + + parent_class->get_coord = vik_xml_search_tool_get_coord; + + g_type_class_add_private (klass, sizeof (VikXmlSearchToolPrivate)); +} + +VikXmlSearchTool *vik_xml_search_tool_new () +{ + return VIK_XML_SEARCH_TOOL ( g_object_new ( VIK_XML_SEARCH_TOOL_TYPE, "label", "Google", NULL ) ); +} + +static void vik_xml_search_tool_init ( VikXmlSearchTool *self ) +{ + VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self); + priv->url_format = NULL; + priv->lat_path = NULL; + priv->lon_path = NULL; +} + +static void vik_xml_search_tool_finalize ( GObject *gob ) +{ + G_OBJECT_GET_CLASS(gob)->finalize(gob); +} + +static gboolean +stack_is_path (const GSList *stack, + const gchar *path) +{ + gboolean equal = FALSE; + // TODO + return equal; +} + +/* Called for character data */ +/* text is not nul-terminated */ +static void +_text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (user_data); + VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self); + const GSList *stack = g_markup_parse_context_get_element_stack (context); + if (stack_is_path (stack, priv->lat_path)) + { + // TODO priv->ll.lat = g_ascii_strtod(text, NULL); + } + if (stack_is_path (stack, priv->lon_path)) + { + // TODO priv->ll.lon = g_ascii_strtod(text, NULL); + } +} + +static gboolean +parse_file_for_latlon(VikXmlSearchTool *self, gchar *filename, struct LatLon *ll) +{ + GMarkupParser xml_parser; + GMarkupParseContext *xml_context; + GError *error; + + FILE *file = g_fopen (filename, "r"); + if (file == NULL) + /* TODO emit warning */ + return FALSE; + + /* setup context parse (ie callbacks) */ + xml_parser.start_element = NULL; + xml_parser.end_element = NULL; + xml_parser.text = &_text; + xml_parser.passthrough = NULL; + xml_parser.error = NULL; + + xml_context = g_markup_parse_context_new(&xml_parser, 0, self, NULL); + + gchar buff[BUFSIZ]; + size_t nb; + while ((nb = fread (buff, sizeof(gchar), BUFSIZ, file)) > 0) + { + if (!g_markup_parse_context_parse(xml_context, buff, nb, &error)) + printf("read_xml() : parsing error.\n"); + } + /* cleanup */ + if (!g_markup_parse_context_end_parse(xml_context, &error)) + printf("read_xml() : errors occurred reading file.\n"); + + g_markup_parse_context_free(xml_context); + fclose (file); + + if (ll != NULL) + { + VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self); + *ll = priv->ll; + } + + return TRUE; +} + +static int vik_xml_search_tool_get_coord ( VikSearchTool *object, VikWindow *vw, VikViewport *vvp, gchar *srch_str, VikCoord *coord ) +{ + FILE *tmp_file; + int tmp_fd; + gchar *tmpname; + gchar *uri; + gchar *escaped_srch_str; + int ret = 0; /* OK */ + struct LatLon ll; + + g_debug("%s: raw search: %s", __FUNCTION__, srch_str); + + escaped_srch_str = uri_escape(srch_str); + + g_debug("%s: escaped search: %s", __FUNCTION__, escaped_srch_str); + + if ((tmp_fd = g_file_open_tmp ("vikxmlsearch.XXXXXX", &tmpname, NULL)) == -1) { + g_critical(_("couldn't open temp file")); + exit(1); + } + + VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (object); + VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self); + + tmp_file = fdopen(tmp_fd, "r+"); + uri = g_strdup_printf(priv->url_format, escaped_srch_str); + + /* TODO: curl may not be available */ + if (curl_download_uri(uri, tmp_file, NULL)) { /* error */ + fclose(tmp_file); + tmp_file = NULL; + ret = -1; + goto done; + } + + fclose(tmp_file); + tmp_file = NULL; + if (!parse_file_for_latlon(self, tmpname, &ll)) { + ret = -1; + goto done; + } + + vik_coord_load_from_latlon ( coord, vik_viewport_get_coord_mode(vvp), &ll ); + +done: + g_free(escaped_srch_str); + g_free(uri); + g_remove(tmpname); + g_free(tmpname); + return ret; +} diff --git a/src/vikxmlsearchtool.h b/src/vikxmlsearchtool.h new file mode 100644 index 00000000..9bf7bbaa --- /dev/null +++ b/src/vikxmlsearchtool.h @@ -0,0 +1,34 @@ +#ifndef __VIK_XML_SEARCH_TOOL_H +#define __VIK_XML_SEARCH_TOOL_H + +#include + +#include "vikwindow.h" + +#include "viksearchtool.h" + +#define VIK_XML_SEARCH_TOOL_TYPE (vik_xml_search_tool_get_type ()) +#define VIK_XML_SEARCH_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIK_XML_SEARCH_TOOL_TYPE, VikXmlSearchTool)) +#define VIK_XML_SEARCH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIK_XML_SEARCH_TOOL_TYPE, VikXmlSearchToolClass)) +#define IS_VIK_XML_SEARCH_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIK_XML_SEARCH_TOOL_TYPE)) +#define IS_VIK_XML_SEARCH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIK_XML_SEARCH_TOOL_TYPE)) +#define VIK_XML_SEARCH_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIK_XML_SEARCH_TOOL_TYPE, VikXmlSearchToolClass)) + + +typedef struct _VikXmlSearchTool VikXmlSearchTool; +typedef struct _VikXmlSearchToolClass VikXmlSearchToolClass; + +struct _VikXmlSearchToolClass +{ + VikSearchToolClass object_class; +}; + +GType vik_xml_search_tool_get_type (); + +struct _VikXmlSearchTool { + VikSearchTool obj; +}; + +VikXmlSearchTool *vik_xml_search_tool_new (); + +#endif -- 2.11.4.GIT