summaryrefslogtreecommitdiff
path: root/json-glib/json-gboxed.c
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@linux.intel.com>2009-10-27 20:49:09 +0000
committerEmmanuele Bassi <ebassi@linux.intel.com>2009-10-27 20:49:09 +0000
commitc176f70e593c9cfb4901cd9f27ce54b8aa7152f2 (patch)
tree45a93b95e4ff88d36af3fa3b838b8484b0365972 /json-glib/json-gboxed.c
parent373fa3d9b73391b38620fbd9ce9b69f358e5f4c8 (diff)
downloadjson-glib-c176f70e593c9cfb4901cd9f27ce54b8aa7152f2.tar.gz
build: Split out GBoxed and Serializable
The json-gobject.c is getting pretty crowded; we should split out the JsonBoxed API and the JsonSerialized implementation into their separate source files.
Diffstat (limited to 'json-glib/json-gboxed.c')
-rw-r--r--json-glib/json-gboxed.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/json-glib/json-gboxed.c b/json-glib/json-gboxed.c
new file mode 100644
index 0000000..6dd85c4
--- /dev/null
+++ b/json-glib/json-gboxed.c
@@ -0,0 +1,275 @@
+/* json-gboxed.c - JSON GBoxed integration
+ *
+ * This file is part of JSON-GLib
+ *
+ * Copyright (C) 2007 OpenedHand Ltd.
+ * Copyright (C) 2009 Intel Corp.
+ *
+ * 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.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Author:
+ * Emmanuele Bassi <ebassi@linux.intel.com>
+ */
+
+/**
+ * SECTION:json-gboxed
+ * @short_description: Serialize and deserialize GBoxed types
+ *
+ * FIXME
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "json-types-private.h"
+#include "json-gobject.h"
+
+typedef struct _BoxedTransform BoxedTransform;
+
+struct _BoxedTransform
+{
+ GType boxed_type;
+ gint node_type;
+
+ JsonBoxedSerializeFunc serialize;
+ JsonBoxedDeserializeFunc deserialize;
+};
+
+G_LOCK_DEFINE_STATIC (boxed_transforms);
+static GSList *boxed_transforms = NULL;
+
+static gint
+boxed_transforms_cmp (gconstpointer a,
+ gconstpointer b)
+{
+ const BoxedTransform *ta = a;
+ const BoxedTransform *tb = b;
+
+ return tb->boxed_type - ta->boxed_type;
+}
+
+static gint
+boxed_transforms_find (gconstpointer a,
+ gconstpointer b)
+{
+ const BoxedTransform *haystack = a;
+ const BoxedTransform *needle = b;
+
+ if (needle->node_type != -1)
+ return (haystack->boxed_type == needle->boxed_type &&
+ haystack->node_type == needle->node_type) ? 0 : 1;
+ else
+ return (haystack->boxed_type == needle->boxed_type) ? 0 : 1;
+}
+
+static BoxedTransform *
+lookup_boxed_transform (GType gboxed_type,
+ JsonNodeType node_type)
+{
+ BoxedTransform lookup;
+ GSList *t;
+
+ lookup.boxed_type = gboxed_type;
+ lookup.node_type = node_type;
+
+ t = g_slist_find_custom (boxed_transforms, &lookup, boxed_transforms_find);
+ if (t == NULL)
+ return NULL;
+
+ return t->data;
+}
+
+/**
+ * json_boxed_register_transform_func:
+ * @gboxed_type: a boxed type
+ * @node_type: a node type
+ * @serialize_func: (allow-none): serialization function for @boxed_type
+ * into a #JsonNode of type @node_type; can be %NULL if @deserialize_func
+ * is not %NULL
+ * @deserialize_func: (allow-none): deserialization function for @boxed_type
+ * from a #JsonNode of type @node_type; can be %NULL if @serialize_func
+ * is not %NULL
+ *
+ * Registers a serialization and deserialization functions for a #GBoxed
+ * of type @gboxed_type to and from a #JsonNode of type @node_type
+ *
+ * Since: 0.10
+ */
+void
+json_boxed_register_transform_func (GType gboxed_type,
+ JsonNodeType node_type,
+ JsonBoxedSerializeFunc serialize_func,
+ JsonBoxedDeserializeFunc deserialize_func)
+{
+ BoxedTransform *t;
+
+ g_return_if_fail (G_TYPE_IS_BOXED (gboxed_type));
+ g_return_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE);
+
+ if (serialize_func == NULL)
+ g_return_if_fail (deserialize_func != NULL);
+
+ if (deserialize_func == NULL)
+ g_return_if_fail (serialize_func != NULL);
+
+ G_LOCK (boxed_transforms);
+
+ t = lookup_boxed_transform (gboxed_type, node_type);
+ if (t == NULL)
+ {
+ t = g_slice_new (BoxedTransform);
+
+ t->boxed_type = gboxed_type;
+ t->node_type = node_type;
+ t->serialize = serialize_func;
+ t->deserialize = deserialize_func;
+
+ boxed_transforms = g_slist_insert_sorted (boxed_transforms, t,
+ boxed_transforms_cmp);
+ }
+ else
+ g_warning ("A transformation for the boxed type %s into "
+ "JSON nodes of type %s already exists",
+ g_type_name (gboxed_type),
+ json_node_type_get_name (node_type));
+
+ G_UNLOCK (boxed_transforms);
+}
+
+/**
+ * json_boxed_can_serialize:
+ * @gboxed_type: a boxed type
+ * @node_type: (out): the #JsonNode type to which the boxed type can be
+ * deserialized into
+ *
+ * Checks whether it is possible to serialize a #GBoxed of
+ * type @gboxed_type into a #JsonNode of type @node_type
+ *
+ * Return value: %TRUE if the type can be serialized, %FALSE otherwise
+ *
+ * Since: 0.10
+ */
+gboolean
+json_boxed_can_serialize (GType gboxed_type,
+ JsonNodeType *node_type)
+{
+ BoxedTransform *t;
+
+ g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, FALSE);
+
+ t = lookup_boxed_transform (gboxed_type, -1);
+ if (t != NULL && t->serialize != NULL)
+ {
+ if (node_type)
+ *node_type = t->node_type;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * json_boxed_can_deserialize:
+ * @gboxed_type: a boxed type
+ * @node_type: a #JsonNode type
+ *
+ * Checks whether it is possible to deserialize a #GBoxed of
+ * type @gboxed_type from a #JsonNode of type @node_type
+ *
+ * Return value: %TRUE if the type can be deserialized, %FALSE otherwise
+ *
+ * Since: 0.10
+ */
+gboolean
+json_boxed_can_deserialize (GType gboxed_type,
+ JsonNodeType node_type)
+{
+ BoxedTransform *t;
+
+ g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, FALSE);
+
+ t = lookup_boxed_transform (gboxed_type, node_type);
+ if (t != NULL && t->deserialize != NULL)
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * json_boxed_serialize:
+ * @gboxed_type: a boxed type
+ * @node_type: a #JsonNode type
+ * @boxed: a pointer to a #GBoxed of type @gboxed_type
+ *
+ * Serializes @boxed, a pointer to a #GBoxed of type @gboxed_type,
+ * into a #JsonNode of type @node_type
+ *
+ * Return value: a #JsonNode with the serialization of the boxed
+ * type, or %NULL if serialization either failed or was not
+ * possible
+ *
+ * Since: 0.10
+ */
+JsonNode *
+json_boxed_serialize (GType gboxed_type,
+ JsonNodeType node_type,
+ gconstpointer boxed)
+{
+ BoxedTransform *t;
+
+ g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, NULL);
+ g_return_val_if_fail (boxed != NULL, NULL);
+
+ t = lookup_boxed_transform (gboxed_type, node_type);
+ if (t != NULL && t->serialize != NULL)
+ return t->serialize (boxed);
+
+ return NULL;
+}
+
+/**
+ * json_boxed_serialize:
+ * @gboxed_type: a boxed type
+ * @node: a #JsonNode
+ *
+ * Deserializes @node into @boxed, a pointer to a #GBoxed of type
+ * @gboxed_type
+ *
+ * Since: 0.10
+ */
+gpointer
+json_boxed_deserialize (GType gboxed_type,
+ JsonNode *node)
+{
+ JsonNodeType node_type;
+ BoxedTransform *t;
+
+ g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), NULL);
+ g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, NULL);
+ g_return_val_if_fail (node != NULL, NULL);
+
+ node_type = json_node_get_node_type (node);
+
+ t = lookup_boxed_transform (gboxed_type, node_type);
+ if (t != NULL && t->deserialize != NULL)
+ return t->deserialize (node);
+
+ return NULL;
+}