]> git.street.me.uk Git - andy/viking.git/blame - src/vikgotoxmltool.c
Refactoring: move download code to vikgototool
[andy/viking.git] / src / vikgotoxmltool.c
CommitLineData
51f93b0b
GB
1/*
2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3 *
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
d260d798 5 * Copyright (C) 2009, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
51f93b0b
GB
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Created by Quy Tonthat <qtonthat@gmail.com>
22 */
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26#include <stdlib.h>
27#include <stdio.h>
28#include <string.h>
bc9cecab
GB
29#ifdef HAVE_MATH_H
30#include "math.h"
31#endif
51f93b0b
GB
32#include <glib.h>
33#include <glib/gstdio.h>
34#include <glib/gprintf.h>
35#include <glib/gi18n.h>
36
37#include "viking.h"
51f93b0b 38
34e71b99 39#include "vikgotoxmltool.h"
51f93b0b
GB
40
41
0c6b26d3
GB
42static void _goto_xml_tool_class_init ( VikGotoXmlToolClass *klass );
43static void _goto_xml_tool_init ( VikGotoXmlTool *self );
51f93b0b 44
0c6b26d3 45static void _goto_xml_tool_finalize ( GObject *gob );
51f93b0b 46
0c6b26d3
GB
47static gchar *_goto_xml_tool_get_url_format ( VikGotoTool *self );
48static gboolean _goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct LatLon *ll);
51f93b0b 49
34e71b99 50typedef struct _VikGotoXmlToolPrivate VikGotoXmlToolPrivate;
51f93b0b 51
34e71b99 52struct _VikGotoXmlToolPrivate
51f93b0b
GB
53{
54 gchar *url_format;
55 gchar *lat_path;
56 gchar *lon_path;
57
58 struct LatLon ll;
59};
60
34e71b99
GB
61#define GOTO_XML_TOOL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
62 VIK_GOTO_XML_TOOL_TYPE, \
63 VikGotoXmlToolPrivate))
51f93b0b 64
34e71b99 65GType vik_goto_xml_tool_get_type()
51f93b0b
GB
66{
67 static GType w_type = 0;
68
69 if (!w_type)
70 {
71 static const GTypeInfo w_info =
72 {
34e71b99 73 sizeof (VikGotoXmlToolClass),
51f93b0b
GB
74 NULL, /* base_init */
75 NULL, /* base_finalize */
0c6b26d3 76 (GClassInitFunc) _goto_xml_tool_class_init,
51f93b0b
GB
77 NULL, /* class_finalize */
78 NULL, /* class_data */
34e71b99 79 sizeof (VikGotoXmlTool),
51f93b0b 80 0,
0c6b26d3 81 (GInstanceInitFunc) _goto_xml_tool_init,
51f93b0b 82 };
34e71b99 83 w_type = g_type_register_static ( VIK_GOTO_TOOL_TYPE, "VikGotoXmlTool", &w_info, 0 );
51f93b0b
GB
84 }
85
86 return w_type;
87}
88
89enum
90{
91 PROP_0,
92
93 PROP_URL_FORMAT,
94 PROP_LAT_PATH,
95 PROP_LON_PATH,
96};
97
98static void
0c6b26d3
GB
99_goto_xml_tool_set_property (GObject *object,
100 guint property_id,
101 const GValue *value,
102 GParamSpec *pspec)
51f93b0b 103{
34e71b99
GB
104 VikGotoXmlTool *self = VIK_GOTO_XML_TOOL (object);
105 VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
51f93b0b
GB
106
107 switch (property_id)
108 {
109 case PROP_URL_FORMAT:
110 g_free (priv->url_format);
111 priv->url_format = g_value_dup_string (value);
112 break;
113
114 case PROP_LAT_PATH:
115 g_free (priv->lat_path);
116 priv->lat_path = g_value_dup_string (value);
117 break;
118
119 case PROP_LON_PATH:
120 g_free (priv->lon_path);
121 priv->lon_path = g_value_dup_string (value);
122 break;
123
124 default:
125 /* We don't have any other property... */
126 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
127 break;
128 }
129}
130
131static void
0c6b26d3
GB
132_goto_xml_tool_get_property (GObject *object,
133 guint property_id,
134 GValue *value,
135 GParamSpec *pspec)
51f93b0b 136{
34e71b99
GB
137 VikGotoXmlTool *self = VIK_GOTO_XML_TOOL (object);
138 VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
51f93b0b
GB
139
140 switch (property_id)
141 {
142 case PROP_URL_FORMAT:
143 g_value_set_string (value, priv->url_format);
144 break;
145
146 case PROP_LAT_PATH:
147 g_value_set_string (value, priv->lat_path);
148 break;
149
150 case PROP_LON_PATH:
151 g_value_set_string (value, priv->lon_path);
152 break;
153
154 default:
155 /* We don't have any other property... */
156 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
157 break;
158 }
159}
160
0c6b26d3 161static void _goto_xml_tool_class_init ( VikGotoXmlToolClass *klass )
51f93b0b
GB
162{
163 GObjectClass *object_class;
34e71b99 164 VikGotoToolClass *parent_class;
51f93b0b
GB
165 GParamSpec *pspec;
166
167 object_class = G_OBJECT_CLASS (klass);
168
0c6b26d3
GB
169 object_class->finalize = _goto_xml_tool_finalize;
170 object_class->set_property = _goto_xml_tool_set_property;
171 object_class->get_property = _goto_xml_tool_get_property;
51f93b0b
GB
172
173
174 pspec = g_param_spec_string ("url-format",
175 "URL format",
176 "The format of the URL",
177 "<no-set>" /* default value */,
178 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
179 g_object_class_install_property (object_class,
180 PROP_URL_FORMAT,
181 pspec);
182
183 pspec = g_param_spec_string ("lat-path",
184 "Lat path",
185 "XPath of the latitude",
186 "<no-set>" /* default value */,
187 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
188 g_object_class_install_property (object_class,
189 PROP_LAT_PATH,
190 pspec);
191
192 pspec = g_param_spec_string ("lon-path",
193 "Lon path",
194 "XPath of the longitude",
195 "<no-set>" /* default value */,
196 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
197 g_object_class_install_property (object_class,
198 PROP_LON_PATH,
199 pspec);
200
34e71b99 201 parent_class = VIK_GOTO_TOOL_CLASS (klass);
51f93b0b 202
0c6b26d3
GB
203 parent_class->get_url_format = _goto_xml_tool_get_url_format;
204 parent_class->parse_file_for_latlon = _goto_xml_tool_parse_file_for_latlon;
51f93b0b 205
34e71b99 206 g_type_class_add_private (klass, sizeof (VikGotoXmlToolPrivate));
51f93b0b
GB
207}
208
34e71b99 209VikGotoXmlTool *vik_goto_xml_tool_new ()
51f93b0b 210{
34e71b99 211 return VIK_GOTO_XML_TOOL ( g_object_new ( VIK_GOTO_XML_TOOL_TYPE, "label", "Google", NULL ) );
51f93b0b
GB
212}
213
0c6b26d3 214static void _goto_xml_tool_init ( VikGotoXmlTool *self )
51f93b0b 215{
34e71b99 216 VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
51f93b0b
GB
217 priv->url_format = NULL;
218 priv->lat_path = NULL;
219 priv->lon_path = NULL;
bc9cecab
GB
220 //
221 priv->ll.lat = NAN;
222 priv->ll.lon = NAN;
51f93b0b
GB
223}
224
0c6b26d3 225static void _goto_xml_tool_finalize ( GObject *gob )
51f93b0b
GB
226{
227 G_OBJECT_GET_CLASS(gob)->finalize(gob);
228}
229
230static gboolean
231stack_is_path (const GSList *stack,
232 const gchar *path)
233{
bc9cecab 234 gboolean equal = TRUE;
b146adc7 235 int stack_len = g_list_length((GList *)stack);
bc9cecab
GB
236 int i = 0;
237 i = stack_len - 1;
238 while (equal == TRUE && i >= 0)
239 {
240 if (*path != '/')
241 equal = FALSE;
242 else
243 path++;
b146adc7 244 const gchar *current = g_list_nth_data((GList *)stack, i);
bc9cecab
GB
245 size_t len = strlen(current);
246 if (strncmp(path, current, len) != 0 )
247 equal = FALSE;
248 else
249 {
250 path += len;
251 }
252 i--;
253 }
254 if (*path != '\0')
255 equal = FALSE;
51f93b0b
GB
256 return equal;
257}
258
259/* Called for character data */
260/* text is not nul-terminated */
261static void
262_text (GMarkupParseContext *context,
263 const gchar *text,
264 gsize text_len,
265 gpointer user_data,
266 GError **error)
267{
34e71b99
GB
268 VikGotoXmlTool *self = VIK_GOTO_XML_TOOL (user_data);
269 VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
51f93b0b 270 const GSList *stack = g_markup_parse_context_get_element_stack (context);
bc9cecab 271 gchar *textl = g_strndup(text, text_len);
039bdd14
GB
272 /* Store only first result */
273 if (isnan(priv->ll.lat) && stack_is_path (stack, priv->lat_path))
51f93b0b 274 {
bc9cecab 275 priv->ll.lat = g_ascii_strtod(textl, NULL);
51f93b0b 276 }
039bdd14 277 if (isnan(priv->ll.lon) && stack_is_path (stack, priv->lon_path))
51f93b0b 278 {
bc9cecab 279 priv->ll.lon = g_ascii_strtod(textl, NULL);
51f93b0b 280 }
bc9cecab 281 g_free(textl);
51f93b0b
GB
282}
283
284static gboolean
0c6b26d3 285_goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct LatLon *ll)
51f93b0b
GB
286{
287 GMarkupParser xml_parser;
288 GMarkupParseContext *xml_context;
289 GError *error;
34e71b99 290 VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
0c6b26d3 291 g_return_val_if_fail(priv != NULL, FALSE);
51f93b0b
GB
292
293 FILE *file = g_fopen (filename, "r");
294 if (file == NULL)
295 /* TODO emit warning */
296 return FALSE;
297
298 /* setup context parse (ie callbacks) */
299 xml_parser.start_element = NULL;
300 xml_parser.end_element = NULL;
301 xml_parser.text = &_text;
302 xml_parser.passthrough = NULL;
303 xml_parser.error = NULL;
304
305 xml_context = g_markup_parse_context_new(&xml_parser, 0, self, NULL);
bc9cecab
GB
306
307 /* setup result */
308 priv->ll.lat = NAN;
309 priv->ll.lon = NAN;
51f93b0b
GB
310
311 gchar buff[BUFSIZ];
312 size_t nb;
313 while ((nb = fread (buff, sizeof(gchar), BUFSIZ, file)) > 0)
314 {
315 if (!g_markup_parse_context_parse(xml_context, buff, nb, &error))
4ce0404a 316 fprintf(stderr, "%s: parsing error.\n", __FUNCTION__);
51f93b0b
GB
317 }
318 /* cleanup */
319 if (!g_markup_parse_context_end_parse(xml_context, &error))
4ce0404a 320 fprintf(stderr, "%s: errors occurred reading file.\n", __FUNCTION__);
51f93b0b
GB
321
322 g_markup_parse_context_free(xml_context);
323 fclose (file);
324
325 if (ll != NULL)
326 {
51f93b0b
GB
327 *ll = priv->ll;
328 }
329
bc9cecab
GB
330 if (isnan(priv->ll.lat) || isnan(priv->ll.lat))
331 /* At least one coordinate not found */
332 return FALSE;
333 else
334 return TRUE;
51f93b0b
GB
335}
336
0c6b26d3
GB
337static gchar *
338_goto_xml_tool_get_url_format ( VikGotoTool *self )
51f93b0b 339{
34e71b99 340 VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
0c6b26d3
GB
341 g_return_val_if_fail(priv != NULL, NULL);
342 return priv->url_format;
51f93b0b 343}