1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* ibus - The Input Bus
4 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
5 * Copyright (C) 2008-2010 Red Hat, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
22 #include "ibusinternal.h"
23 #include "ibusserializable.h"
25 #define IBUS_SERIALIZABLE_GET_PRIVATE(o) \
26 (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_SERIALIZABLE, IBusSerializablePrivate))
32 struct _IBusSerializablePrivate {
36 // static guint object_signals[LAST_SIGNAL] = { 0 };
38 /* functions prototype */
39 static void ibus_serializable_base_init (IBusSerializableClass *class);
40 static void ibus_serializable_base_fini (IBusSerializableClass *class);
41 static void ibus_serializable_class_init (IBusSerializableClass *class);
42 static void ibus_serializable_init (IBusSerializable *object);
43 static void ibus_serializable_destroy (IBusSerializable *object);
44 static gboolean ibus_serializable_real_serialize (IBusSerializable *object,
45 GVariantBuilder *builder);
46 static gint ibus_serializable_real_deserialize (IBusSerializable *object,
48 static gboolean ibus_serializable_real_copy (IBusSerializable *dest,
49 const IBusSerializable *src);
51 static IBusObjectClass *parent_class = NULL;
54 ibus_serializable_get_type (void)
56 static GType type = 0;
58 static const GTypeInfo type_info = {
59 sizeof (IBusSerializableClass),
60 (GBaseInitFunc) ibus_serializable_base_init,
61 (GBaseFinalizeFunc) ibus_serializable_base_fini,
62 (GClassInitFunc) ibus_serializable_class_init,
63 NULL, /* class finialize */
64 NULL, /* class data */
65 sizeof (IBusSerializable),
67 (GInstanceInitFunc) ibus_serializable_init,
71 type = g_type_register_static (IBUS_TYPE_OBJECT,
81 ibus_serializable_new (void)
83 return IBUS_SERIALIZABLE (g_object_new (IBUS_TYPE_SERIALIZABLE, NULL));
87 ibus_serializable_base_init (IBusSerializableClass *class)
92 ibus_serializable_base_fini (IBusSerializableClass *class)
97 ibus_serializable_class_init (IBusSerializableClass *class)
99 IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
101 parent_class = (IBusObjectClass *) g_type_class_peek_parent (class);
103 g_type_class_add_private (class, sizeof (IBusSerializablePrivate));
105 object_class->destroy = (IBusObjectDestroyFunc) ibus_serializable_destroy;
107 class->serialize = ibus_serializable_real_serialize;
108 class->deserialize = ibus_serializable_real_deserialize;
109 class->copy = ibus_serializable_real_copy;
113 ibus_serializable_init (IBusSerializable *serializable)
115 serializable->priv = IBUS_SERIALIZABLE_GET_PRIVATE (serializable);
116 serializable->priv->attachments = NULL;
117 g_datalist_init (&serializable->priv->attachments);
121 ibus_serializable_destroy (IBusSerializable *serializable)
123 g_datalist_clear (&serializable->priv->attachments);
124 parent_class->destroy (IBUS_OBJECT (serializable));
128 _serialize_cb (GQuark key,
130 GVariantBuilder *array)
132 g_variant_builder_add (array, "{sv}",
133 g_quark_to_string (key), g_variant_new_variant (value));
137 ibus_serializable_real_serialize (IBusSerializable *serializable,
138 GVariantBuilder *builder)
140 GVariantBuilder array;
141 g_variant_builder_init (&array, G_VARIANT_TYPE ("a{sv}"));
143 g_datalist_foreach (&serializable->priv->attachments,
144 (GDataForeachFunc) _serialize_cb,
146 g_variant_builder_add (builder, "a{sv}", &array);
151 ibus_serializable_real_deserialize (IBusSerializable *object,
156 GVariantIter *iter = NULL;
157 g_variant_get_child (variant, 1, "a{sv}", &iter);
158 while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
159 GVariant *attachment = g_variant_get_variant (value);
160 ibus_serializable_set_attachment (object,
163 g_variant_unref (attachment);
165 g_variant_iter_free (iter);
170 _copy_cb (GQuark key,
174 g_datalist_id_set_data_full (datalist,
176 g_variant_ref (value),
177 (GDestroyNotify) g_variant_unref);
181 ibus_serializable_real_copy (IBusSerializable *dest,
182 const IBusSerializable *src)
184 IBusSerializablePrivate *src_priv;
185 IBusSerializablePrivate *dest_priv;
186 src_priv = IBUS_SERIALIZABLE_GET_PRIVATE (src);
187 dest_priv = IBUS_SERIALIZABLE_GET_PRIVATE (dest);
189 g_datalist_foreach (&src_priv->attachments,
190 (GDataForeachFunc) _copy_cb,
191 &dest_priv->attachments);
196 ibus_serializable_set_qattachment (IBusSerializable *serializable,
200 g_return_if_fail (IBUS_IS_SERIALIZABLE (serializable));
201 g_return_if_fail (key != 0);
203 g_datalist_id_set_data_full (&serializable->priv->attachments,
205 value ? g_variant_ref_sink (value) : NULL,
206 (GDestroyNotify) g_variant_unref);
210 ibus_serializable_get_qattachment (IBusSerializable *serializable,
214 g_return_val_if_fail (IBUS_IS_SERIALIZABLE (serializable), NULL);
215 g_return_val_if_fail (key != 0, NULL);
217 return (GVariant *) g_datalist_id_get_data (
218 &serializable->priv->attachments, key);
222 ibus_serializable_remove_qattachment (IBusSerializable *serializable,
226 g_return_if_fail (IBUS_IS_SERIALIZABLE (serializable));
227 g_return_if_fail (key != 0);
229 g_datalist_id_set_data (&serializable->priv->attachments, key, NULL);
233 ibus_serializable_copy (IBusSerializable *object)
235 g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), NULL);
238 IBusSerializable *new_object;
240 type = G_OBJECT_TYPE (object);
242 new_object = g_object_new (type, NULL);
243 g_return_val_if_fail (new_object != NULL, NULL);
245 if (IBUS_SERIALIZABLE_GET_CLASS (new_object)->copy (new_object, object)) {
249 g_object_unref (new_object);
250 g_return_val_if_reached (NULL);
254 ibus_serializable_serialize (IBusSerializable *object)
256 g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), FALSE);
259 GVariantBuilder builder;
260 g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
262 g_variant_builder_add (&builder, "s", g_type_name (G_OBJECT_TYPE (object)));
263 retval = IBUS_SERIALIZABLE_GET_CLASS (object)->serialize (object, &builder);
266 return g_variant_builder_end (&builder);
270 ibus_serializable_deserialize (GVariant *variant)
272 g_return_val_if_fail (variant != NULL, NULL);
274 GVariant *var = NULL;
275 switch (g_variant_classify (variant)) {
276 case G_VARIANT_CLASS_VARIANT:
277 var = g_variant_get_variant (variant);
279 case G_VARIANT_CLASS_TUPLE:
280 var = g_variant_ref (variant);
283 g_return_val_if_reached (NULL);
286 gchar *type_name = NULL;
287 g_variant_get_child (var, 0, "&s", &type_name);
288 GType type = g_type_from_name (type_name);
290 g_return_val_if_fail (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE), NULL);
292 IBusSerializable *object = g_object_new (type, NULL);
294 gint retval = IBUS_SERIALIZABLE_GET_CLASS (object)->deserialize (object, var);
295 g_variant_unref (var);
299 g_object_unref (object);
300 g_return_val_if_reached (NULL);