OLD | NEW |
1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ | 1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ |
2 /* vim:set et sts=4: */ | 2 /* vim:set et sts=4: */ |
3 /* ibus - The Input Bus | 3 /* ibus - The Input Bus |
4 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com> | 4 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com> |
5 * Copyright (C) 2008-2010 Red Hat, Inc. | 5 * Copyright (C) 2008-2010 Red Hat, Inc. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Lesser General Public | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 g_datalist_init (&serializable->priv->attachments); | 117 g_datalist_init (&serializable->priv->attachments); |
118 } | 118 } |
119 | 119 |
120 static void | 120 static void |
121 ibus_serializable_destroy (IBusSerializable *serializable) | 121 ibus_serializable_destroy (IBusSerializable *serializable) |
122 { | 122 { |
123 g_datalist_clear (&serializable->priv->attachments); | 123 g_datalist_clear (&serializable->priv->attachments); |
124 parent_class->destroy (IBUS_OBJECT (serializable)); | 124 parent_class->destroy (IBUS_OBJECT (serializable)); |
125 } | 125 } |
126 | 126 |
127 static GValue * | |
128 ibus_g_value_dup (const GValue *value) | |
129 { | |
130 GValue *new_value; | |
131 | |
132 new_value = g_slice_new0 (GValue); | |
133 g_value_init (new_value, G_VALUE_TYPE (value)); | |
134 g_value_copy (value, new_value); | |
135 | |
136 return new_value; | |
137 } | |
138 | |
139 static void | |
140 ibus_g_value_free (GValue *value) | |
141 { | |
142 g_value_unset (value); | |
143 g_slice_free (GValue, value); | |
144 } | |
145 | |
146 static GVariant * | |
147 _g_value_serialize (GValue *value) | |
148 { | |
149 GType type; | |
150 | |
151 type = G_VALUE_TYPE (value); | |
152 g_return_val_if_fail (type != G_TYPE_INVALID, FALSE); | |
153 | |
154 if (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE)) { | |
155 IBusSerializable *object; | |
156 object = IBUS_SERIALIZABLE (g_value_get_object (value)); | |
157 return ibus_serializable_serialize (object); | |
158 } | |
159 | |
160 typedef const gchar *gstring; | |
161 switch (type) { | |
162 #define CASE_ENTRY(TYPE, _type, signature) \ | |
163 case G_TYPE_##TYPE: \ | |
164 { \ | |
165 g##_type v; \ | |
166 v = g_value_get_##_type (value); \ | |
167 return g_variant_new (signature, v); \ | |
168 } | |
169 CASE_ENTRY(CHAR, char, "y"); | |
170 CASE_ENTRY(BOOLEAN, boolean, "b"); | |
171 CASE_ENTRY(INT, int, "i"); | |
172 CASE_ENTRY(UINT, uint, "u"); | |
173 CASE_ENTRY(INT64, int64, "x"); | |
174 CASE_ENTRY(UINT64, uint64, "t"); | |
175 CASE_ENTRY(FLOAT, float, "d"); | |
176 CASE_ENTRY(DOUBLE, double, "d"); | |
177 CASE_ENTRY(STRING, string, "s"); | |
178 #undef CASE_ENTRY | |
179 } | |
180 | |
181 g_assert_not_reached (); | |
182 } | |
183 | |
184 static GValue * | |
185 _g_value_deserialize (GVariant *variant) | |
186 { | |
187 GValue *value = NULL; | |
188 const GVariantType *type; | |
189 | |
190 type = g_variant_get_type (variant); | |
191 if (type == G_VARIANT_TYPE_TUPLE) { | |
192 IBusSerializable *object; | |
193 object = ibus_serializable_deserialize (variant); | |
194 value = g_slice_new0 (GValue); | |
195 g_value_init (value, G_OBJECT_TYPE (object)); | |
196 g_value_take_object (value, object); | |
197 return value; | |
198 } | |
199 | |
200 typedef gchar *gstring; | |
201 #define IF_ENTRY(TYPE, _type, signature) \ | |
202 if (g_variant_type_equal(type, G_VARIANT_TYPE_##TYPE)) { \ | |
203 g##_type v; \ | |
204 g_variant_get (variant, signature, &v); \ | |
205 value = g_slice_new0 (GValue); \ | |
206 g_value_init (value, G_TYPE_##TYPE); \ | |
207 g_value_set_##_type (value, v); \ | |
208 return value; \ | |
209 } | |
210 #define G_VARIANT_TYPE_CHAR G_VARIANT_TYPE_BYTE | |
211 IF_ENTRY(CHAR, char, "y"); | |
212 #undef G_VARIANT_TYPE_CHAR | |
213 IF_ENTRY(BOOLEAN, boolean, "b"); | |
214 #define G_VARIANT_TYPE_INT G_VARIANT_TYPE_INT32 | |
215 #define G_VARIANT_TYPE_UINT G_VARIANT_TYPE_UINT32 | |
216 IF_ENTRY(INT, int, "i"); | |
217 IF_ENTRY(UINT, uint, "u"); | |
218 #undef G_VARIANT_TYPE_INT | |
219 #undef G_VARIANT_TYPE_UINT | |
220 IF_ENTRY(INT64, int64, "x"); | |
221 IF_ENTRY(UINT64, uint64, "t"); | |
222 IF_ENTRY(DOUBLE, double, "d"); | |
223 IF_ENTRY(STRING, string, "s"); | |
224 | |
225 g_return_val_if_reached (NULL); | |
226 } | |
227 | |
228 static void | 127 static void |
229 _serialize_cb (GQuark key, | 128 _serialize_cb (GQuark key, |
230 GValue *value, | 129 GVariant *value, |
231 GVariantBuilder *array) | 130 GVariantBuilder *array) |
232 { | 131 { |
233 g_variant_builder_add (array, "{sv}", | 132 g_variant_builder_add (array, "{sv}", |
234 g_quark_to_string (key), _g_value_serialize (value)); | 133 g_quark_to_string (key), g_variant_new_variant (value)); |
235 } | 134 } |
236 | 135 |
237 static gboolean | 136 static gboolean |
238 ibus_serializable_real_serialize (IBusSerializable *serializable, | 137 ibus_serializable_real_serialize (IBusSerializable *serializable, |
239 GVariantBuilder *builder) | 138 GVariantBuilder *builder) |
240 { | 139 { |
241 GVariantBuilder array; | 140 GVariantBuilder array; |
242 g_variant_builder_init (&array, G_VARIANT_TYPE ("a{sv}")); | 141 g_variant_builder_init (&array, G_VARIANT_TYPE ("a{sv}")); |
243 | 142 |
244 g_datalist_foreach (&serializable->priv->attachments, | 143 g_datalist_foreach (&serializable->priv->attachments, |
245 (GDataForeachFunc) _serialize_cb, | 144 (GDataForeachFunc) _serialize_cb, |
246 &array); | 145 &array); |
247 g_variant_builder_add (builder, "a{sv}", &array); | 146 g_variant_builder_add (builder, "a{sv}", &array); |
248 return TRUE; | 147 return TRUE; |
249 } | 148 } |
250 | 149 |
251 static gint | 150 static gint |
252 ibus_serializable_real_deserialize (IBusSerializable *object, | 151 ibus_serializable_real_deserialize (IBusSerializable *object, |
253 GVariant *variant) | 152 GVariant *variant) |
254 { | 153 { |
255 const gchar *key; | 154 const gchar *key; |
256 GVariant *value; | 155 GVariant *value; |
257 GVariantIter *iter = NULL; | 156 GVariantIter *iter = NULL; |
258 g_variant_get_child (variant, 1, "a{sv}", &iter); | 157 g_variant_get_child (variant, 1, "a{sv}", &iter); |
259 while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) { | 158 while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) { |
260 ibus_serializable_set_attachment (object, key, _g_value_deserialize (val
ue)); | 159 GVariant *attachment = g_variant_get_variant (value); |
| 160 ibus_serializable_set_attachment (object, |
| 161 key, |
| 162 attachment); |
| 163 g_variant_unref (attachment); |
| 164 g_variant_unref (value); |
261 } | 165 } |
262 g_variant_iter_free (iter); | 166 g_variant_iter_free (iter); |
263 return 2; | 167 return 2; |
264 } | 168 } |
265 | 169 |
266 static void | 170 static void |
267 _copy_cb (GQuark key, | 171 _copy_cb (GQuark key, |
268 GValue *value, | 172 GVariant *value, |
269 GData **datalist) | 173 GData **datalist) |
270 { | 174 { |
271 g_datalist_id_set_data_full (datalist, | 175 g_datalist_id_set_data_full (datalist, |
272 key, | 176 key, |
273 ibus_g_value_dup (value), | 177 g_variant_ref (value), |
274 (GDestroyNotify) ibus_g_value_free); | 178 (GDestroyNotify) g_variant_unref); |
275 } | 179 } |
276 | 180 |
277 static gboolean | 181 static gboolean |
278 ibus_serializable_real_copy (IBusSerializable *dest, | 182 ibus_serializable_real_copy (IBusSerializable *dest, |
279 const IBusSerializable *src) | 183 const IBusSerializable *src) |
280 { | 184 { |
281 IBusSerializablePrivate *src_priv; | 185 IBusSerializablePrivate *src_priv; |
282 IBusSerializablePrivate *dest_priv; | 186 IBusSerializablePrivate *dest_priv; |
283 src_priv = IBUS_SERIALIZABLE_GET_PRIVATE (src); | 187 src_priv = IBUS_SERIALIZABLE_GET_PRIVATE (src); |
284 dest_priv = IBUS_SERIALIZABLE_GET_PRIVATE (dest); | 188 dest_priv = IBUS_SERIALIZABLE_GET_PRIVATE (dest); |
285 | 189 |
286 g_datalist_foreach (&src_priv->attachments, | 190 g_datalist_foreach (&src_priv->attachments, |
287 (GDataForeachFunc) _copy_cb, | 191 (GDataForeachFunc) _copy_cb, |
288 &dest_priv->attachments); | 192 &dest_priv->attachments); |
289 return TRUE; | 193 return TRUE; |
290 } | 194 } |
291 | 195 |
292 gboolean | 196 void |
293 ibus_serializable_set_qattachment (IBusSerializable *object, | 197 ibus_serializable_set_qattachment (IBusSerializable *serializable, |
294 GQuark key, | 198 GQuark key, |
295 const GValue *value) | 199 GVariant *value) |
296 { | 200 { |
297 g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), FALSE); | 201 g_return_if_fail (IBUS_IS_SERIALIZABLE (serializable)); |
298 g_return_val_if_fail (key != 0, FALSE); | 202 g_return_if_fail (key != 0); |
299 g_return_val_if_fail (G_IS_VALUE (value), FALSE); | |
300 | 203 |
301 IBusSerializablePrivate *priv; | 204 g_datalist_id_set_data_full (&serializable->priv->attachments, |
302 priv = IBUS_SERIALIZABLE_GET_PRIVATE (object); | 205 key, |
303 | 206 value ? g_variant_ref_sink (value) : NULL, |
304 GType type = G_VALUE_TYPE (value); | 207 (GDestroyNotify) g_variant_unref); |
305 | |
306 switch (type) { | |
307 case G_TYPE_CHAR: | |
308 case G_TYPE_INT: | |
309 case G_TYPE_INT64: | |
310 case G_TYPE_UINT: | |
311 case G_TYPE_UINT64: | |
312 case G_TYPE_BOOLEAN: | |
313 case G_TYPE_DOUBLE: | |
314 case G_TYPE_FLOAT: | |
315 case G_TYPE_STRING: | |
316 g_datalist_id_set_data_full (&priv->attachments, | |
317 key, | |
318 ibus_g_value_dup (value), | |
319 (GDestroyNotify) ibus_g_value_free); | |
320 return TRUE; | |
321 } | |
322 | |
323 if (g_type_is_a (type, IBUS_TYPE_SERIALIZABLE)) { | |
324 g_datalist_id_set_data_full (&priv->attachments, | |
325 key, | |
326 ibus_g_value_dup (value), | |
327 (GDestroyNotify) ibus_g_value_free); | |
328 return TRUE; | |
329 } | |
330 | |
331 g_warning ("The value of %s is not support serializing", g_type_name (type))
; | |
332 return FALSE; | |
333 } | 208 } |
334 | 209 |
335 const GValue * | 210 GVariant * |
336 ibus_serializable_get_qattachment (IBusSerializable *serializable, | 211 ibus_serializable_get_qattachment (IBusSerializable *serializable, |
337 GQuark key) | 212 GQuark key) |
338 { | 213 { |
339 | 214 |
340 g_return_val_if_fail (IBUS_IS_SERIALIZABLE (serializable), NULL); | 215 g_return_val_if_fail (IBUS_IS_SERIALIZABLE (serializable), NULL); |
341 g_return_val_if_fail (key != 0, NULL); | 216 g_return_val_if_fail (key != 0, NULL); |
342 | 217 |
343 return (const GValue *) g_datalist_id_get_data (&serializable->priv->attachm
ents, key); | 218 return (GVariant *) g_datalist_id_get_data ( |
| 219 &serializable->priv->attachments, key); |
344 } | 220 } |
345 | 221 |
346 void | 222 void |
347 ibus_serializable_remove_qattachment (IBusSerializable *serializable, | 223 ibus_serializable_remove_qattachment (IBusSerializable *serializable, |
348 GQuark key) | 224 GQuark key) |
349 { | 225 { |
350 | 226 |
351 g_return_if_fail (IBUS_IS_SERIALIZABLE (serializable)); | 227 g_return_if_fail (IBUS_IS_SERIALIZABLE (serializable)); |
352 g_return_if_fail (key != 0); | 228 g_return_if_fail (key != 0); |
353 | 229 |
354 g_datalist_id_remove_no_notify (&serializable->priv->attachments, key); | 230 g_datalist_id_set_data (&serializable->priv->attachments, key, NULL); |
355 } | 231 } |
356 | 232 |
357 IBusSerializable * | 233 IBusSerializable * |
358 ibus_serializable_copy (IBusSerializable *object) | 234 ibus_serializable_copy (IBusSerializable *object) |
359 { | 235 { |
360 g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), NULL); | 236 g_return_val_if_fail (IBUS_IS_SERIALIZABLE (object), NULL); |
361 | 237 |
362 GType type; | 238 GType type; |
363 IBusSerializable *new_object; | 239 IBusSerializable *new_object; |
364 | 240 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 | 294 |
419 gint retval = IBUS_SERIALIZABLE_GET_CLASS (object)->deserialize (object, var
); | 295 gint retval = IBUS_SERIALIZABLE_GET_CLASS (object)->deserialize (object, var
); |
420 g_variant_unref (var); | 296 g_variant_unref (var); |
421 if (retval) | 297 if (retval) |
422 return object; | 298 return object; |
423 | 299 |
424 g_object_unref (object); | 300 g_object_unref (object); |
425 g_return_val_if_reached (NULL); | 301 g_return_val_if_reached (NULL); |
426 } | 302 } |
427 | 303 |
OLD | NEW |