]>
Commit | Line | Data |
---|---|---|
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 |
42 | static void _goto_xml_tool_class_init ( VikGotoXmlToolClass *klass ); |
43 | static void _goto_xml_tool_init ( VikGotoXmlTool *self ); | |
51f93b0b | 44 | |
0c6b26d3 | 45 | static void _goto_xml_tool_finalize ( GObject *gob ); |
51f93b0b | 46 | |
0c6b26d3 GB |
47 | static gchar *_goto_xml_tool_get_url_format ( VikGotoTool *self ); |
48 | static gboolean _goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct LatLon *ll); | |
51f93b0b | 49 | |
34e71b99 | 50 | typedef struct _VikGotoXmlToolPrivate VikGotoXmlToolPrivate; |
51f93b0b | 51 | |
34e71b99 | 52 | struct _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 | 65 | GType 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 | ||
89 | enum | |
90 | { | |
91 | PROP_0, | |
92 | ||
93 | PROP_URL_FORMAT, | |
94 | PROP_LAT_PATH, | |
95 | PROP_LON_PATH, | |
96 | }; | |
97 | ||
98 | static 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 | ||
131 | static 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 | 161 | static 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 | 209 | VikGotoXmlTool *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 | 214 | static 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 | 225 | static void _goto_xml_tool_finalize ( GObject *gob ) |
51f93b0b GB |
226 | { |
227 | G_OBJECT_GET_CLASS(gob)->finalize(gob); | |
228 | } | |
229 | ||
230 | static gboolean | |
231 | stack_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 */ | |
261 | static 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 | ||
284 | static 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 |
337 | static 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 | } |