]> git.street.me.uk Git - andy/viking.git/commitdiff
Added layer marshalling support; for now trw and map layers are implemented.
authorAlex Foobarian <foobarian@gmail.com>
Wed, 16 Nov 2005 23:14:30 +0000 (23:14 +0000)
committerAlex Foobarian <foobarian@gmail.com>
Wed, 16 Nov 2005 23:14:30 +0000 (23:14 +0000)
src/vikaggregatelayer.c
src/vikcoordlayer.c
src/vikgeoreflayer.c
src/viklayer.c
src/viklayer.h
src/vikmapslayer.c
src/viktrwlayer.c

index 81ea05cd07ad405d7679a216b437fc563bf9e1fa..74787dda1565e4a712f29194a3a8eaec4b548ae5 100644 (file)
@@ -58,6 +58,8 @@ VikLayerInterface vik_aggregate_layer_interface = {
   (VikLayerFuncSublayerToggleVisible)   NULL,
 
   (VikLayerFuncCopy)                    aggregate_layer_copy,
+  (VikLayerFuncMarshall)               NULL,
+  (VikLayerFuncUnmarshall)             NULL,
 
   (VikLayerFuncSetParam)                NULL,
   (VikLayerFuncGetParam)                NULL,
index 85632a48b6a9cb7b259e8036507443ac3195d433..8baee7b6dd91147cacbf8b55ab47e6164a3f042d 100644 (file)
@@ -71,6 +71,8 @@ VikLayerInterface vik_coord_layer_interface = {
   (VikLayerFuncSublayerToggleVisible)   NULL,
 
   (VikLayerFuncCopy)                    coord_layer_copy,
+  (VikLayerFuncMarshall)               NULL,
+  (VikLayerFuncUnmarshall)             NULL,
 
   (VikLayerFuncSetParam)                coord_layer_set_param,
   (VikLayerFuncGetParam)                coord_layer_get_param,
index f3b3356e85820e98f1214c8974c2c30a346df2c2..604dc407d2a806fbf16413730f41d8b4cd43e2fc 100644 (file)
@@ -83,6 +83,8 @@ VikLayerInterface vik_georef_layer_interface = {
   (VikLayerFuncSublayerToggleVisible)   NULL,
 
   (VikLayerFuncCopy)                    georef_layer_copy,
+  (VikLayerFuncMarshall)               NULL,
+  (VikLayerFuncUnmarshall)             NULL,
 
   (VikLayerFuncSetParam)                georef_layer_set_param,
   (VikLayerFuncGetParam)                georef_layer_get_param,
index edd2eef48fdcdbaba72046e004f1a0d68b583483..65807c25569a28564fadbc5c28037e86b965ca91 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "viking.h"
 #include "vikradiogroup.h"
+#include <string.h>
 
 /* functions common to all layers. */
 /* TODO longone: rename interface free -> finalize */
@@ -194,6 +195,128 @@ VikLayer *vik_layer_copy ( VikLayer *vl, gpointer vp )
     return NULL;
 }
 
+typedef struct {
+  gint layer_type;
+  gint len;
+  guint8 data[0];
+} header_t;
+
+void vik_layer_marshall ( VikLayer *vl, guint8 **data, gint *len )
+{
+  header_t *header;
+  if ( vl && vik_layer_interfaces[vl->type]->marshall ) {
+    vik_layer_interfaces[vl->type]->marshall ( vl, data, len );
+    if (*data) {
+      header = g_malloc(*len + sizeof(*header));
+      header->layer_type = vl->type;
+      header->len = *len;
+      memcpy(header->data, *data, *len);
+      g_free(*data);
+      *data = (guint8 *)header;
+      *len = *len + sizeof(*header);
+    }
+  } else {
+    *data = NULL;
+  }
+}
+
+void vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *datalen )
+{
+  VikLayerParam *params = vik_layer_get_interface(vl->type)->params;
+  VikLayerFuncGetParam get_param = vik_layer_get_interface(vl->type)->get_param;
+  GByteArray* b = g_byte_array_new ();
+  gint len;
+
+#define vlm_append(obj, sz)    \
+  len = (sz);                  \
+  g_byte_array_append ( b, (guint8 *)&len, sizeof(len) );      \
+  g_byte_array_append ( b, (guint8 *)(obj), len );
+
+  vlm_append(vl->name, strlen(vl->name));
+
+  if ( params && get_param )
+  {
+    VikLayerParamData d;
+    guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count;
+    for ( i = 0; i < params_count; i++ )
+    {
+      d = get_param(vl, i);
+      switch ( params[i].type )
+      {
+      case VIK_LAYER_PARAM_STRING: 
+       vlm_append(d.s, strlen(d.s));
+       break;
+      default:
+       vlm_append(&d, sizeof(d));
+       break;
+      }
+    }
+  }
+  
+  *data = b->data;
+  *datalen = b->len;
+  g_byte_array_free ( b, FALSE );
+
+#undef vlm_append
+}
+
+void vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint datalen, VikViewport *vvp )
+{
+  VikLayerParam *params = vik_layer_get_interface(vl->type)->params;
+  VikLayerFuncSetParam set_param = vik_layer_get_interface(vl->type)->set_param;
+  gchar *s;
+  guint8 *b = (guint8 *)data;
+  
+#define vlm_size (*(gint *)b)
+#define vlm_read(obj)                          \
+  memcpy((obj), b+sizeof(gint), vlm_size);     \
+  b += sizeof(gint) + vlm_size;
+  
+  s = g_malloc(vlm_size + 1);
+  s[vlm_size]=0;
+  vlm_read(s);
+  
+  vik_layer_rename(vl, s);
+  
+  g_free(s);
+
+  if ( params && set_param )
+  {
+    VikLayerParamData d;
+    guint16 i, params_count = vik_layer_get_interface(vl->type)->params_count;
+    for ( i = 0; i < params_count; i++ )
+    {
+      switch ( params[i].type )
+      {
+      case VIK_LAYER_PARAM_STRING: 
+       s = g_malloc(vlm_size + 1);
+       s[vlm_size]=0;
+       vlm_read(s);
+       d.s = s;
+       set_param(vl, i, d, vvp);
+       g_free(s);
+       break;
+      default:
+       vlm_read(&d);
+       set_param(vl, i, d, vvp);
+       break;
+      }
+    }
+  }
+}
+
+VikLayer *vik_layer_unmarshall ( guint8 *data, gint len, VikViewport *vvp )
+{
+  header_t *header;
+
+  header = (header_t *)data;
+  
+  if ( vik_layer_interfaces[header->layer_type]->unmarshall ) {
+    return vik_layer_interfaces[header->layer_type]->unmarshall ( header->data, header->len, vvp );
+  } else {
+    return NULL;
+  }
+}
 
 static void layer_finalize ( VikLayer *vl )
 {
index 22404e2b00c3d581e7e9937bd1af98b8527de7b1..1afec173e985638d7b5a2793baca84468735f97f 100644 (file)
@@ -166,6 +166,8 @@ typedef const gchar * (*VikLayerFuncSublayerRenameRequest) (VikLayer *,const gch
 typedef gboolean      (*VikLayerFuncSublayerToggleVisible) (VikLayer *,gint,gpointer);
 
 typedef VikLayer *    (*VikLayerFuncCopy)                  (VikLayer *,VikViewport *);
+typedef void          (*VikLayerFuncMarshall)              (VikLayer *, guint8 **, gint *);
+typedef VikLayer *    (*VikLayerFuncUnmarshall)            (guint8 *, gint, VikViewport *);
 
 /* returns TRUE if needs to redraw due to changed param */
 typedef gboolean      (*VikLayerFuncSetParam)              (VikLayer *, guint16, VikLayerParamData, VikViewport *);
@@ -217,6 +219,8 @@ struct _VikLayerInterface {
   VikLayerFuncSublayerToggleVisible sublayer_toggle_visible;
 
   VikLayerFuncCopy                  copy;
+  VikLayerFuncMarshall              marshall;
+  VikLayerFuncUnmarshall            unmarshall;
 
   /* for I/O */
   VikLayerFuncSetParam              set_param;
@@ -257,6 +261,10 @@ void vik_layer_post_read ( VikLayer *layer, gpointer vp );
 gboolean vik_layer_sublayer_add_menu_items ( VikLayer *l, GtkMenu *menu, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter );
 
 VikLayer *vik_layer_copy ( VikLayer *vl, gpointer vp );
+void      vik_layer_marshall ( VikLayer *vl, guint8 **data, gint *len );
+VikLayer *vik_layer_unmarshall ( guint8 *data, gint len, VikViewport *vvp );
+void      vik_layer_marshall_params ( VikLayer *vl, guint8 **data, gint *len );
+void      vik_layer_unmarshall_params ( VikLayer *vl, guint8 *data, gint len, VikViewport *vvp );
 
 const gchar *vik_layer_sublayer_rename_request ( VikLayer *l, const gchar *newname, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter );
 
index 4dd894c7ac0d2656eefe7754d583c388b550b4c0..932e0046509bc7bf06353c04e8f8424d7784b01d 100644 (file)
@@ -102,6 +102,8 @@ static guint params_maptypes_ids[] = { 2, 1, 4, 5, 9, 8, 7, 10, 11 };
 
 
 static VikMapsLayer *maps_layer_copy ( VikMapsLayer *vml, VikViewport *vvp );
+static void maps_layer_marshall( VikMapsLayer *vml, guint8 **data, gint *len );
+static VikMapsLayer *maps_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp );
 static gboolean maps_layer_set_param ( VikMapsLayer *vml, guint16 id, VikLayerParamData data, VikViewport *vvp );
 static VikLayerParamData maps_layer_get_param ( VikMapsLayer *vml, guint16 id );
 static void maps_layer_draw ( VikMapsLayer *vml, VikViewport *vvp );
@@ -161,6 +163,8 @@ VikLayerInterface vik_maps_layer_interface = {
   (VikLayerFuncSublayerToggleVisible)   NULL,
 
   (VikLayerFuncCopy)                    maps_layer_copy,
+  (VikLayerFuncMarshall)               maps_layer_marshall,
+  (VikLayerFuncUnmarshall)             maps_layer_unmarshall,
 
   (VikLayerFuncSetParam)                maps_layer_set_param,
   (VikLayerFuncGetParam)                maps_layer_get_param,
@@ -397,6 +401,18 @@ static VikMapsLayer *maps_layer_copy ( VikMapsLayer *vml, VikViewport *vvp )
   return rv;
 }
 
+static void maps_layer_marshall( VikMapsLayer *vml, guint8 **data, gint *len )
+{
+  vik_layer_marshall_params ( VIK_LAYER(vml), data, len );
+}
+
+static VikMapsLayer *maps_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
+{
+  VikMapsLayer *rv = maps_layer_new ( vvp );
+  vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp );
+  return rv;
+}
+
 /*********************/
 /****** DRAWING ******/
 /*********************/
index 42c8e8d443e2ca5d6d47033400d5fb3bd2a54136..58ce9105a718e52fb5acadfd25bb97e7d857dcc1 100644 (file)
@@ -31,6 +31,7 @@
 #include "garminsymbols.h"
 #include "thumbnails.h"
 #include "background.h"
+#include "gpx.h"
 
 #include <math.h>
 #include <string.h>
@@ -186,6 +187,9 @@ static gboolean tool_new_waypoint ( VikTrwLayer *vtl, GdkEventButton *event, Vik
 static gboolean tool_new_track ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
 
 static VikTrwLayer *trw_layer_copy ( VikTrwLayer *vtl, gpointer vp );
+static void trw_layer_marshall( VikTrwLayer *vtl, guint8 **data, gint *len );
+static VikTrwLayer *trw_layer_unmarshall( gpointer data, gint len, VikViewport *vvp );
+
 static gboolean trw_layer_set_param ( VikTrwLayer *vtl, guint16 id, VikLayerParamData data, VikViewport *vp );
 static VikLayerParamData trw_layer_get_param ( VikTrwLayer *vtl, guint16 id );
 
@@ -318,6 +322,8 @@ VikLayerInterface vik_trw_layer_interface = {
   (VikLayerFuncSublayerToggleVisible)   vik_trw_layer_sublayer_toggle_visible,
 
   (VikLayerFuncCopy)                    trw_layer_copy,
+  (VikLayerFuncMarshall)                trw_layer_marshall,
+  (VikLayerFuncUnmarshall)              trw_layer_unmarshall,
 
   (VikLayerFuncSetParam)                trw_layer_set_param,
   (VikLayerFuncGetParam)                trw_layer_get_param,
@@ -530,6 +536,59 @@ static void track_copy ( const gchar *name, VikTrack *tr, GHashTable *dest )
   g_hash_table_insert ( dest, g_strdup ( name ), vik_track_copy(tr) );
 }
 
+static void trw_layer_marshall( VikTrwLayer *vtl, guint8 **data, gint *len )
+{
+  guint8 *pd, *dd;
+  gint pl, dl;
+  gchar *tmpname;
+  FILE *f;
+
+  *data = NULL;
+
+  if ((f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) {
+    a_gpx_write_file(vtl, f);
+    vik_layer_marshall_params(VIK_LAYER(vtl), &pd, &pl);
+    fclose(f);
+    g_file_get_contents(tmpname, (void *)&dd, &dl, NULL);
+    *len = sizeof(pl) + pl + dl;
+    *data = g_malloc(*len);
+    memcpy(*data, &pl, sizeof(pl));
+    memcpy(*data + sizeof(pl), pd, pl);
+    memcpy(*data + sizeof(pl) + pl, dd, dl);
+    
+    g_free(pd);
+    g_free(dd);
+    remove(tmpname);
+    g_free(tmpname);
+  }
+}
+
+static VikTrwLayer *trw_layer_unmarshall( gpointer data, gint len, VikViewport *vvp )
+{
+  VikTrwLayer *rv = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, NULL, FALSE ));
+  guint pl;
+  gchar *tmpname;
+  FILE *f;
+
+
+  memcpy(&pl, data, sizeof(pl));
+  data += sizeof(pl);
+  vik_layer_unmarshall_params ( VIK_LAYER(rv), data, pl, vvp );
+  data += pl;
+
+  if (!(f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) {
+    g_critical("couldn't open temp file\n");
+    exit(1);
+  }
+  fwrite(data, len - pl - sizeof(pl), 1, f);
+  rewind(f);
+  a_gpx_read_file(rv, f);
+  fclose(f);
+  remove(tmpname);
+  g_free(tmpname);
+  return rv;
+}
+
 static VikTrwLayer *trw_layer_copy ( VikTrwLayer *vtl, gpointer vp )
 {
   VikTrwLayer *rv = vik_trw_layer_new ( vtl->drawmode );