From 911400b5f03f33605110ef8eb4564d758cf84c3c Mon Sep 17 00:00:00 2001 From: Alex Foobarian Date: Wed, 16 Nov 2005 23:14:30 +0000 Subject: [PATCH] Added layer marshalling support; for now trw and map layers are implemented. --- src/vikaggregatelayer.c | 2 + src/vikcoordlayer.c | 2 + src/vikgeoreflayer.c | 2 + src/viklayer.c | 123 ++++++++++++++++++++++++++++++++++++++++ src/viklayer.h | 8 +++ src/vikmapslayer.c | 16 ++++++ src/viktrwlayer.c | 59 +++++++++++++++++++ 7 files changed, 212 insertions(+) diff --git a/src/vikaggregatelayer.c b/src/vikaggregatelayer.c index 81ea05cd..74787dda 100644 --- a/src/vikaggregatelayer.c +++ b/src/vikaggregatelayer.c @@ -58,6 +58,8 @@ VikLayerInterface vik_aggregate_layer_interface = { (VikLayerFuncSublayerToggleVisible) NULL, (VikLayerFuncCopy) aggregate_layer_copy, + (VikLayerFuncMarshall) NULL, + (VikLayerFuncUnmarshall) NULL, (VikLayerFuncSetParam) NULL, (VikLayerFuncGetParam) NULL, diff --git a/src/vikcoordlayer.c b/src/vikcoordlayer.c index 85632a48..8baee7b6 100644 --- a/src/vikcoordlayer.c +++ b/src/vikcoordlayer.c @@ -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, diff --git a/src/vikgeoreflayer.c b/src/vikgeoreflayer.c index f3b3356e..604dc407 100644 --- a/src/vikgeoreflayer.c +++ b/src/vikgeoreflayer.c @@ -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, diff --git a/src/viklayer.c b/src/viklayer.c index edd2eef4..65807c25 100644 --- a/src/viklayer.c +++ b/src/viklayer.c @@ -21,6 +21,7 @@ #include "viking.h" #include "vikradiogroup.h" +#include /* 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 ) { diff --git a/src/viklayer.h b/src/viklayer.h index 22404e2b..1afec173 100644 --- a/src/viklayer.h +++ b/src/viklayer.h @@ -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 ); diff --git a/src/vikmapslayer.c b/src/vikmapslayer.c index 4dd894c7..932e0046 100644 --- a/src/vikmapslayer.c +++ b/src/vikmapslayer.c @@ -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 ******/ /*********************/ diff --git a/src/viktrwlayer.c b/src/viktrwlayer.c index 42c8e8d4..58ce9105 100644 --- a/src/viktrwlayer.c +++ b/src/viktrwlayer.c @@ -31,6 +31,7 @@ #include "garminsymbols.h" #include "thumbnails.h" #include "background.h" +#include "gpx.h" #include #include @@ -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 ); -- 2.39.5