[glib/gsettings] add GValue serialiser
- From: Ryan Lortie <ryanl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glib/gsettings] add GValue serialiser
- Date: Tue, 29 Sep 2009 03:55:59 +0000 (UTC)
commit 7e7f79ffcc3ae6a2557e445e3491321bb771bcbc
Author: Ryan Lortie <desrt desrt ca>
Date: Mon Sep 28 23:44:46 2009 -0400
add GValue serialiser
glib/glib-object.h | 1 +
gobject/Makefile.am | 2 +
gobject/gobject.symbols | 9 +
gobject/gtype.c | 3 +
gobject/gtype.h | 1 +
gobject/gtypeserialiser.c | 592 +++++++++++++++++++++++++++++++++++++++++++++
gobject/gtypeserialiser.h | 41 +++
7 files changed, 649 insertions(+), 0 deletions(-)
---
diff --git a/glib/glib-object.h b/glib/glib-object.h
index 8687ef1..a8c90e2 100644
--- a/glib/glib-object.h
+++ b/glib/glib-object.h
@@ -35,6 +35,7 @@
#include <gobject/gvalue.h>
#include <gobject/gvaluearray.h>
#include <gobject/gvaluetypes.h>
+#include <gobject/gtypeserialiser.h>
#undef __GLIB_GOBJECT_H_INSIDE__
diff --git a/gobject/Makefile.am b/gobject/Makefile.am
index ec27aa1..c617b53 100644
--- a/gobject/Makefile.am
+++ b/gobject/Makefile.am
@@ -101,6 +101,7 @@ gobject_public_h_sources = \
gtype.h \
gtypemodule.h \
gtypeplugin.h \
+ gtypeserialiser.h \
gvalue.h \
gvaluearray.h \
gvaluecollector.h \
@@ -123,6 +124,7 @@ gobject_c_sources = \
gtype.c \
gtypemodule.c \
gtypeplugin.c \
+ gtypeserialiser.c \
gvalue.c \
gvaluearray.c \
gvaluetransform.c \
diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols
index 3e0e162..b2fbc7f 100644
--- a/gobject/gobject.symbols
+++ b/gobject/gobject.symbols
@@ -436,6 +436,15 @@ g_value_set_instance
#endif
#endif
+#if IN_HEADER(__G_TYPE_SERIALISER_H__)
+#if IN_FILE(__G_TYPE_SERIALISER_C__)
+g_value_serialise
+g_value_deserialise
+g_type_serialiser_check
+g_type_serialiser_register_static
+#endif
+#endif
+
#ifdef INCLUDE_VARIABLES
g_param_spec_types
#endif
diff --git a/gobject/gtype.c b/gobject/gtype.c
index c6dff7f..2f32ed5 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -4045,6 +4045,9 @@ g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
/* G_TYPE_* value types
*/
g_value_types_init ();
+
+ /* serialiser */
+ g_type_serialiser_init ();
/* G_TYPE_ENUM & G_TYPE_FLAGS
*/
diff --git a/gobject/gtype.h b/gobject/gtype.h
index 1eeccde..4de5d4d 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -1449,6 +1449,7 @@ G_CONST_RETURN gchar* g_type_name_from_class (GTypeClass *g_class);
/* --- internal functions --- */
G_GNUC_INTERNAL void g_value_c_init (void); /* sync with gvalue.c */
G_GNUC_INTERNAL void g_value_types_init (void); /* sync with gvaluetypes.c */
+G_GNUC_INTERNAL void g_type_serialiser_init (void); /* sync with gvalueserialiser.c */
G_GNUC_INTERNAL void g_enum_types_init (void); /* sync with genums.c */
G_GNUC_INTERNAL void g_param_type_init (void); /* sync with gparam.c */
G_GNUC_INTERNAL void g_boxed_type_init (void); /* sync with gboxed.c */
diff --git a/gobject/gtypeserialiser.c b/gobject/gtypeserialiser.c
new file mode 100644
index 0000000..d9f451d
--- /dev/null
+++ b/gobject/gtypeserialiser.c
@@ -0,0 +1,592 @@
+/*
+ * Copyright © 2009 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * licence, or (at your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ */
+
+#include "gtypeserialiser.h"
+#include "gvaluetypes.h"
+#include "gvalue.h"
+
+#include "gobjectalias.h"
+
+static GQuark _table_quark;
+static GQuark
+table_quark (void)
+{
+ if (_table_quark == 0)
+ _table_quark = g_quark_from_string ("GTypeSerialiserTable");
+
+ return _table_quark;
+}
+
+static GTypeSerialiserTable *
+table_lookup (GType type)
+{
+ return g_type_get_qdata (type, table_quark ());
+}
+
+gboolean
+g_type_serialiser_check (GType g_type,
+ const GVariantType *type)
+{
+ GTypeSerialiserTable *table = table_lookup (g_type);
+
+ if (table)
+ return table->check (g_type, type);
+
+ return FALSE;
+}
+
+GVariant *
+g_value_serialise (GValue *value,
+ const GVariantType *type)
+{
+ GTypeSerialiserTable *table = table_lookup (value->g_type);
+
+ if (table)
+ {
+ GVariant *result;
+
+ if ((result = table->serialise (value, type)) != NULL)
+ /* XXX this is a little bit wrong... */
+ return g_variant_ref_sink (result);
+ }
+
+ return NULL;
+}
+
+gboolean
+g_value_deserialise (GValue *value,
+ GVariant *variant)
+{
+ GTypeSerialiserTable *table = table_lookup (value->g_type);
+
+ if (table)
+ return table->deserialise (value, variant);
+
+ return FALSE;
+}
+
+void
+g_type_serialiser_register_static (GType type,
+ const GTypeSerialiserTable *table)
+{
+ g_type_set_qdata (type, table_quark (), (gpointer) table);
+}
+
+static gboolean
+check_byte (GType g_type,
+ const GVariantType *type)
+{
+ return g_variant_type_matches (type, G_VARIANT_TYPE_BYTE);
+}
+
+static gboolean
+check_boolean (GType g_type,
+ const GVariantType *type)
+{
+ return g_variant_type_matches (type, G_VARIANT_TYPE_BOOLEAN);
+}
+
+static gboolean
+check_number (GType g_type,
+ const GVariantType *type)
+{
+ switch (g_variant_type_get_class (type))
+ {
+ case G_VARIANT_TYPE_CLASS_INT16:
+ case G_VARIANT_TYPE_CLASS_UINT16:
+ case G_VARIANT_TYPE_CLASS_INT32:
+ case G_VARIANT_TYPE_CLASS_UINT32:
+ case G_VARIANT_TYPE_CLASS_INT64:
+ case G_VARIANT_TYPE_CLASS_UINT64:
+ case G_VARIANT_TYPE_CLASS_DOUBLE:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+static gboolean
+check_string (GType g_type,
+ const GVariantType *type)
+{
+ switch (g_variant_type_get_class (type))
+ {
+ case G_VARIANT_TYPE_CLASS_STRING:
+ case G_VARIANT_TYPE_CLASS_OBJECT_PATH:
+ case G_VARIANT_TYPE_CLASS_SIGNATURE:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+static GVariant *
+serialise_boolean (GValue *value,
+ const GVariantType *type)
+{
+ return g_variant_new_boolean (value->data[0].v_ulong);
+}
+
+static GVariant *
+serialise_byte (GValue *value,
+ const GVariantType *type)
+{
+ return g_variant_new_byte (value->data[0].v_ulong);
+}
+
+static GVariant *
+serialise_long0 (GValue *value,
+ const GVariantType *type)
+{
+ GVariantTypeClass class = g_variant_type_get_class (type);
+ gint64 integer;
+
+ g_assert (sizeof (gint) == 4);
+ g_assert (4 <= sizeof (glong) && sizeof (glong) <= 8);
+ g_assert (sizeof (gint64) == 8);
+
+ integer = value->data[0].v_long;
+
+ switch (class)
+ {
+ case G_VARIANT_TYPE_CLASS_INT16:
+ if (G_MININT16 <= integer && integer <= G_MAXINT16)
+ return g_variant_new_int16 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_UINT16:
+ if (0 <= integer && integer <= G_MAXUINT16)
+ return g_variant_new_uint16 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_INT32:
+ if (G_MININT32 <= integer && integer <= G_MAXINT32)
+ return g_variant_new_int32 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_UINT32:
+ if (0 <= integer && integer <= G_MAXUINT32)
+ return g_variant_new_uint32 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_INT64:
+ if (G_MININT64 <= integer && integer <= G_MAXINT64)
+ return g_variant_new_int64 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_UINT64:
+ if (0 <= integer && integer <= G_MAXUINT64)
+ return g_variant_new_uint64 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_DOUBLE:
+ return g_variant_new_double (integer);
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static GVariant *
+serialise_ulong0 (GValue *value,
+ const GVariantType *type)
+{
+ GVariantTypeClass class = g_variant_type_get_class (type);
+ guint64 integer;
+
+ g_assert (sizeof (gint) == 4);
+ g_assert (4 <= sizeof (glong) && sizeof (glong) <= 8);
+ g_assert (sizeof (gint64) == 8);
+
+ integer = value->data[0].v_ulong;
+
+ switch (class)
+ {
+ case G_VARIANT_TYPE_CLASS_INT16:
+ if (integer <= G_MAXINT16)
+ return g_variant_new_int16 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_UINT16:
+ if (integer <= G_MAXUINT16)
+ return g_variant_new_uint16 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_INT32:
+ if (integer <= G_MAXINT32)
+ return g_variant_new_int32 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_UINT32:
+ if (integer <= G_MAXUINT32)
+ return g_variant_new_uint32 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_INT64:
+ if (integer <= G_MAXINT64)
+ return g_variant_new_int64 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_UINT64:
+ if (integer <= G_MAXUINT64)
+ return g_variant_new_uint64 (integer);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_DOUBLE:
+ return g_variant_new_double (integer);
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static GVariant *
+serialise_floating (GValue *value,
+ const GVariantType *type)
+{
+ GVariantTypeClass class = g_variant_type_get_class (type);
+ gdouble floating;
+
+ if (value->g_type == G_TYPE_FLOAT)
+ floating = value->data[0].v_float;
+ else
+ floating = value->data[0].v_double;
+
+ switch (class)
+ {
+ case G_VARIANT_TYPE_CLASS_INT16:
+ if (G_MININT16 <= floating && floating <= G_MAXINT16)
+ return g_variant_new_int16 (floating);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_UINT16:
+ if (0 <= floating && floating <= G_MAXUINT16)
+ return g_variant_new_uint16 (floating);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_INT32:
+ if (G_MININT32 <= floating && floating <= G_MAXINT32)
+ return g_variant_new_int32 (floating);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_UINT32:
+ if (0 <= floating && floating <= G_MAXUINT32)
+ return g_variant_new_uint32 (floating);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_INT64:
+ if (G_MININT64 <= floating && floating <= G_MAXINT64)
+ return g_variant_new_int64 (floating);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_UINT64:
+ if (0 <= floating && floating <= G_MAXUINT64)
+ return g_variant_new_uint64 (floating);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_DOUBLE:
+ return g_variant_new_double (floating);
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static GVariant *
+serialise_string (GValue *value,
+ const GVariantType *type)
+{
+ const gchar *string = value->data[0].v_pointer;
+
+ switch (g_variant_type_get_class (type))
+ {
+ case G_VARIANT_TYPE_CLASS_STRING:
+ return g_variant_new_string (string);
+
+ case G_VARIANT_TYPE_CLASS_OBJECT_PATH:
+ if (g_variant_is_object_path (string))
+ return g_variant_new_object_path (string);
+ return NULL;
+
+ case G_VARIANT_TYPE_CLASS_SIGNATURE:
+ if (g_variant_is_signature (string))
+ return g_variant_new_signature (string);
+ return NULL;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static gboolean
+deserialise_boolean (GValue *value,
+ GVariant *variant)
+{
+ value->data[0].v_ulong = g_variant_get_boolean (variant);
+ return TRUE;
+}
+
+static gboolean
+deserialise_byte (GValue *value,
+ GVariant *variant)
+{
+ if (value->g_type == G_TYPE_CHAR)
+ value->data[0].v_long = (gchar) g_variant_get_byte (variant);
+ else /* G_TYPE_UCHAR */
+ value->data[0].v_ulong = g_variant_get_byte (variant);
+ return TRUE;
+}
+
+static gboolean
+deserialise_long0 (GValue *value,
+ GVariant *variant)
+{
+ gint64 integer;
+
+ switch (g_variant_get_type_class (variant))
+ {
+ case G_VARIANT_TYPE_CLASS_INT16:
+ integer = g_variant_get_int16 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_UINT16:
+ integer = g_variant_get_uint16 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_INT32:
+ integer = g_variant_get_int32 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_UINT32:
+ integer = g_variant_get_uint32 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_INT64:
+ integer = g_variant_get_int64 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_UINT64:
+ {
+ guint64 uinteger = g_variant_get_uint64 (variant);
+
+ if (uinteger > G_MAXINT64)
+ return FALSE;
+
+ integer = uinteger;
+ }
+ break;
+
+ case G_VARIANT_TYPE_CLASS_DOUBLE:
+ integer = g_variant_get_double (variant);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ if ((value->g_type == G_TYPE_UINT &&
+ (integer > G_MAXINT || integer < G_MININT)) ||
+ (value->g_type == G_TYPE_ULONG &&
+ (integer > G_MAXLONG || integer < G_MINLONG)))
+ return FALSE;
+
+ value->data[0].v_long = integer;
+
+ return TRUE;
+}
+
+static gboolean
+deserialise_ulong0 (GValue *value,
+ GVariant *variant)
+{
+ guint64 integer;
+
+ switch (g_variant_get_type_class (variant))
+ {
+ case G_VARIANT_TYPE_CLASS_INT16:
+ integer = g_variant_get_int16 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_UINT16:
+ integer = g_variant_get_uint16 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_INT32:
+ integer = g_variant_get_int32 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_UINT32:
+ integer = g_variant_get_uint32 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_INT64:
+ {
+ gint64 sinteger = g_variant_get_int64 (variant);
+
+ if (sinteger < 0)
+ return FALSE;
+
+ integer = sinteger;
+ }
+ break;
+
+ case G_VARIANT_TYPE_CLASS_UINT64:
+ integer = g_variant_get_uint64 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_DOUBLE:
+ integer = g_variant_get_double (variant);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ if ((value->g_type == G_TYPE_UINT && integer > G_MAXUINT) ||
+ (value->g_type == G_TYPE_ULONG && integer > G_MAXULONG))
+ return FALSE;
+
+ value->data[0].v_ulong = integer;
+
+ return TRUE;
+}
+
+static gboolean
+deserialise_floating (GValue *value,
+ GVariant *variant)
+{
+ gdouble floating;
+
+ switch (g_variant_get_type_class (variant))
+ {
+ case G_VARIANT_TYPE_CLASS_INT16:
+ floating = g_variant_get_int16 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_UINT16:
+ floating = g_variant_get_uint16 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_INT32:
+ floating = g_variant_get_int32 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_UINT32:
+ floating = g_variant_get_uint32 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_INT64:
+ floating = g_variant_get_int64 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_UINT64:
+ floating = g_variant_get_uint64 (variant);
+ break;
+
+ case G_VARIANT_TYPE_CLASS_DOUBLE:
+ floating = g_variant_get_double (variant);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (value->g_type == G_TYPE_FLOAT)
+ value->data[0].v_float = floating;
+ else
+ value->data[0].v_double = floating;
+
+ return TRUE;
+}
+
+static gboolean
+deserialise_string (GValue *value,
+ GVariant *variant)
+{
+ g_value_set_string (value, g_variant_get_string (variant, NULL));
+
+ return TRUE;
+}
+
+void
+g_type_serialiser_init ()
+{
+ /* boolean */
+ {
+ static const GTypeSerialiserTable serialiser_table = {
+ check_boolean,
+ serialise_boolean,
+ deserialise_boolean
+ };
+ g_type_serialiser_register_static (G_TYPE_BOOLEAN, &serialiser_table);
+ }
+
+ /* char/uchar */
+ {
+ static const GTypeSerialiserTable serialiser_table = {
+ check_byte,
+ serialise_byte,
+ deserialise_byte
+ };
+ g_type_serialiser_register_static (G_TYPE_CHAR, &serialiser_table);
+ g_type_serialiser_register_static (G_TYPE_UCHAR, &serialiser_table);
+ }
+
+ /* signed integers */
+ {
+ static const GTypeSerialiserTable serialiser_table = {
+ check_number,
+ serialise_long0,
+ deserialise_long0
+ };
+ g_type_serialiser_register_static (G_TYPE_INT, &serialiser_table);
+ g_type_serialiser_register_static (G_TYPE_LONG, &serialiser_table);
+ g_type_serialiser_register_static (G_TYPE_INT64, &serialiser_table);
+ }
+
+ /* unsigned integers */
+ {
+ static const GTypeSerialiserTable serialiser_table = {
+ check_number,
+ serialise_ulong0,
+ deserialise_ulong0
+ };
+ g_type_serialiser_register_static (G_TYPE_UINT, &serialiser_table);
+ g_type_serialiser_register_static (G_TYPE_ULONG, &serialiser_table);
+ g_type_serialiser_register_static (G_TYPE_UINT64, &serialiser_table);
+ }
+
+ /* floating point */
+ {
+ static const GTypeSerialiserTable serialiser_table = {
+ check_number,
+ serialise_floating,
+ deserialise_floating
+ };
+ g_type_serialiser_register_static (G_TYPE_DOUBLE, &serialiser_table);
+ g_type_serialiser_register_static (G_TYPE_FLOAT, &serialiser_table);
+ }
+
+ /* strings */
+ {
+ static const GTypeSerialiserTable serialiser_table = {
+ check_string,
+ serialise_string,
+ deserialise_string
+ };
+ g_type_serialiser_register_static (G_TYPE_STRING, &serialiser_table);
+ }
+}
+
+#define __G_TYPE_SERIALISER_C__
+#include "gobjectaliasdef.c"
diff --git a/gobject/gtypeserialiser.h b/gobject/gtypeserialiser.h
new file mode 100644
index 0000000..2e23d18
--- /dev/null
+++ b/gobject/gtypeserialiser.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2009 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * licence, or (at your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ */
+
+#ifndef __G_TYPE_SERIALISER_H__
+#define __G_TYPE_SERIALISER_H__
+
+#include "gtype.h"
+
+G_BEGIN_DECLS
+
+struct _GTypeSerialiserTable
+{
+ gboolean (*check) (GType g_type,
+ const GVariantType *type);
+ GVariant * (*serialise) (GValue *value,
+ const GVariantType *type);
+ gboolean (*deserialise) (GValue *value,
+ GVariant *variant);
+};
+
+typedef struct _GTypeSerialiserTable GTypeSerialiserTable;
+
+gboolean g_type_serialiser_check (GType g_type,
+ const GVariantType *type);
+GVariant * g_value_serialise (GValue *value,
+ const GVariantType *type);
+gboolean g_value_deserialise (GValue *value,
+ GVariant *variant);
+void g_type_serialiser_register_static (GType type,
+ const GTypeSerialiserTable *table);
+G_END_DECLS
+
+#endif /* __G_TYPE_SERIALISER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]