]> git.street.me.uk Git - andy/viking.git/blobdiff - src/file.c
Merge pull request #20 from huobos/zh_CN
[andy/viking.git] / src / file.c
index 835f2ecec590fa3226167ce5eaa8fdb61ac709cc..f0d3f23ce4e0afc5ae545a7c9d1b9a760104b840 100644 (file)
 #include <glib/gi18n.h>
 
 #include "file.h"
+#include "misc/strtod.h"
 
 #define TEST_BOOLEAN(str) (! ((str)[0] == '\0' || (str)[0] == '0' || (str)[0] == 'n' || (str)[0] == 'N' || (str)[0] == 'f' || (str)[0] == 'F') )
 #define VIK_MAGIC "#VIK"
 #define GPX_MAGIC "<?xm"
 #define VIK_MAGIC_LEN 4
+#define GPX_MAGIC_LEN 4
 
 #define VIKING_FILE_VERSION 1
 
@@ -57,7 +59,7 @@ typedef struct _Stack Stack;
 
 struct _Stack {
   Stack *under;
-  gpointer *data;
+  gpointer data;
 };
 
 static void pop(Stack **stack) {
@@ -73,9 +75,9 @@ static void push(Stack **stack)
   *stack = tmp;
 }
 
-static gboolean check_magic ( FILE *f, const gchar *magic_number )
+static gboolean check_magic ( FILE *f, const gchar *magic_number, guint magic_length )
 {
-  gchar magic[VIK_MAGIC_LEN];
+  gchar magic[magic_length];
   gboolean rv = FALSE;
   gint8 i;
   if ( fread(magic, 1, sizeof(magic), f) == sizeof(magic) &&
@@ -269,7 +271,7 @@ static void string_list_set_param (gint i, GList *list, gpointer *layer_and_vp)
  */
 static gboolean file_read ( VikAggregateLayer *top, FILE *f, const gchar *dirpath, VikViewport *vp )
 {
-  Stack *stack;
+  Stack *stack = NULL;
   struct LatLon ll = { 0.0, 0.0 };
   gchar buffer[4096];
   gchar *line;
@@ -433,13 +435,13 @@ static gboolean file_read ( VikAggregateLayer *top, FILE *f, const gchar *dirpat
         // However we'll still carry and attempt to read whatever we can
       }
       else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "xmpp", eq_pos ) == 0) /* "hard coded" params: global & for all layer-types */
-        vik_viewport_set_xmpp ( VIK_VIEWPORT(vp), strtod ( line+5, NULL ) );
+        vik_viewport_set_xmpp ( VIK_VIEWPORT(vp), strtod_i8n ( line+5, NULL ) );
       else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "ympp", eq_pos ) == 0)
-        vik_viewport_set_ympp ( VIK_VIEWPORT(vp), strtod ( line+5, NULL ) );
+        vik_viewport_set_ympp ( VIK_VIEWPORT(vp), strtod_i8n ( line+5, NULL ) );
       else if ( stack->under == NULL && eq_pos == 3 && strncasecmp ( line, "lat", eq_pos ) == 0 )
-        ll.lat = strtod ( line+4, NULL );
+        ll.lat = strtod_i8n ( line+4, NULL );
       else if ( stack->under == NULL && eq_pos == 3 && strncasecmp ( line, "lon", eq_pos ) == 0 )
-        ll.lon = strtod ( line+4, NULL );
+        ll.lon = strtod_i8n ( line+4, NULL );
       else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "utm" ) == 0)
         vik_viewport_set_drawmode ( VIK_VIEWPORT(vp), VIK_VIEWPORT_DRAWMODE_UTM);
       else if ( stack->under == NULL && eq_pos == 4 && strncasecmp ( line, "mode", eq_pos ) == 0 && strcasecmp ( line+5, "expedia" ) == 0)
@@ -500,7 +502,7 @@ static gboolean file_read ( VikAggregateLayer *top, FILE *f, const gchar *dirpat
             } else {
               switch ( params[i].type )
               {
-                case VIK_LAYER_PARAM_DOUBLE: x.d = strtod(line, NULL); break;
+                case VIK_LAYER_PARAM_DOUBLE: x.d = strtod_i8n(line, NULL); break;
                 case VIK_LAYER_PARAM_UINT: x.u = strtoul(line, NULL, 10); break;
                 case VIK_LAYER_PARAM_INT: x.i = strtol(line, NULL, 10); break;
                case VIK_LAYER_PARAM_BOOLEAN: x.b = TEST_BOOLEAN(line); break;
@@ -600,7 +602,7 @@ gboolean check_file_magic_vik ( const gchar *filename )
   gboolean result = FALSE;
   FILE *ff = xfopen ( filename );
   if ( ff ) {
-    result = check_magic ( ff, VIK_MAGIC );
+    result = check_magic ( ff, VIK_MAGIC, VIK_MAGIC_LEN );
     xfclose ( ff );
   }
   return result;
@@ -647,7 +649,7 @@ gchar *append_file_ext ( const gchar *filename, VikFileType_t type )
   return new_name;
 }
 
-VikLoadType_t a_file_load ( VikAggregateLayer *top, VikViewport *vp, const gchar *filename_or_uri )
+VikLoadType_t a_file_load ( VikAggregateLayer *top, VikViewport *vp, VikTrwLayer *vtl, const gchar *filename_or_uri )
 {
   g_return_val_if_fail ( vp != NULL, LOAD_TYPE_READ_FAILURE );
 
@@ -668,7 +670,7 @@ VikLoadType_t a_file_load ( VikAggregateLayer *top, VikViewport *vp, const gchar
 
   gchar *dirpath = g_path_get_dirname ( filename );
   // Attempt loading the primary file type first - our internal .vik file:
-  if ( check_magic ( f, VIK_MAGIC ) )
+  if ( check_magic ( f, VIK_MAGIC, VIK_MAGIC_LEN ) )
   {
     if ( file_read ( top, f, dirpath, vp ) )
       load_answer = LOAD_TYPE_VIK_SUCCESS;
@@ -685,32 +687,35 @@ VikLoadType_t a_file_load ( VikAggregateLayer *top, VikViewport *vp, const gchar
        //  must be loaded into a new TrackWaypoint layer (hence it be created)
     gboolean success = TRUE; // Detect load failures - mainly to remove the layer created as it's not required
 
-    VikLayer *vtl = vik_layer_create ( VIK_LAYER_TRW, vp, FALSE );
-    vik_layer_rename ( vtl, a_file_basename ( filename ) );
+    // Add to specified layer
+    gboolean add_new = !IS_VIK_TRW_LAYER(vtl);
+    if (add_new) {
+      vtl = VIK_TRW_LAYER (vik_layer_create ( VIK_LAYER_TRW, vp, FALSE ));
+      vik_layer_rename ( VIK_LAYER(vtl), a_file_basename ( filename ) );
+    }
 
     // In fact both kml & gpx files start the same as they are in xml
-    if ( a_file_check_ext ( filename, ".kml" ) && check_magic ( f, GPX_MAGIC ) ) {
+    if ( a_file_check_ext ( filename, ".kml" ) && check_magic ( f, GPX_MAGIC, GPX_MAGIC_LEN ) ) {
       // Implicit Conversion
-      if ( ! ( success = a_babel_convert_from ( VIK_TRW_LAYER(vtl), "-i kml", filename, NULL, NULL, NULL ) ) ) {
+      ProcessOptions po = { "-i kml", filename, NULL, NULL, NULL, NULL };
+      if ( ! ( success = a_babel_convert_from ( vtl, &po, NULL, NULL, NULL ) ) ) {
         load_answer = LOAD_TYPE_GPSBABEL_FAILURE;
       }
     }
     // NB use a extension check first, as a GPX file header may have a Byte Order Mark (BOM) in it
     //    - which currently confuses our check_magic function
-    else if ( a_file_check_ext ( filename, ".gpx" ) || check_magic ( f, GPX_MAGIC ) ) {
-      if ( ! ( success = a_gpx_read_file ( VIK_TRW_LAYER(vtl), f ) ) ) {
+    else if ( a_file_check_ext ( filename, ".gpx" ) || check_magic ( f, GPX_MAGIC, GPX_MAGIC_LEN ) ) {
+      if ( ! ( success = a_gpx_read_file ( vtl, f ) ) ) {
         load_answer = LOAD_TYPE_GPX_FAILURE;
       }
     }
     else {
       // Try final supported file type
-      if ( ! ( success = a_gpspoint_read_file ( VIK_TRW_LAYER(vtl), f, dirpath ) ) ) {
+      if ( ! ( success = a_gpspoint_read_file ( vtl, f, dirpath ) ) ) {
         // Failure here means we don't know how to handle the file
         load_answer = LOAD_TYPE_UNSUPPORTED_FAILURE;
       }
     }
-    g_free ( dirpath );
-
     // Clean up when we can't handle the file
     if ( ! success ) {
       // free up layer
@@ -718,11 +723,14 @@ VikLoadType_t a_file_load ( VikAggregateLayer *top, VikViewport *vp, const gchar
     }
     else {
       // Complete the setup from the successful load
-      vik_layer_post_read ( vtl, vp, TRUE );
-      vik_aggregate_layer_add_layer ( top, vtl, FALSE );
-      vik_trw_layer_auto_set_view ( VIK_TRW_LAYER(vtl), vp );
+      vik_layer_post_read ( VIK_LAYER(vtl), vp, TRUE );
+      if (add_new) {
+        vik_aggregate_layer_add_layer ( top, VIK_LAYER(vtl), FALSE );
+      }
+      vik_trw_layer_auto_set_view ( vtl, vp );
     }
   }
+  g_free ( dirpath );
   xfclose(f);
   return load_answer;
 }
@@ -829,7 +837,6 @@ gboolean a_file_export ( VikTrwLayer *vtl, const gchar *filename, VikFileType_t
           break;
         case FILE_TYPE_KML:
          fclose ( f );
-         f = NULL;
          switch ( a_vik_get_kml_export_units () ) {
            case VIK_KML_EXPORT_UNITS_STATUTE:
              return a_babel_convert_to ( vtl, NULL, "-o kml", filename, NULL, NULL );
@@ -848,7 +855,6 @@ gboolean a_file_export ( VikTrwLayer *vtl, const gchar *filename, VikFileType_t
       }
     }
     fclose ( f );
-    f = NULL;
     return result;
   }
   return FALSE;
@@ -940,7 +946,7 @@ const gchar *file_GetRelativeFilename ( gchar *currentDirectory, gchar *absolute
   // Handle DOS names that are on different drives:
   if (currentDirectory[0] != absoluteFilename[0]) {
     // not on the same drive, so only absolute filename will do
-    strcpy(relativeFilename, absoluteFilename);
+    g_strlcpy(relativeFilename, absoluteFilename, MAXPATHLEN+1);
     return relativeFilename;
   }
 
@@ -961,7 +967,7 @@ const gchar *file_GetRelativeFilename ( gchar *currentDirectory, gchar *absolute
       i++;
     }
 
-    strcpy(relativeFilename, &absoluteFilename[i]);
+    g_strlcpy(relativeFilename, &absoluteFilename[i], MAXPATHLEN+1);
     return relativeFilename;
   }