(VikLayerFuncSublayerToggleVisible) NULL,
(VikLayerFuncCopy) aggregate_layer_copy,
+ (VikLayerFuncMarshall) NULL,
+ (VikLayerFuncUnmarshall) NULL,
(VikLayerFuncSetParam) NULL,
(VikLayerFuncGetParam) NULL,
(VikLayerFuncSublayerToggleVisible) NULL,
(VikLayerFuncCopy) coord_layer_copy,
+ (VikLayerFuncMarshall) NULL,
+ (VikLayerFuncUnmarshall) NULL,
(VikLayerFuncSetParam) coord_layer_set_param,
(VikLayerFuncGetParam) coord_layer_get_param,
(VikLayerFuncSublayerToggleVisible) NULL,
(VikLayerFuncCopy) georef_layer_copy,
+ (VikLayerFuncMarshall) NULL,
+ (VikLayerFuncUnmarshall) NULL,
(VikLayerFuncSetParam) georef_layer_set_param,
(VikLayerFuncGetParam) georef_layer_get_param,
#include "viking.h"
#include "vikradiogroup.h"
+#include <string.h>
/* functions common to all layers. */
/* TODO longone: rename interface free -> finalize */
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 )
{
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 *);
VikLayerFuncSublayerToggleVisible sublayer_toggle_visible;
VikLayerFuncCopy copy;
+ VikLayerFuncMarshall marshall;
+ VikLayerFuncUnmarshall unmarshall;
/* for I/O */
VikLayerFuncSetParam set_param;
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 );
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 );
(VikLayerFuncSublayerToggleVisible) NULL,
(VikLayerFuncCopy) maps_layer_copy,
+ (VikLayerFuncMarshall) maps_layer_marshall,
+ (VikLayerFuncUnmarshall) maps_layer_unmarshall,
(VikLayerFuncSetParam) maps_layer_set_param,
(VikLayerFuncGetParam) maps_layer_get_param,
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 ******/
/*********************/
#include "garminsymbols.h"
#include "thumbnails.h"
#include "background.h"
+#include "gpx.h"
#include <math.h>
#include <string.h>
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 );
(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,
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 );