]> git.street.me.uk Git - andy/viking.git/blobdiff - src/vikgotoxmltool.c
Prevent the program grinding to a halt if trying to deal with thousands of tiles
[andy/viking.git] / src / vikgotoxmltool.c
index 07800a4619049c1d4abb19ed1156bebf4e3b62a3..0248477e2369d5f1bc0669e2dfe6d1e662381c0e 100644 (file)
@@ -18,7 +18,6 @@
  * 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 <qtonthat@gmail.com>
  */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -27,7 +26,7 @@
 #include <stdio.h>
 #include <string.h>
 #ifdef HAVE_MATH_H
-#include "math.h"
+#include <math.h>
 #endif
 #include <glib.h>
 #include <glib/gstdio.h>
 
 #include "vikgotoxmltool.h"
 
+static void vik_goto_xml_tool_finalize ( GObject *gob );
 
-static void _goto_xml_tool_class_init ( VikGotoXmlToolClass *klass );
-static void _goto_xml_tool_init ( VikGotoXmlTool *self );
-
-static void _goto_xml_tool_finalize ( GObject *gob );
-
-static gchar *_goto_xml_tool_get_url_format ( VikGotoTool *self );
-static gboolean _goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct LatLon *ll);
+static gchar *vik_goto_xml_tool_get_url_format ( VikGotoTool *self );
+static gboolean vik_goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct LatLon *ll);
 
 typedef struct _VikGotoXmlToolPrivate VikGotoXmlToolPrivate;
 
@@ -64,29 +59,7 @@ struct _VikGotoXmlToolPrivate
                                         VIK_GOTO_XML_TOOL_TYPE,          \
                                         VikGotoXmlToolPrivate))
 
-GType vik_goto_xml_tool_get_type()
-{
-  static GType w_type = 0;
-
-  if (!w_type)
-  {
-    static const GTypeInfo w_info = 
-    {
-      sizeof (VikGotoXmlToolClass),
-      NULL, /* base_init */
-      NULL, /* base_finalize */
-      (GClassInitFunc) _goto_xml_tool_class_init,
-      NULL, /* class_finalize */
-      NULL, /* class_data */
-      sizeof (VikGotoXmlTool),
-      0,
-      (GInstanceInitFunc) _goto_xml_tool_init,
-    };
-    w_type = g_type_register_static ( VIK_GOTO_TOOL_TYPE, "VikGotoXmlTool", &w_info, 0 );
-  }
-
-  return w_type;
-}
+G_DEFINE_TYPE (VikGotoXmlTool, vik_goto_xml_tool, VIK_GOTO_TOOL_TYPE)
 
 enum
 {
@@ -100,13 +73,14 @@ enum
 };
 
 static void
-_goto_xml_tool_set_property (GObject      *object,
-                             guint         property_id,
-                             const GValue *value,
-                             GParamSpec   *pspec)
+vik_goto_xml_tool_set_property (GObject      *object,
+                                guint         property_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
 {
   VikGotoXmlTool *self = VIK_GOTO_XML_TOOL (object);
   VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
+  gchar **splitted = NULL;
 
   switch (property_id)
     {
@@ -116,23 +90,53 @@ _goto_xml_tool_set_property (GObject      *object,
       break;
 
     case PROP_LAT_PATH:
+      splitted = g_strsplit (g_value_get_string (value), "@", 2);
       g_free (priv->lat_path);
-      priv->lat_path = g_value_dup_string (value);
+      priv->lat_path = splitted[0];
+      if (splitted[1])
+      {
+        g_object_set (object, "lat-attr", splitted[1], NULL);
+        g_free (splitted[1]);
+      }
+      /* only free the tab, not the strings */
+      g_free (splitted);
+      splitted = NULL;
       break;
 
     case PROP_LAT_ATTR:
-      g_free (priv->lat_attr);
-      priv->lat_attr = g_value_dup_string (value);
+      /* Avoid to overwrite XPATH value */
+      /* NB: This disable future overwriting,
+         but as property is CONSTRUCT_ONLY there is no matter */
+      if (!priv->lat_attr || g_value_get_string (value))
+      {
+        g_free (priv->lat_attr);
+        priv->lat_attr = g_value_dup_string (value);
+      }
       break;
 
     case PROP_LON_PATH:
+      splitted = g_strsplit (g_value_get_string (value), "@", 2);
       g_free (priv->lon_path);
-      priv->lon_path = g_value_dup_string (value);
+      priv->lon_path = splitted[0];
+      if (splitted[1])
+      {
+        g_object_set (object, "lon-attr", splitted[1], NULL);
+        g_free (splitted[1]);
+      }
+      /* only free the tab, not the strings */
+      g_free (splitted);
+      splitted = NULL;
       break;
 
     case PROP_LON_ATTR:
-      g_free (priv->lon_attr);
-      priv->lon_attr = g_value_dup_string (value);
+      /* Avoid to overwrite XPATH value */
+      /* NB: This disable future overwriting,
+         but as property is CONSTRUCT_ONLY there is no matter */
+      if (!priv->lon_attr || g_value_get_string (value))
+      {
+        g_free (priv->lon_attr);
+        priv->lon_attr = g_value_dup_string (value);
+      }
       break;
 
     default:
@@ -143,10 +147,10 @@ _goto_xml_tool_set_property (GObject      *object,
 }
 
 static void
-_goto_xml_tool_get_property (GObject    *object,
-                             guint       property_id,
-                             GValue     *value,
-                             GParamSpec *pspec)
+vik_goto_xml_tool_get_property (GObject    *object,
+                                guint       property_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
 {
   VikGotoXmlTool *self = VIK_GOTO_XML_TOOL (object);
   VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
@@ -180,7 +184,8 @@ _goto_xml_tool_get_property (GObject    *object,
     }
 }
 
-static void _goto_xml_tool_class_init ( VikGotoXmlToolClass *klass )
+static void
+vik_goto_xml_tool_class_init ( VikGotoXmlToolClass *klass )
 {
   GObjectClass *object_class;
   VikGotoToolClass *parent_class;
@@ -188,9 +193,9 @@ static void _goto_xml_tool_class_init ( VikGotoXmlToolClass *klass )
 
   object_class = G_OBJECT_CLASS (klass);
 
-  object_class->finalize = _goto_xml_tool_finalize;
-  object_class->set_property = _goto_xml_tool_set_property;
-  object_class->get_property = _goto_xml_tool_get_property;
+  object_class->finalize = vik_goto_xml_tool_finalize;
+  object_class->set_property = vik_goto_xml_tool_set_property;
+  object_class->get_property = vik_goto_xml_tool_get_property;
 
 
   pspec = g_param_spec_string ("url-format",
@@ -240,18 +245,20 @@ static void _goto_xml_tool_class_init ( VikGotoXmlToolClass *klass )
 
   parent_class = VIK_GOTO_TOOL_CLASS (klass);
 
-  parent_class->get_url_format = _goto_xml_tool_get_url_format;
-  parent_class->parse_file_for_latlon = _goto_xml_tool_parse_file_for_latlon;
+  parent_class->get_url_format = vik_goto_xml_tool_get_url_format;
+  parent_class->parse_file_for_latlon = vik_goto_xml_tool_parse_file_for_latlon;
 
   g_type_class_add_private (klass, sizeof (VikGotoXmlToolPrivate));
 }
 
-VikGotoXmlTool *vik_goto_xml_tool_new ()
+VikGotoXmlTool *
+vik_goto_xml_tool_new ()
 {
   return VIK_GOTO_XML_TOOL ( g_object_new ( VIK_GOTO_XML_TOOL_TYPE, "label", "Google", NULL ) );
 }
 
-static void _goto_xml_tool_init ( VikGotoXmlTool *self )
+static void
+vik_goto_xml_tool_init ( VikGotoXmlTool *self )
 {
   VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
   priv->url_format = NULL;
@@ -264,7 +271,8 @@ static void _goto_xml_tool_init ( VikGotoXmlTool *self )
   priv->ll.lon = NAN;
 }
 
-static void _goto_xml_tool_finalize ( GObject *gob )
+static void
+vik_goto_xml_tool_finalize ( GObject *gob )
 {
   G_OBJECT_GET_CLASS(gob)->finalize(gob);
 }
@@ -364,14 +372,19 @@ _text (GMarkupParseContext *context,
 }
 
 static gboolean
-_goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct LatLon *ll)
+vik_goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct LatLon *ll)
 {
        GMarkupParser xml_parser;
-       GMarkupParseContext *xml_context;
-       GError *error;
+       GMarkupParseContext *xml_context = NULL;
+       GError *error = NULL;
        VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
   g_return_val_if_fail(priv != NULL, FALSE);
 
+  g_debug ("%s: %s@%s, %s@%s",
+           __FUNCTION__,
+           priv->lat_path, priv->lat_attr,
+           priv->lon_path, priv->lon_attr);
+
        FILE *file = g_fopen (filename, "r");
        if (file == NULL)
                /* TODO emit warning */
@@ -400,16 +413,28 @@ _goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct
        
        gchar buff[BUFSIZ];
        size_t nb;
-       while ((nb = fread (buff, sizeof(gchar), BUFSIZ, file)) > 0)
+       while (xml_context &&
+              (nb = fread (buff, sizeof(gchar), BUFSIZ, file)) > 0)
        {
                if (!g_markup_parse_context_parse(xml_context, buff, nb, &error))
-                       fprintf(stderr, "%s: parsing error.\n", __FUNCTION__);
+               {
+                       fprintf(stderr, "%s: parsing error: %s.\n",
+                               __FUNCTION__, error->message);
+                       g_markup_parse_context_free(xml_context);
+                       xml_context = NULL;
+               }
+               g_clear_error (&error);
        }
        /* cleanup */
-       if (!g_markup_parse_context_end_parse(xml_context, &error))
-               fprintf(stderr, "%s: errors occurred reading file.\n", __FUNCTION__);
+       if (xml_context &&
+           !g_markup_parse_context_end_parse(xml_context, &error))
+               fprintf(stderr, "%s: errors occurred while reading file: %s.\n",
+                       __FUNCTION__, error->message);
+       g_clear_error (&error);
        
-       g_markup_parse_context_free(xml_context);
+       if (xml_context)
+               g_markup_parse_context_free(xml_context);
+       xml_context = NULL;
        fclose (file);
   
   if (ll != NULL)
@@ -425,7 +450,7 @@ _goto_xml_tool_parse_file_for_latlon(VikGotoTool *self, gchar *filename, struct
 }
 
 static gchar *
-_goto_xml_tool_get_url_format ( VikGotoTool *self )
+vik_goto_xml_tool_get_url_format ( VikGotoTool *self )
 {
   VikGotoXmlToolPrivate *priv = GOTO_XML_TOOL_GET_PRIVATE (self);
   g_return_val_if_fail(priv != NULL, NULL);