|
1 /* -*- mode: C; c-file-style: "gnu" -*- */ |
|
2 /* dbus-gvalue.c GValue to-from DBusMessageIter |
|
3 * |
|
4 * Copyright (C) 2004 Ximian, Inc. |
|
5 * Copyright (C) 2005 Red Hat, Inc. |
|
6 * Portion Copyright © 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
7 * Licensed under the Academic Free License version 2.1 |
|
8 * |
|
9 * This program is free software; you can redistribute it and/or modify |
|
10 * it under the terms of the GNU General Public License as published by |
|
11 * the Free Software Foundation; either version 2 of the License, or |
|
12 * (at your option) any later version. |
|
13 * |
|
14 * This program is distributed in the hope that it will be useful, |
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
17 * GNU General Public License for more details. |
|
18 * |
|
19 * You should have received a copy of the GNU General Public License |
|
20 * along with this program; if not, write to the Free Software |
|
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
22 * |
|
23 */ |
|
24 |
|
25 #include "config.h" |
|
26 #include "dbus-gtest.h" |
|
27 #include "dbus-gvalue.h" |
|
28 #include "dbus-gsignature.h" |
|
29 #include "dbus-gobject.h" |
|
30 #include "dbus-gvalue-utils.h" |
|
31 #include "dbus/dbus-glib.h" |
|
32 #include <string.h> |
|
33 #include <glib.h> |
|
34 #ifndef __SYMBIAN32__ |
|
35 #include <glib/gi18n.h> |
|
36 #include <libintl.h> |
|
37 #define _(x) dgettext (GETTEXT_PACKAGE, x) |
|
38 #define N_(x) x |
|
39 #else |
|
40 |
|
41 #define _(x) x |
|
42 #define N_(x) x |
|
43 #endif |
|
44 |
|
45 |
|
46 #include "dbus/dbus-signature.h" |
|
47 #ifdef __SYMBIAN32__ |
|
48 #include "libdbus_glib_wsd_solution.h" |
|
49 #endif |
|
50 |
|
51 static gboolean demarshal_static_variant (DBusGValueMarshalCtx *context, |
|
52 DBusMessageIter *iter, |
|
53 GValue *value, |
|
54 GError **error); |
|
55 |
|
56 |
|
57 static gboolean marshal_basic (DBusMessageIter *iter, |
|
58 const GValue *value); |
|
59 static gboolean demarshal_basic (DBusGValueMarshalCtx *context, |
|
60 DBusMessageIter *iter, |
|
61 GValue *value, |
|
62 GError **error); |
|
63 static gboolean marshal_strv (DBusMessageIter *iter, |
|
64 const GValue *value); |
|
65 static gboolean demarshal_strv (DBusGValueMarshalCtx *context, |
|
66 DBusMessageIter *iter, |
|
67 GValue *value, |
|
68 GError **error); |
|
69 static gboolean marshal_valuearray (DBusMessageIter *iter, |
|
70 const GValue *value); |
|
71 static gboolean demarshal_valuearray (DBusGValueMarshalCtx *context, |
|
72 DBusMessageIter *iter, |
|
73 GValue *value, |
|
74 GError **error); |
|
75 static gboolean marshal_variant (DBusMessageIter *iter, |
|
76 const GValue *value); |
|
77 static gboolean demarshal_variant (DBusGValueMarshalCtx *context, |
|
78 DBusMessageIter *iter, |
|
79 GValue *value, |
|
80 GError **error); |
|
81 static gboolean marshal_proxy (DBusMessageIter *iter, |
|
82 const GValue *value); |
|
83 static gboolean demarshal_proxy (DBusGValueMarshalCtx *context, |
|
84 DBusMessageIter *iter, |
|
85 GValue *value, |
|
86 GError **error); |
|
87 static gboolean marshal_object_path (DBusMessageIter *iter, |
|
88 const GValue *value); |
|
89 static gboolean demarshal_object_path (DBusGValueMarshalCtx *context, |
|
90 DBusMessageIter *iter, |
|
91 GValue *value, |
|
92 GError **error); |
|
93 static gboolean marshal_object (DBusMessageIter *iter, |
|
94 const GValue *value); |
|
95 static gboolean demarshal_object (DBusGValueMarshalCtx *context, |
|
96 DBusMessageIter *iter, |
|
97 GValue *value, |
|
98 GError **error); |
|
99 static gboolean marshal_map (DBusMessageIter *iter, |
|
100 const GValue *value); |
|
101 static gboolean demarshal_map (DBusGValueMarshalCtx *context, |
|
102 DBusMessageIter *iter, |
|
103 GValue *value, |
|
104 GError **error); |
|
105 |
|
106 static gboolean marshal_collection (DBusMessageIter *iter, |
|
107 const GValue *value); |
|
108 static gboolean marshal_collection_ptrarray (DBusMessageIter *iter, |
|
109 const GValue *value); |
|
110 static gboolean marshal_collection_array (DBusMessageIter *iter, |
|
111 const GValue *value); |
|
112 static gboolean demarshal_collection (DBusGValueMarshalCtx *context, |
|
113 DBusMessageIter *iter, |
|
114 GValue *value, |
|
115 GError **error); |
|
116 static gboolean demarshal_collection_ptrarray (DBusGValueMarshalCtx *context, |
|
117 DBusMessageIter *iter, |
|
118 GValue *value, |
|
119 GError **error); |
|
120 static gboolean demarshal_collection_array (DBusGValueMarshalCtx *context, |
|
121 DBusMessageIter *iter, |
|
122 GValue *value, |
|
123 GError **error); |
|
124 static gboolean marshal_struct (DBusMessageIter *iter, |
|
125 const GValue *value); |
|
126 static gboolean demarshal_struct (DBusGValueMarshalCtx *context, |
|
127 DBusMessageIter *iter, |
|
128 GValue *value, |
|
129 GError **error); |
|
130 |
|
131 |
|
132 typedef gboolean (*DBusGValueMarshalFunc) (DBusMessageIter *iter, |
|
133 const GValue *value); |
|
134 typedef gboolean (*DBusGValueDemarshalFunc) (DBusGValueMarshalCtx *context, |
|
135 DBusMessageIter *iter, |
|
136 GValue *value, |
|
137 GError **error); |
|
138 |
|
139 typedef struct { |
|
140 DBusGValueMarshalFunc marshaller; |
|
141 DBusGValueDemarshalFunc demarshaller; |
|
142 } DBusGTypeMarshalVtable; |
|
143 |
|
144 typedef struct { |
|
145 const char *sig; |
|
146 const DBusGTypeMarshalVtable *vtable; |
|
147 } DBusGTypeMarshalData; |
|
148 |
|
149 |
|
150 #if EMULATOR |
|
151 GET_STATIC_VAR_FROM_TLS(quark,dbus_gvalue,GQuark ) |
|
152 #define quark (*GET_DBUS_WSD_VAR_NAME(quark,dbus_gvalue,s)()) |
|
153 #endif |
|
154 |
|
155 static GQuark |
|
156 dbus_g_type_metadata_data_quark () |
|
157 { |
|
158 #ifndef EMULATOR |
|
159 static GQuark quark; |
|
160 #endif |
|
161 if (!quark) |
|
162 quark = g_quark_from_static_string ("DBusGTypeMetaData"); |
|
163 |
|
164 return quark; |
|
165 } |
|
166 |
|
167 static void |
|
168 set_type_metadata (GType type, const DBusGTypeMarshalData *data) |
|
169 { |
|
170 g_type_set_qdata (type, dbus_g_type_metadata_data_quark (), (gpointer) data); |
|
171 } |
|
172 |
|
173 static void |
|
174 register_basic (int typecode, const DBusGTypeMarshalData *typedata) |
|
175 { |
|
176 set_type_metadata (_dbus_gtype_from_basic_typecode (typecode), typedata); |
|
177 } |
|
178 |
|
179 #if EMULATOR |
|
180 GET_STATIC_VAR_FROM_TLS(types_initialized,dbus_gvalue,gboolean ) |
|
181 #define types_initialized (*GET_DBUS_WSD_VAR_NAME(types_initialized,dbus_gvalue,s)()) |
|
182 |
|
183 #endif |
|
184 |
|
185 void |
|
186 _dbus_g_value_types_init (void) |
|
187 { |
|
188 |
|
189 #ifndef EMULATOR |
|
190 static gboolean types_initialized; |
|
191 #endif |
|
192 |
|
193 static const DBusGTypeMarshalVtable basic_vtable = { |
|
194 marshal_basic, |
|
195 demarshal_basic |
|
196 }; |
|
197 |
|
198 if (types_initialized) |
|
199 return; |
|
200 |
|
201 dbus_g_type_specialized_init (); |
|
202 _dbus_g_type_specialized_builtins_init (); |
|
203 |
|
204 /* Register basic types */ |
|
205 { |
|
206 static const DBusGTypeMarshalData typedata = { |
|
207 DBUS_TYPE_BOOLEAN_AS_STRING, |
|
208 &basic_vtable, |
|
209 }; |
|
210 register_basic (DBUS_TYPE_BOOLEAN, &typedata); |
|
211 } |
|
212 { |
|
213 static const DBusGTypeMarshalData typedata = { |
|
214 DBUS_TYPE_BYTE_AS_STRING, |
|
215 &basic_vtable, |
|
216 }; |
|
217 register_basic (DBUS_TYPE_BYTE, &typedata); |
|
218 } |
|
219 { |
|
220 static const DBusGTypeMarshalData typedata = { |
|
221 DBUS_TYPE_INT16_AS_STRING, |
|
222 &basic_vtable, |
|
223 }; |
|
224 register_basic (DBUS_TYPE_INT16, &typedata); |
|
225 } |
|
226 { |
|
227 static const DBusGTypeMarshalData typedata = { |
|
228 DBUS_TYPE_UINT16_AS_STRING, |
|
229 &basic_vtable, |
|
230 }; |
|
231 register_basic (DBUS_TYPE_UINT16, &typedata); |
|
232 } |
|
233 { |
|
234 static const DBusGTypeMarshalData typedata = { |
|
235 DBUS_TYPE_UINT32_AS_STRING, |
|
236 &basic_vtable, |
|
237 }; |
|
238 register_basic (DBUS_TYPE_UINT32, &typedata); |
|
239 } |
|
240 { |
|
241 static const DBusGTypeMarshalData typedata = { |
|
242 DBUS_TYPE_INT32_AS_STRING, |
|
243 &basic_vtable, |
|
244 }; |
|
245 register_basic (DBUS_TYPE_INT32, &typedata); |
|
246 } |
|
247 { |
|
248 static const DBusGTypeMarshalData typedata = { |
|
249 DBUS_TYPE_UINT64_AS_STRING, |
|
250 &basic_vtable, |
|
251 }; |
|
252 register_basic (DBUS_TYPE_UINT64, &typedata); |
|
253 } |
|
254 { |
|
255 static const DBusGTypeMarshalData typedata = { |
|
256 DBUS_TYPE_INT64_AS_STRING, |
|
257 &basic_vtable, |
|
258 }; |
|
259 register_basic (DBUS_TYPE_INT64, &typedata); |
|
260 } |
|
261 { |
|
262 static const DBusGTypeMarshalData typedata = { |
|
263 DBUS_TYPE_DOUBLE_AS_STRING, |
|
264 &basic_vtable, |
|
265 }; |
|
266 register_basic (DBUS_TYPE_DOUBLE, &typedata); |
|
267 } |
|
268 { |
|
269 static const DBusGTypeMarshalData typedata = { |
|
270 DBUS_TYPE_STRING_AS_STRING, |
|
271 &basic_vtable, |
|
272 }; |
|
273 register_basic (DBUS_TYPE_STRING, &typedata); |
|
274 } |
|
275 /* fundamental GTypes that don't map 1:1 with D-BUS types */ |
|
276 { |
|
277 static const DBusGTypeMarshalData typedata = { |
|
278 DBUS_TYPE_BYTE_AS_STRING, |
|
279 &basic_vtable, |
|
280 }; |
|
281 set_type_metadata (G_TYPE_CHAR, &typedata); |
|
282 } |
|
283 { |
|
284 static const DBusGTypeMarshalData typedata = { |
|
285 DBUS_TYPE_INT32_AS_STRING, |
|
286 &basic_vtable, |
|
287 }; |
|
288 set_type_metadata (G_TYPE_LONG, &typedata); |
|
289 } |
|
290 { |
|
291 static const DBusGTypeMarshalData typedata = { |
|
292 DBUS_TYPE_UINT32_AS_STRING, |
|
293 &basic_vtable, |
|
294 }; |
|
295 set_type_metadata (G_TYPE_ULONG, &typedata); |
|
296 } |
|
297 { |
|
298 static const DBusGTypeMarshalData typedata = { |
|
299 DBUS_TYPE_DOUBLE_AS_STRING, |
|
300 &basic_vtable, |
|
301 }; |
|
302 set_type_metadata (G_TYPE_FLOAT, &typedata); |
|
303 } |
|
304 |
|
305 /* Register complex types with builtin GType mappings */ |
|
306 { |
|
307 static const DBusGTypeMarshalVtable vtable = { |
|
308 marshal_variant, |
|
309 demarshal_variant |
|
310 }; |
|
311 static const DBusGTypeMarshalData typedata = { |
|
312 DBUS_TYPE_VARIANT_AS_STRING, |
|
313 &vtable |
|
314 }; |
|
315 set_type_metadata (G_TYPE_VALUE, &typedata); |
|
316 }; |
|
317 { |
|
318 static const DBusGTypeMarshalVtable vtable = { |
|
319 marshal_strv, |
|
320 demarshal_strv |
|
321 }; |
|
322 static const DBusGTypeMarshalData typedata = { |
|
323 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, |
|
324 &vtable |
|
325 }; |
|
326 set_type_metadata (G_TYPE_STRV, &typedata); |
|
327 }; |
|
328 |
|
329 |
|
330 /* Register some types specific to the D-BUS GLib bindings */ |
|
331 { |
|
332 static const DBusGTypeMarshalVtable vtable = { |
|
333 marshal_proxy, |
|
334 demarshal_proxy |
|
335 }; |
|
336 static const DBusGTypeMarshalData typedata = { |
|
337 DBUS_TYPE_OBJECT_PATH_AS_STRING, |
|
338 &vtable |
|
339 }; |
|
340 set_type_metadata (DBUS_TYPE_G_PROXY, &typedata); |
|
341 } |
|
342 |
|
343 { |
|
344 static const DBusGTypeMarshalVtable vtable = { |
|
345 marshal_object_path, |
|
346 demarshal_object_path |
|
347 }; |
|
348 static const DBusGTypeMarshalData typedata = { |
|
349 DBUS_TYPE_OBJECT_PATH_AS_STRING, |
|
350 &vtable |
|
351 }; |
|
352 set_type_metadata (DBUS_TYPE_G_OBJECT_PATH, &typedata); |
|
353 } |
|
354 |
|
355 { |
|
356 static const DBusGTypeMarshalVtable vtable = { |
|
357 marshal_object, |
|
358 demarshal_object |
|
359 }; |
|
360 static const DBusGTypeMarshalData typedata = { |
|
361 DBUS_TYPE_OBJECT_PATH_AS_STRING, |
|
362 &vtable |
|
363 }; |
|
364 set_type_metadata (G_TYPE_OBJECT, &typedata); |
|
365 } |
|
366 |
|
367 types_initialized = TRUE; |
|
368 } |
|
369 |
|
370 /** |
|
371 * Get the GLib type ID for a DBusGObjectPath boxed type. |
|
372 * |
|
373 * Returns: GLib type |
|
374 */ |
|
375 #if EMULATOR |
|
376 GET_STATIC_VAR_FROM_TLS(type_id,dbus_gvalue,GType ) |
|
377 #define type_id (*GET_DBUS_WSD_VAR_NAME(type_id,dbus_gvalue,s)()) |
|
378 #endif |
|
379 |
|
380 #ifdef __SYMBIAN32__ |
|
381 EXPORT_C |
|
382 #endif |
|
383 GType |
|
384 dbus_g_object_path_get_g_type (void) |
|
385 { |
|
386 #ifndef EMULATOR |
|
387 static GType type_id = 0; |
|
388 #endif |
|
389 |
|
390 |
|
391 |
|
392 if (!type_id) |
|
393 type_id = g_boxed_type_register_static ("DBusGObjectPath", |
|
394 (GBoxedCopyFunc) g_strdup, |
|
395 (GBoxedFreeFunc) g_free); |
|
396 return type_id; |
|
397 } |
|
398 |
|
399 |
|
400 char * |
|
401 _dbus_gtype_to_signature (GType gtype) |
|
402 { |
|
403 char *ret; |
|
404 DBusGTypeMarshalData *typedata; |
|
405 |
|
406 if (dbus_g_type_is_collection (gtype)) |
|
407 { |
|
408 GType elt_gtype; |
|
409 char *subsig; |
|
410 |
|
411 elt_gtype = dbus_g_type_get_collection_specialization (gtype); |
|
412 subsig = _dbus_gtype_to_signature (elt_gtype); |
|
413 ret = g_strconcat (DBUS_TYPE_ARRAY_AS_STRING, subsig, NULL); |
|
414 g_free (subsig); |
|
415 } |
|
416 else if (dbus_g_type_is_map (gtype)) |
|
417 { |
|
418 GType key_gtype; |
|
419 GType val_gtype; |
|
420 char *key_subsig; |
|
421 char *val_subsig; |
|
422 |
|
423 key_gtype = dbus_g_type_get_map_key_specialization (gtype); |
|
424 val_gtype = dbus_g_type_get_map_value_specialization (gtype); |
|
425 key_subsig = _dbus_gtype_to_signature (key_gtype); |
|
426 val_subsig = _dbus_gtype_to_signature (val_gtype); |
|
427 ret = g_strconcat (DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING, key_subsig, val_subsig, DBUS_DICT_ENTRY_END_CHAR_AS_STRING, NULL); |
|
428 g_free (key_subsig); |
|
429 g_free (val_subsig); |
|
430 } |
|
431 else if (dbus_g_type_is_struct (gtype)) |
|
432 { |
|
433 guint i, size; |
|
434 GString *sig; |
|
435 size = dbus_g_type_get_struct_size (gtype); |
|
436 sig = g_string_sized_new (size+2); /*some sensible starting size*/ |
|
437 g_string_assign (sig, DBUS_STRUCT_BEGIN_CHAR_AS_STRING); |
|
438 for (i = 0; i < size; i++) |
|
439 { |
|
440 gchar *subsig; |
|
441 subsig = _dbus_gtype_to_signature ( |
|
442 dbus_g_type_get_struct_member_type (gtype, i)); |
|
443 g_string_append (sig, subsig); |
|
444 g_free (subsig); |
|
445 } |
|
446 g_string_append (sig, DBUS_STRUCT_END_CHAR_AS_STRING); |
|
447 ret = g_string_free (sig, FALSE); |
|
448 } |
|
449 else |
|
450 { |
|
451 typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ()); |
|
452 if (typedata == NULL) |
|
453 return NULL; |
|
454 ret = g_strdup (typedata->sig); |
|
455 } |
|
456 return ret; |
|
457 } |
|
458 |
|
459 char * |
|
460 _dbus_gvalue_to_signature (const GValue *val) |
|
461 { |
|
462 GType gtype; |
|
463 |
|
464 gtype = G_VALUE_TYPE (val); |
|
465 if (g_type_is_a (gtype, G_TYPE_VALUE_ARRAY)) |
|
466 { |
|
467 GString *str; |
|
468 guint i; |
|
469 GValueArray *array; |
|
470 |
|
471 array = g_value_get_boxed (val); |
|
472 |
|
473 str = g_string_new (DBUS_STRUCT_BEGIN_CHAR_AS_STRING); |
|
474 for (i = 0; i < array->n_values; i++) |
|
475 { |
|
476 char *sig; |
|
477 sig = _dbus_gvalue_to_signature (g_value_array_get_nth (array, i)); |
|
478 g_string_append (str, sig); |
|
479 g_free (sig); |
|
480 } |
|
481 g_string_append (str, DBUS_STRUCT_END_CHAR_AS_STRING); |
|
482 |
|
483 return g_string_free (str, FALSE); |
|
484 } |
|
485 else |
|
486 return _dbus_gtype_to_signature (gtype); |
|
487 } |
|
488 |
|
489 static gboolean |
|
490 demarshal_basic (DBusGValueMarshalCtx *context, |
|
491 DBusMessageIter *iter, |
|
492 GValue *value, |
|
493 GError **error) |
|
494 { |
|
495 int current_type; |
|
496 |
|
497 current_type = dbus_message_iter_get_arg_type (iter); |
|
498 g_assert (dbus_type_is_basic (current_type)); |
|
499 |
|
500 switch (current_type) |
|
501 { |
|
502 case DBUS_TYPE_BOOLEAN: |
|
503 { |
|
504 dbus_bool_t bool; |
|
505 dbus_message_iter_get_basic (iter, &bool); |
|
506 g_value_set_boolean (value, bool); |
|
507 return TRUE; |
|
508 } |
|
509 case DBUS_TYPE_BYTE: |
|
510 { |
|
511 unsigned char byte; |
|
512 dbus_message_iter_get_basic (iter, &byte); |
|
513 g_value_set_uchar (value, byte); |
|
514 return TRUE; |
|
515 } |
|
516 case DBUS_TYPE_INT32: |
|
517 { |
|
518 dbus_int32_t intval; |
|
519 dbus_message_iter_get_basic (iter, &intval); |
|
520 g_value_set_int (value, intval); |
|
521 return TRUE; |
|
522 } |
|
523 case DBUS_TYPE_UINT32: |
|
524 { |
|
525 dbus_uint32_t intval; |
|
526 dbus_message_iter_get_basic (iter, &intval); |
|
527 g_value_set_uint (value, intval); |
|
528 return TRUE; |
|
529 } |
|
530 case DBUS_TYPE_INT64: |
|
531 { |
|
532 dbus_int64_t intval; |
|
533 dbus_message_iter_get_basic (iter, &intval); |
|
534 g_value_set_int64 (value, intval); |
|
535 return TRUE; |
|
536 } |
|
537 case DBUS_TYPE_UINT64: |
|
538 { |
|
539 dbus_uint64_t intval; |
|
540 dbus_message_iter_get_basic (iter, &intval); |
|
541 g_value_set_uint64 (value, intval); |
|
542 return TRUE; |
|
543 } |
|
544 case DBUS_TYPE_DOUBLE: |
|
545 { |
|
546 double dval; |
|
547 dbus_message_iter_get_basic (iter, &dval); |
|
548 g_value_set_double (value, dval); |
|
549 return TRUE; |
|
550 } |
|
551 case DBUS_TYPE_INT16: |
|
552 { |
|
553 dbus_int16_t v; |
|
554 dbus_message_iter_get_basic (iter, &v); |
|
555 g_value_set_int (value, v); |
|
556 return TRUE; |
|
557 } |
|
558 case DBUS_TYPE_UINT16: |
|
559 { |
|
560 dbus_uint16_t v; |
|
561 dbus_message_iter_get_basic (iter, &v); |
|
562 g_value_set_uint (value, v); |
|
563 return TRUE; |
|
564 } |
|
565 case DBUS_TYPE_STRING: |
|
566 { |
|
567 const char *s; |
|
568 dbus_message_iter_get_basic (iter, &s); |
|
569 g_value_set_string (value, s); |
|
570 return TRUE; |
|
571 } |
|
572 default: |
|
573 g_assert_not_reached (); |
|
574 return FALSE; |
|
575 } |
|
576 } |
|
577 |
|
578 static gboolean |
|
579 demarshal_static_variant (DBusGValueMarshalCtx *context, |
|
580 DBusMessageIter *iter, |
|
581 GValue *value, |
|
582 GError **error) |
|
583 { |
|
584 char *sig; |
|
585 int current_type; |
|
586 DBusMessageIter subiter; |
|
587 GType variant_type; |
|
588 |
|
589 current_type = dbus_message_iter_get_arg_type (iter); |
|
590 dbus_message_iter_recurse (iter, &subiter); |
|
591 sig = dbus_message_iter_get_signature (&subiter); |
|
592 |
|
593 variant_type = _dbus_gtype_from_signature (sig, context->proxy != NULL); |
|
594 if (variant_type != G_TYPE_INVALID) |
|
595 { |
|
596 g_value_init (value, variant_type); |
|
597 |
|
598 if (!_dbus_gvalue_demarshal (context, &subiter, value, error)) |
|
599 { |
|
600 dbus_free (sig); |
|
601 return FALSE; |
|
602 } |
|
603 } |
|
604 dbus_free (sig); |
|
605 return TRUE; |
|
606 } |
|
607 |
|
608 static gboolean |
|
609 demarshal_variant (DBusGValueMarshalCtx *context, |
|
610 DBusMessageIter *iter, |
|
611 GValue *value, |
|
612 GError **error) |
|
613 |
|
614 { |
|
615 GValue *variant_val; |
|
616 variant_val = g_new0 (GValue, 1); |
|
617 |
|
618 if (!demarshal_static_variant (context, iter, variant_val, error)) |
|
619 return FALSE; |
|
620 |
|
621 g_value_set_boxed_take_ownership (value, variant_val); |
|
622 return TRUE; |
|
623 } |
|
624 |
|
625 static gboolean |
|
626 demarshal_proxy (DBusGValueMarshalCtx *context, |
|
627 DBusMessageIter *iter, |
|
628 GValue *value, |
|
629 GError **error) |
|
630 { |
|
631 DBusGProxy *new_proxy; |
|
632 const char *objpath; |
|
633 int current_type; |
|
634 |
|
635 current_type = dbus_message_iter_get_arg_type (iter); |
|
636 if (current_type != DBUS_TYPE_OBJECT_PATH) |
|
637 { |
|
638 g_set_error (error, |
|
639 DBUS_GERROR, |
|
640 DBUS_GERROR_INVALID_ARGS, |
|
641 _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type); |
|
642 return FALSE; |
|
643 } |
|
644 |
|
645 g_assert (context->proxy != NULL); |
|
646 |
|
647 dbus_message_iter_get_basic (iter, &objpath); |
|
648 |
|
649 new_proxy = dbus_g_proxy_new_from_proxy (context->proxy, NULL, objpath); |
|
650 g_value_set_object_take_ownership (value, new_proxy); |
|
651 |
|
652 return TRUE; |
|
653 } |
|
654 |
|
655 static gboolean |
|
656 demarshal_object_path (DBusGValueMarshalCtx *context, |
|
657 DBusMessageIter *iter, |
|
658 GValue *value, |
|
659 GError **error) |
|
660 { |
|
661 const char *objpath; |
|
662 int current_type; |
|
663 |
|
664 current_type = dbus_message_iter_get_arg_type (iter); |
|
665 if (current_type != DBUS_TYPE_OBJECT_PATH) |
|
666 { |
|
667 g_set_error (error, |
|
668 DBUS_GERROR, |
|
669 DBUS_GERROR_INVALID_ARGS, |
|
670 _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type); |
|
671 return FALSE; |
|
672 } |
|
673 |
|
674 dbus_message_iter_get_basic (iter, &objpath); |
|
675 |
|
676 g_value_set_boxed_take_ownership (value, g_strdup (objpath)); |
|
677 |
|
678 return TRUE; |
|
679 } |
|
680 |
|
681 static gboolean |
|
682 demarshal_object (DBusGValueMarshalCtx *context, |
|
683 DBusMessageIter *iter, |
|
684 GValue *value, |
|
685 GError **error) |
|
686 { |
|
687 const char *objpath; |
|
688 int current_type; |
|
689 GObject *obj; |
|
690 |
|
691 current_type = dbus_message_iter_get_arg_type (iter); |
|
692 if (current_type != DBUS_TYPE_OBJECT_PATH) |
|
693 { |
|
694 g_set_error (error, |
|
695 DBUS_GERROR, |
|
696 DBUS_GERROR_INVALID_ARGS, |
|
697 _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type); |
|
698 return FALSE; |
|
699 } |
|
700 g_assert (context->proxy == NULL); |
|
701 |
|
702 dbus_message_iter_get_basic (iter, &objpath); |
|
703 |
|
704 obj = dbus_g_connection_lookup_g_object (context->gconnection, objpath); |
|
705 if (obj == NULL) |
|
706 { |
|
707 g_set_error (error, |
|
708 DBUS_GERROR, |
|
709 DBUS_GERROR_INVALID_ARGS, |
|
710 _("Unregistered object at path '%s'"), |
|
711 objpath); |
|
712 return FALSE; |
|
713 } |
|
714 g_value_set_object (value, obj); |
|
715 |
|
716 return TRUE; |
|
717 } |
|
718 |
|
719 static gboolean |
|
720 demarshal_strv (DBusGValueMarshalCtx *context, |
|
721 DBusMessageIter *iter, |
|
722 GValue *value, |
|
723 GError **error) |
|
724 { |
|
725 DBusMessageIter subiter; |
|
726 int current_type; |
|
727 char **ret; |
|
728 int len; |
|
729 int i; |
|
730 |
|
731 current_type = dbus_message_iter_get_arg_type (iter); |
|
732 if (current_type != DBUS_TYPE_ARRAY) |
|
733 { |
|
734 g_set_error (error, |
|
735 DBUS_GERROR, |
|
736 DBUS_GERROR_INVALID_ARGS, |
|
737 _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type); |
|
738 return FALSE; |
|
739 } |
|
740 |
|
741 dbus_message_iter_recurse (iter, &subiter); |
|
742 |
|
743 current_type = dbus_message_iter_get_arg_type (&subiter); |
|
744 if (current_type != DBUS_TYPE_INVALID |
|
745 && current_type != DBUS_TYPE_STRING) |
|
746 { |
|
747 g_set_error (error, |
|
748 DBUS_GERROR, |
|
749 DBUS_GERROR_INVALID_ARGS, |
|
750 _("Expected D-BUS string, got type code \'%c\'"), (guchar) current_type); |
|
751 return FALSE; |
|
752 } |
|
753 |
|
754 len = dbus_message_iter_get_array_len (&subiter); |
|
755 g_assert (len >= 0); |
|
756 ret = g_malloc (sizeof (char *) * (len + 1)); |
|
757 |
|
758 i = 0; |
|
759 while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) |
|
760 { |
|
761 g_assert (i < len); |
|
762 g_assert (current_type == DBUS_TYPE_STRING); |
|
763 |
|
764 dbus_message_iter_get_basic (&subiter, &(ret[i])); |
|
765 ret[i] = g_strdup (ret[i]); |
|
766 |
|
767 dbus_message_iter_next (&subiter); |
|
768 i++; |
|
769 } |
|
770 ret[i] = NULL; |
|
771 g_value_set_boxed_take_ownership (value, ret); |
|
772 |
|
773 return TRUE; |
|
774 } |
|
775 |
|
776 static gboolean |
|
777 demarshal_valuearray (DBusGValueMarshalCtx *context, |
|
778 DBusMessageIter *iter, |
|
779 GValue *value, |
|
780 GError **error) |
|
781 { |
|
782 int current_type; |
|
783 GValueArray *ret; |
|
784 DBusMessageIter subiter; |
|
785 |
|
786 current_type = dbus_message_iter_get_arg_type (iter); |
|
787 if (current_type != DBUS_TYPE_STRUCT) |
|
788 { |
|
789 g_set_error (error, |
|
790 DBUS_GERROR, |
|
791 DBUS_GERROR_INVALID_ARGS, |
|
792 _("Expected D-BUS struct, got type code \'%c\'"), (guchar) current_type); |
|
793 return FALSE; |
|
794 } |
|
795 |
|
796 dbus_message_iter_recurse (iter, &subiter); |
|
797 |
|
798 ret = g_value_array_new (12); |
|
799 |
|
800 while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) |
|
801 { |
|
802 GValue *val; |
|
803 GType elt_type; |
|
804 char *current_sig; |
|
805 |
|
806 g_value_array_append (ret, NULL); |
|
807 val = g_value_array_get_nth (ret, ret->n_values - 1); |
|
808 |
|
809 current_sig = dbus_message_iter_get_signature (&subiter); |
|
810 elt_type = _dbus_gtype_from_signature (current_sig, TRUE); |
|
811 |
|
812 dbus_free (current_sig); |
|
813 if (elt_type == G_TYPE_INVALID) |
|
814 { |
|
815 g_value_array_free (ret); |
|
816 g_set_error (error, |
|
817 DBUS_GERROR, |
|
818 DBUS_GERROR_INVALID_ARGS, |
|
819 _("Couldn't demarshal argument with signature \"%s\""), current_sig); |
|
820 return FALSE; |
|
821 } |
|
822 |
|
823 g_value_init (val, elt_type); |
|
824 |
|
825 if (!_dbus_gvalue_demarshal (context, &subiter, val, error)) |
|
826 { |
|
827 g_value_array_free (ret); |
|
828 return FALSE; |
|
829 } |
|
830 |
|
831 dbus_message_iter_next (&subiter); |
|
832 } |
|
833 |
|
834 g_value_set_boxed_take_ownership (value, ret); |
|
835 |
|
836 return TRUE; |
|
837 } |
|
838 |
|
839 static gboolean |
|
840 demarshal_map (DBusGValueMarshalCtx *context, |
|
841 DBusMessageIter *iter, |
|
842 GValue *value, |
|
843 GError **error) |
|
844 { |
|
845 GType gtype; |
|
846 DBusMessageIter subiter; |
|
847 int current_type; |
|
848 gpointer ret; |
|
849 GType key_gtype; |
|
850 GType value_gtype; |
|
851 DBusGTypeSpecializedAppendContext appendctx; |
|
852 |
|
853 current_type = dbus_message_iter_get_arg_type (iter); |
|
854 if (current_type != DBUS_TYPE_ARRAY) |
|
855 { |
|
856 g_set_error (error, |
|
857 DBUS_GERROR, |
|
858 DBUS_GERROR_INVALID_ARGS, |
|
859 _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type); |
|
860 return FALSE; |
|
861 } |
|
862 |
|
863 gtype = G_VALUE_TYPE (value); |
|
864 |
|
865 dbus_message_iter_recurse (iter, &subiter); |
|
866 |
|
867 current_type = dbus_message_iter_get_arg_type (&subiter); |
|
868 if (current_type != DBUS_TYPE_INVALID |
|
869 && current_type != DBUS_TYPE_DICT_ENTRY) |
|
870 { |
|
871 g_set_error (error, |
|
872 DBUS_GERROR, |
|
873 DBUS_GERROR_INVALID_ARGS, |
|
874 _("Expected D-BUS dict entry, got type code \'%c\'"), (guchar) current_type); |
|
875 return FALSE; |
|
876 } |
|
877 |
|
878 key_gtype = dbus_g_type_get_map_key_specialization (gtype); |
|
879 value_gtype = dbus_g_type_get_map_value_specialization (gtype); |
|
880 |
|
881 ret = dbus_g_type_specialized_construct (gtype); |
|
882 g_value_set_boxed_take_ownership (value, ret); |
|
883 |
|
884 dbus_g_type_specialized_init_append (value, &appendctx); |
|
885 |
|
886 while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) |
|
887 { |
|
888 DBusMessageIter entry_iter; |
|
889 GValue key_value = {0,}; |
|
890 GValue value_value = {0,}; |
|
891 |
|
892 current_type = dbus_message_iter_get_arg_type (&subiter); |
|
893 g_assert (current_type == DBUS_TYPE_DICT_ENTRY); |
|
894 |
|
895 dbus_message_iter_recurse (&subiter, &entry_iter); |
|
896 |
|
897 g_value_init (&key_value, key_gtype); |
|
898 if (!_dbus_gvalue_demarshal (context, |
|
899 &entry_iter, |
|
900 &key_value, |
|
901 error)) |
|
902 return FALSE; |
|
903 |
|
904 dbus_message_iter_next (&entry_iter); |
|
905 |
|
906 g_value_init (&value_value, value_gtype); |
|
907 if (!_dbus_gvalue_demarshal (context, |
|
908 &entry_iter, |
|
909 &value_value, |
|
910 error)) |
|
911 return FALSE; |
|
912 |
|
913 dbus_g_type_specialized_map_append (&appendctx, &key_value, &value_value); |
|
914 /* Ownership of values passes to map, don't unset */ |
|
915 |
|
916 dbus_message_iter_next (&subiter); |
|
917 } |
|
918 |
|
919 return TRUE; |
|
920 } |
|
921 |
|
922 static gboolean |
|
923 demarshal_struct (DBusGValueMarshalCtx *context, |
|
924 DBusMessageIter *iter, |
|
925 GValue *value, |
|
926 GError **error) |
|
927 { |
|
928 int current_type; |
|
929 DBusMessageIter subiter; |
|
930 guint i, size; |
|
931 GValue val = {0,}; |
|
932 GType elt_type; |
|
933 |
|
934 current_type = dbus_message_iter_get_arg_type (iter); |
|
935 if (current_type != DBUS_TYPE_STRUCT) |
|
936 { |
|
937 g_set_error (error, |
|
938 DBUS_GERROR, |
|
939 DBUS_GERROR_INVALID_ARGS, |
|
940 _("Expected D-BUS struct, got type code \'%c\'"), (guchar) current_type); |
|
941 return FALSE; |
|
942 } |
|
943 |
|
944 dbus_message_iter_recurse (iter, &subiter); |
|
945 |
|
946 g_value_set_boxed_take_ownership (value, |
|
947 dbus_g_type_specialized_construct (G_VALUE_TYPE (value))); |
|
948 |
|
949 size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value)); |
|
950 |
|
951 for (i=0; i < size; i++) |
|
952 { |
|
953 |
|
954 elt_type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE(value), i); |
|
955 if (elt_type == G_TYPE_INVALID) |
|
956 { |
|
957 g_value_unset (value); |
|
958 g_set_error (error, |
|
959 DBUS_GERROR, |
|
960 DBUS_GERROR_INVALID_ARGS, |
|
961 _("Couldn't demarshal argument, " |
|
962 "struct type %s has no member %d"), |
|
963 g_type_name (G_VALUE_TYPE(value)), i); |
|
964 return FALSE; |
|
965 } |
|
966 |
|
967 g_value_init (&val, elt_type); |
|
968 |
|
969 if (!_dbus_gvalue_demarshal (context, &subiter, &val, error)) |
|
970 { |
|
971 g_value_unset (&val); |
|
972 g_value_unset (value); |
|
973 return FALSE; |
|
974 } |
|
975 if (!dbus_g_type_struct_set_member (value, i, &val)) |
|
976 { |
|
977 g_value_unset (&val); |
|
978 g_value_unset (value); |
|
979 return FALSE; |
|
980 } |
|
981 |
|
982 dbus_message_iter_next (&subiter); |
|
983 g_value_unset (&val); |
|
984 } |
|
985 |
|
986 g_assert (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_INVALID); |
|
987 |
|
988 return TRUE; |
|
989 } |
|
990 |
|
991 |
|
992 static DBusGValueDemarshalFunc |
|
993 get_type_demarshaller (GType type) |
|
994 { |
|
995 DBusGTypeMarshalData *typedata; |
|
996 |
|
997 typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ()); |
|
998 if (typedata == NULL) |
|
999 { |
|
1000 if (g_type_is_a (type, G_TYPE_VALUE_ARRAY)) |
|
1001 return demarshal_valuearray; |
|
1002 if (dbus_g_type_is_collection (type)) |
|
1003 return demarshal_collection; |
|
1004 if (dbus_g_type_is_map (type)) |
|
1005 return demarshal_map; |
|
1006 if (dbus_g_type_is_struct (type)) |
|
1007 return demarshal_struct; |
|
1008 |
|
1009 g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type)); |
|
1010 return NULL; |
|
1011 } |
|
1012 g_assert (typedata->vtable); |
|
1013 return typedata->vtable->demarshaller; |
|
1014 } |
|
1015 |
|
1016 static gboolean |
|
1017 demarshal_collection (DBusGValueMarshalCtx *context, |
|
1018 DBusMessageIter *iter, |
|
1019 GValue *value, |
|
1020 GError **error) |
|
1021 { |
|
1022 GType coltype; |
|
1023 GType subtype; |
|
1024 |
|
1025 coltype = G_VALUE_TYPE (value); |
|
1026 subtype = dbus_g_type_get_collection_specialization (coltype); |
|
1027 |
|
1028 if (_dbus_g_type_is_fixed (subtype)) |
|
1029 return demarshal_collection_array (context, iter, value, error); |
|
1030 else |
|
1031 return demarshal_collection_ptrarray (context, iter, value, error); |
|
1032 } |
|
1033 |
|
1034 static gboolean |
|
1035 demarshal_collection_ptrarray (DBusGValueMarshalCtx *context, |
|
1036 DBusMessageIter *iter, |
|
1037 GValue *value, |
|
1038 GError **error) |
|
1039 { |
|
1040 GType coltype; |
|
1041 GType subtype; |
|
1042 gpointer instance; |
|
1043 DBusGTypeSpecializedAppendContext ctx; |
|
1044 DBusGValueDemarshalFunc demarshaller; |
|
1045 DBusMessageIter subiter; |
|
1046 int current_type; |
|
1047 |
|
1048 current_type = dbus_message_iter_get_arg_type (iter); |
|
1049 |
|
1050 if (current_type != DBUS_TYPE_ARRAY) |
|
1051 { |
|
1052 g_set_error (error, |
|
1053 DBUS_GERROR, |
|
1054 DBUS_GERROR_INVALID_ARGS, |
|
1055 _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type); |
|
1056 return FALSE; |
|
1057 } |
|
1058 |
|
1059 dbus_message_iter_recurse (iter, &subiter); |
|
1060 |
|
1061 coltype = G_VALUE_TYPE (value); |
|
1062 subtype = dbus_g_type_get_collection_specialization (coltype); |
|
1063 |
|
1064 demarshaller = get_type_demarshaller (subtype); |
|
1065 |
|
1066 if (!demarshaller) |
|
1067 { |
|
1068 g_set_error (error, |
|
1069 DBUS_GERROR, |
|
1070 DBUS_GERROR_INVALID_ARGS, |
|
1071 _("No demarshaller registered for type \"%s\" of collection \"%s\""), |
|
1072 g_type_name (coltype), |
|
1073 g_type_name (subtype)); |
|
1074 return FALSE; |
|
1075 } |
|
1076 |
|
1077 instance = dbus_g_type_specialized_construct (coltype); |
|
1078 g_value_set_boxed_take_ownership (value, instance); |
|
1079 |
|
1080 dbus_g_type_specialized_init_append (value, &ctx); |
|
1081 |
|
1082 while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) |
|
1083 { |
|
1084 GValue eltval = {0, }; |
|
1085 |
|
1086 g_value_init (&eltval, subtype); |
|
1087 |
|
1088 if (!demarshaller (context, &subiter, &eltval, error)) |
|
1089 { |
|
1090 dbus_g_type_specialized_collection_end_append (&ctx); |
|
1091 g_value_unset (value); |
|
1092 return FALSE; |
|
1093 } |
|
1094 dbus_g_type_specialized_collection_append (&ctx, &eltval); |
|
1095 |
|
1096 dbus_message_iter_next (&subiter); |
|
1097 } |
|
1098 dbus_g_type_specialized_collection_end_append (&ctx); |
|
1099 |
|
1100 return TRUE; |
|
1101 } |
|
1102 |
|
1103 static gboolean |
|
1104 demarshal_collection_array (DBusGValueMarshalCtx *context, |
|
1105 DBusMessageIter *iter, |
|
1106 GValue *value, |
|
1107 GError **error) |
|
1108 { |
|
1109 DBusMessageIter subiter; |
|
1110 GArray *ret; |
|
1111 GType elt_gtype; |
|
1112 int elt_size; |
|
1113 void *msgarray; |
|
1114 int msgarray_len; |
|
1115 |
|
1116 dbus_message_iter_recurse (iter, &subiter); |
|
1117 |
|
1118 elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value)); |
|
1119 g_assert (elt_gtype != G_TYPE_INVALID); |
|
1120 g_assert (_dbus_g_type_is_fixed (elt_gtype)); |
|
1121 |
|
1122 elt_size = _dbus_g_type_fixed_get_size (elt_gtype); |
|
1123 |
|
1124 ret = g_array_new (FALSE, TRUE, elt_size); |
|
1125 |
|
1126 msgarray = NULL; |
|
1127 dbus_message_iter_get_fixed_array (&subiter, |
|
1128 &msgarray, |
|
1129 &msgarray_len); |
|
1130 g_assert (msgarray != NULL || msgarray_len == 0); |
|
1131 |
|
1132 if (msgarray_len) |
|
1133 g_array_append_vals (ret, msgarray, (guint) msgarray_len); |
|
1134 |
|
1135 g_value_set_boxed_take_ownership (value, ret); |
|
1136 |
|
1137 return TRUE; |
|
1138 } |
|
1139 |
|
1140 gboolean |
|
1141 _dbus_gvalue_demarshal (DBusGValueMarshalCtx *context, |
|
1142 DBusMessageIter *iter, |
|
1143 GValue *value, |
|
1144 GError **error) |
|
1145 { |
|
1146 GType gtype; |
|
1147 DBusGValueDemarshalFunc demarshaller; |
|
1148 |
|
1149 gtype = G_VALUE_TYPE (value); |
|
1150 |
|
1151 demarshaller = get_type_demarshaller (gtype); |
|
1152 |
|
1153 if (demarshaller == NULL) |
|
1154 { |
|
1155 g_set_error (error, |
|
1156 DBUS_GERROR, |
|
1157 DBUS_GERROR_INVALID_ARGS, |
|
1158 _("No demarshaller registered for type \"%s\""), |
|
1159 g_type_name (gtype)); |
|
1160 return FALSE; |
|
1161 } |
|
1162 |
|
1163 return demarshaller (context, iter, value, error); |
|
1164 } |
|
1165 |
|
1166 gboolean |
|
1167 _dbus_gvalue_demarshal_variant (DBusGValueMarshalCtx *context, |
|
1168 DBusMessageIter *iter, |
|
1169 GValue *value, |
|
1170 GError **error) |
|
1171 { |
|
1172 return demarshal_static_variant (context, iter, value, error); |
|
1173 } |
|
1174 |
|
1175 GValueArray * |
|
1176 _dbus_gvalue_demarshal_message (DBusGValueMarshalCtx *context, |
|
1177 DBusMessage *message, |
|
1178 guint n_types, |
|
1179 const GType *types, |
|
1180 GError **error) |
|
1181 { |
|
1182 GValueArray *ret; |
|
1183 DBusMessageIter iter; |
|
1184 int current_type; |
|
1185 guint index_; |
|
1186 |
|
1187 ret = g_value_array_new (6); /* 6 is a typical maximum for arguments */ |
|
1188 |
|
1189 dbus_message_iter_init (message, &iter); |
|
1190 index_ = 0; |
|
1191 while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) |
|
1192 { |
|
1193 GValue *value; |
|
1194 GType gtype; |
|
1195 |
|
1196 if (index_ >= n_types) |
|
1197 { |
|
1198 g_set_error (error, DBUS_GERROR, |
|
1199 DBUS_GERROR_INVALID_ARGS, |
|
1200 _("Too many arguments in message")); |
|
1201 goto lose; |
|
1202 } |
|
1203 |
|
1204 g_value_array_append (ret, NULL); |
|
1205 value = g_value_array_get_nth (ret, index_); |
|
1206 |
|
1207 gtype = types[index_]; |
|
1208 g_value_init (value, gtype); |
|
1209 |
|
1210 if (!_dbus_gvalue_demarshal (context, &iter, value, error)) |
|
1211 goto lose; |
|
1212 dbus_message_iter_next (&iter); |
|
1213 index_++; |
|
1214 } |
|
1215 if (index_ < n_types) |
|
1216 { |
|
1217 g_set_error (error, DBUS_GERROR, |
|
1218 DBUS_GERROR_INVALID_ARGS, |
|
1219 _("Too few arguments in message")); |
|
1220 goto lose; |
|
1221 } |
|
1222 |
|
1223 return ret; |
|
1224 lose: |
|
1225 g_value_array_free (ret); |
|
1226 return NULL; |
|
1227 } |
|
1228 |
|
1229 static gboolean |
|
1230 marshal_basic (DBusMessageIter *iter, const GValue *value) |
|
1231 { |
|
1232 GType value_type; |
|
1233 |
|
1234 value_type = G_VALUE_TYPE (value); |
|
1235 |
|
1236 switch (value_type) |
|
1237 { |
|
1238 case G_TYPE_CHAR: |
|
1239 { |
|
1240 char b = g_value_get_char (value); |
|
1241 if (!dbus_message_iter_append_basic (iter, |
|
1242 DBUS_TYPE_BYTE, |
|
1243 &b)) |
|
1244 goto nomem; |
|
1245 } |
|
1246 return TRUE; |
|
1247 case G_TYPE_UCHAR: |
|
1248 { |
|
1249 unsigned char b = g_value_get_uchar (value); |
|
1250 if (!dbus_message_iter_append_basic (iter, |
|
1251 DBUS_TYPE_BYTE, |
|
1252 &b)) |
|
1253 goto nomem; |
|
1254 } |
|
1255 return TRUE; |
|
1256 case G_TYPE_BOOLEAN: |
|
1257 { |
|
1258 dbus_bool_t b = g_value_get_boolean (value); |
|
1259 if (!dbus_message_iter_append_basic (iter, |
|
1260 DBUS_TYPE_BOOLEAN, |
|
1261 &b)) |
|
1262 goto nomem; |
|
1263 } |
|
1264 return TRUE; |
|
1265 case G_TYPE_INT: |
|
1266 { |
|
1267 dbus_int32_t v = g_value_get_int (value); |
|
1268 if (!dbus_message_iter_append_basic (iter, |
|
1269 DBUS_TYPE_INT32, |
|
1270 &v)) |
|
1271 goto nomem; |
|
1272 } |
|
1273 return TRUE; |
|
1274 case G_TYPE_UINT: |
|
1275 { |
|
1276 dbus_uint32_t v = g_value_get_uint (value); |
|
1277 if (!dbus_message_iter_append_basic (iter, |
|
1278 DBUS_TYPE_UINT32, |
|
1279 &v)) |
|
1280 goto nomem; |
|
1281 } |
|
1282 return TRUE; |
|
1283 case G_TYPE_LONG: |
|
1284 { |
|
1285 dbus_int32_t v = g_value_get_long (value); |
|
1286 if (!dbus_message_iter_append_basic (iter, |
|
1287 DBUS_TYPE_INT32, |
|
1288 &v)) |
|
1289 goto nomem; |
|
1290 } |
|
1291 return TRUE; |
|
1292 case G_TYPE_ULONG: |
|
1293 { |
|
1294 dbus_uint32_t v = g_value_get_ulong (value); |
|
1295 if (!dbus_message_iter_append_basic (iter, |
|
1296 DBUS_TYPE_UINT32, |
|
1297 &v)) |
|
1298 goto nomem; |
|
1299 } |
|
1300 return TRUE; |
|
1301 case G_TYPE_INT64: |
|
1302 { |
|
1303 gint64 v = g_value_get_int64 (value); |
|
1304 if (!dbus_message_iter_append_basic (iter, |
|
1305 DBUS_TYPE_INT64, |
|
1306 &v)) |
|
1307 goto nomem; |
|
1308 } |
|
1309 return TRUE; |
|
1310 case G_TYPE_UINT64: |
|
1311 { |
|
1312 guint64 v = g_value_get_uint64 (value); |
|
1313 if (!dbus_message_iter_append_basic (iter, |
|
1314 DBUS_TYPE_UINT64, |
|
1315 &v)) |
|
1316 goto nomem; |
|
1317 } |
|
1318 return TRUE; |
|
1319 case G_TYPE_FLOAT: |
|
1320 { |
|
1321 double v = g_value_get_float (value); |
|
1322 |
|
1323 if (!dbus_message_iter_append_basic (iter, |
|
1324 DBUS_TYPE_DOUBLE, |
|
1325 &v)) |
|
1326 goto nomem; |
|
1327 } |
|
1328 return TRUE; |
|
1329 case G_TYPE_DOUBLE: |
|
1330 { |
|
1331 double v = g_value_get_double (value); |
|
1332 |
|
1333 if (!dbus_message_iter_append_basic (iter, |
|
1334 DBUS_TYPE_DOUBLE, |
|
1335 &v)) |
|
1336 goto nomem; |
|
1337 } |
|
1338 return TRUE; |
|
1339 case G_TYPE_STRING: |
|
1340 /* FIXME, the GValue string may not be valid UTF-8 */ |
|
1341 { |
|
1342 const char *v = g_value_get_string (value); |
|
1343 if (!v) |
|
1344 v = ""; |
|
1345 if (!dbus_message_iter_append_basic (iter, |
|
1346 DBUS_TYPE_STRING, |
|
1347 &v)) |
|
1348 goto nomem; |
|
1349 } |
|
1350 return TRUE; |
|
1351 |
|
1352 default: |
|
1353 { |
|
1354 g_assert_not_reached (); |
|
1355 return FALSE; |
|
1356 } |
|
1357 } |
|
1358 |
|
1359 nomem: |
|
1360 g_error ("no memory"); |
|
1361 return FALSE; |
|
1362 } |
|
1363 |
|
1364 static gboolean |
|
1365 marshal_strv (DBusMessageIter *iter, |
|
1366 const GValue *value) |
|
1367 { |
|
1368 DBusMessageIter subiter; |
|
1369 char **array; |
|
1370 char **elt; |
|
1371 gboolean ret = FALSE; |
|
1372 |
|
1373 g_assert (G_VALUE_TYPE (value) == g_strv_get_type ()); |
|
1374 |
|
1375 array = g_value_get_boxed (value); |
|
1376 |
|
1377 if (!dbus_message_iter_open_container (iter, |
|
1378 DBUS_TYPE_ARRAY, |
|
1379 "s", |
|
1380 &subiter)) |
|
1381 goto out; |
|
1382 |
|
1383 if (array) |
|
1384 { |
|
1385 for (elt = array; *elt; elt++) |
|
1386 { |
|
1387 if (!dbus_message_iter_append_basic (&subiter, |
|
1388 DBUS_TYPE_STRING, |
|
1389 elt)) |
|
1390 goto out; |
|
1391 } |
|
1392 } |
|
1393 |
|
1394 if (!dbus_message_iter_close_container (iter, &subiter)) |
|
1395 goto out; |
|
1396 ret = TRUE; |
|
1397 out: |
|
1398 return ret; |
|
1399 } |
|
1400 |
|
1401 static gboolean |
|
1402 marshal_valuearray (DBusMessageIter *iter, |
|
1403 const GValue *value) |
|
1404 { |
|
1405 GValueArray *array; |
|
1406 guint i; |
|
1407 DBusMessageIter subiter; |
|
1408 |
|
1409 g_assert (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY); |
|
1410 |
|
1411 array = g_value_get_boxed (value); |
|
1412 |
|
1413 if (!dbus_message_iter_open_container (iter, |
|
1414 DBUS_TYPE_STRUCT, |
|
1415 NULL, |
|
1416 &subiter)) |
|
1417 goto oom; |
|
1418 |
|
1419 if (array) |
|
1420 { |
|
1421 for (i = 0; i < array->n_values; i++) |
|
1422 { |
|
1423 if (!_dbus_gvalue_marshal (&subiter, g_value_array_get_nth (array, i))) |
|
1424 return FALSE; |
|
1425 } |
|
1426 } |
|
1427 |
|
1428 if (!dbus_message_iter_close_container (iter, &subiter)) |
|
1429 goto oom; |
|
1430 |
|
1431 return TRUE; |
|
1432 oom: |
|
1433 g_error ("out of memory"); |
|
1434 return FALSE; |
|
1435 } |
|
1436 |
|
1437 static gboolean |
|
1438 marshal_proxy (DBusMessageIter *iter, |
|
1439 const GValue *value) |
|
1440 { |
|
1441 const char *path; |
|
1442 DBusGProxy *proxy; |
|
1443 |
|
1444 g_assert (G_VALUE_TYPE (value) == dbus_g_proxy_get_type ()); |
|
1445 |
|
1446 proxy = g_value_get_object (value); |
|
1447 path = dbus_g_proxy_get_path (proxy); |
|
1448 |
|
1449 if (!dbus_message_iter_append_basic (iter, |
|
1450 DBUS_TYPE_OBJECT_PATH, |
|
1451 &path)) |
|
1452 return FALSE; |
|
1453 return TRUE; |
|
1454 } |
|
1455 |
|
1456 static gboolean |
|
1457 marshal_object_path (DBusMessageIter *iter, |
|
1458 const GValue *value) |
|
1459 { |
|
1460 const char *path; |
|
1461 |
|
1462 g_assert (G_VALUE_TYPE (value) == DBUS_TYPE_G_OBJECT_PATH); |
|
1463 |
|
1464 path = (const char*) g_value_get_boxed (value); |
|
1465 |
|
1466 if (!dbus_message_iter_append_basic (iter, |
|
1467 DBUS_TYPE_OBJECT_PATH, |
|
1468 &path)) |
|
1469 return FALSE; |
|
1470 return TRUE; |
|
1471 } |
|
1472 |
|
1473 static gboolean |
|
1474 marshal_object (DBusMessageIter *iter, |
|
1475 const GValue *value) |
|
1476 { |
|
1477 const char *path; |
|
1478 GObject *obj; |
|
1479 |
|
1480 obj = g_value_get_object (value); |
|
1481 path = _dbus_gobject_get_path (obj); |
|
1482 |
|
1483 if (path == NULL) |
|
1484 /* FIXME should throw error */ |
|
1485 return FALSE; |
|
1486 |
|
1487 if (!dbus_message_iter_append_basic (iter, |
|
1488 DBUS_TYPE_OBJECT_PATH, |
|
1489 &path)) |
|
1490 return FALSE; |
|
1491 return TRUE; |
|
1492 } |
|
1493 |
|
1494 struct DBusGLibHashMarshalData |
|
1495 { |
|
1496 const char *entry_sig; |
|
1497 DBusMessageIter *iter; |
|
1498 gboolean err; |
|
1499 }; |
|
1500 |
|
1501 static void |
|
1502 marshal_map_entry (const GValue *key, |
|
1503 const GValue *value, |
|
1504 gpointer data) |
|
1505 { |
|
1506 struct DBusGLibHashMarshalData *hashdata = data; |
|
1507 DBusMessageIter subiter; |
|
1508 |
|
1509 if (hashdata->err) |
|
1510 return; |
|
1511 |
|
1512 if (!dbus_message_iter_open_container (hashdata->iter, |
|
1513 DBUS_TYPE_DICT_ENTRY, |
|
1514 NULL, |
|
1515 &subiter)) |
|
1516 goto lose; |
|
1517 |
|
1518 if (!_dbus_gvalue_marshal (&subiter, key)) |
|
1519 goto lose; |
|
1520 |
|
1521 if (!_dbus_gvalue_marshal (&subiter, value)) |
|
1522 goto lose; |
|
1523 |
|
1524 if (!dbus_message_iter_close_container (hashdata->iter, &subiter)) |
|
1525 goto lose; |
|
1526 |
|
1527 return; |
|
1528 lose: |
|
1529 hashdata->err = TRUE; |
|
1530 } |
|
1531 |
|
1532 static gboolean |
|
1533 marshal_map (DBusMessageIter *iter, |
|
1534 const GValue *value) |
|
1535 { |
|
1536 GType gtype; |
|
1537 DBusMessageIter arr_iter; |
|
1538 gboolean ret; |
|
1539 struct DBusGLibHashMarshalData hashdata; |
|
1540 char *key_sig; |
|
1541 char *value_sig; |
|
1542 GType key_type; |
|
1543 GType value_type; |
|
1544 char *entry_sig; |
|
1545 char *array_sig; |
|
1546 |
|
1547 gtype = G_VALUE_TYPE (value); |
|
1548 |
|
1549 ret = FALSE; |
|
1550 |
|
1551 key_type = dbus_g_type_get_map_key_specialization (gtype); |
|
1552 g_assert (_dbus_gtype_is_valid_hash_key (key_type)); |
|
1553 value_type = dbus_g_type_get_map_value_specialization (gtype); |
|
1554 g_assert (_dbus_gtype_is_valid_hash_value (value_type)); |
|
1555 |
|
1556 key_sig = _dbus_gtype_to_signature (key_type); |
|
1557 if (!key_sig) |
|
1558 { |
|
1559 g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (key_type)); |
|
1560 return FALSE; |
|
1561 } |
|
1562 value_sig = _dbus_gtype_to_signature (value_type); |
|
1563 if (!value_sig) |
|
1564 { |
|
1565 g_free (key_sig); |
|
1566 g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (value_type)); |
|
1567 return FALSE; |
|
1568 } |
|
1569 entry_sig = g_strdup_printf ("%s%s", key_sig, value_sig); |
|
1570 g_free (key_sig); |
|
1571 g_free (value_sig); |
|
1572 array_sig = g_strdup_printf ("%c%s%c", |
|
1573 DBUS_DICT_ENTRY_BEGIN_CHAR, |
|
1574 entry_sig, |
|
1575 DBUS_DICT_ENTRY_END_CHAR); |
|
1576 if (!dbus_message_iter_open_container (iter, |
|
1577 DBUS_TYPE_ARRAY, |
|
1578 array_sig, |
|
1579 &arr_iter)) |
|
1580 goto lose; |
|
1581 |
|
1582 hashdata.iter = &arr_iter; |
|
1583 hashdata.err = FALSE; |
|
1584 hashdata.entry_sig = entry_sig; |
|
1585 |
|
1586 dbus_g_type_map_value_iterate (value, |
|
1587 marshal_map_entry, |
|
1588 &hashdata); |
|
1589 |
|
1590 if (!dbus_message_iter_close_container (iter, &arr_iter)) |
|
1591 goto lose; |
|
1592 |
|
1593 out: |
|
1594 g_free (entry_sig); |
|
1595 g_free (array_sig); |
|
1596 return !hashdata.err; |
|
1597 lose: |
|
1598 hashdata.err = TRUE; |
|
1599 goto out; |
|
1600 } |
|
1601 |
|
1602 static gboolean |
|
1603 marshal_struct (DBusMessageIter *iter, |
|
1604 const GValue *value) |
|
1605 { |
|
1606 GType gtype; |
|
1607 DBusMessageIter subiter; |
|
1608 gboolean ret; |
|
1609 guint size, i; |
|
1610 GValue val = {0,}; |
|
1611 |
|
1612 gtype = G_VALUE_TYPE (value); |
|
1613 |
|
1614 ret = FALSE; |
|
1615 |
|
1616 size = dbus_g_type_get_struct_size (gtype); |
|
1617 |
|
1618 if (!dbus_message_iter_open_container (iter, |
|
1619 DBUS_TYPE_STRUCT, |
|
1620 NULL, |
|
1621 &subiter)) |
|
1622 goto oom; |
|
1623 |
|
1624 for (i = 0; i < size; i++) |
|
1625 { |
|
1626 g_value_init (&val, dbus_g_type_get_struct_member_type |
|
1627 (G_VALUE_TYPE(value), i)); |
|
1628 if (!dbus_g_type_struct_get_member (value, i, &val)) |
|
1629 return FALSE; |
|
1630 if (!_dbus_gvalue_marshal (&subiter, &val)) |
|
1631 return FALSE; |
|
1632 g_value_unset(&val); |
|
1633 } |
|
1634 |
|
1635 if (!dbus_message_iter_close_container (iter, &subiter)) |
|
1636 goto oom; |
|
1637 |
|
1638 return TRUE; |
|
1639 oom: |
|
1640 g_error ("out of memory"); |
|
1641 return FALSE; |
|
1642 } |
|
1643 |
|
1644 static gboolean |
|
1645 marshal_variant (DBusMessageIter *iter, |
|
1646 const GValue *value) |
|
1647 { |
|
1648 GType value_gtype; |
|
1649 DBusMessageIter subiter; |
|
1650 char *variant_sig; |
|
1651 GValue *real_value; |
|
1652 gboolean ret = FALSE; |
|
1653 |
|
1654 real_value = g_value_get_boxed (value); |
|
1655 value_gtype = G_VALUE_TYPE (real_value); |
|
1656 |
|
1657 variant_sig = _dbus_gvalue_to_signature (real_value); |
|
1658 if (variant_sig == NULL) |
|
1659 { |
|
1660 g_warning ("Cannot marshal type \"%s\" in variant", g_type_name (value_gtype)); |
|
1661 return FALSE; |
|
1662 } |
|
1663 |
|
1664 if (!dbus_message_iter_open_container (iter, |
|
1665 DBUS_TYPE_VARIANT, |
|
1666 variant_sig, |
|
1667 &subiter)) |
|
1668 goto out; |
|
1669 |
|
1670 if (!_dbus_gvalue_marshal (&subiter, real_value)) |
|
1671 goto out; |
|
1672 |
|
1673 if (!dbus_message_iter_close_container (iter, &subiter)) |
|
1674 goto out; |
|
1675 |
|
1676 ret = TRUE; |
|
1677 out: |
|
1678 g_free (variant_sig); |
|
1679 return ret; |
|
1680 } |
|
1681 |
|
1682 static DBusGValueMarshalFunc |
|
1683 get_type_marshaller (GType type) |
|
1684 { |
|
1685 DBusGTypeMarshalData *typedata; |
|
1686 |
|
1687 typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ()); |
|
1688 if (typedata == NULL) |
|
1689 { |
|
1690 if (g_type_is_a (type, G_TYPE_VALUE_ARRAY)) |
|
1691 return marshal_valuearray; |
|
1692 if (dbus_g_type_is_collection (type)) |
|
1693 return marshal_collection; |
|
1694 if (dbus_g_type_is_map (type)) |
|
1695 return marshal_map; |
|
1696 if (dbus_g_type_is_struct (type)) |
|
1697 return marshal_struct; |
|
1698 |
|
1699 g_warning ("No marshaller registered for type \"%s\"", g_type_name (type)); |
|
1700 return NULL; |
|
1701 } |
|
1702 g_assert (typedata->vtable); |
|
1703 return typedata->vtable->marshaller; |
|
1704 } |
|
1705 |
|
1706 typedef struct |
|
1707 { |
|
1708 DBusMessageIter *iter; |
|
1709 DBusGValueMarshalFunc marshaller; |
|
1710 gboolean err; |
|
1711 } DBusGValueCollectionMarshalData; |
|
1712 |
|
1713 static void |
|
1714 collection_marshal_iterator (const GValue *eltval, |
|
1715 gpointer user_data) |
|
1716 { |
|
1717 DBusGValueCollectionMarshalData *data = user_data; |
|
1718 |
|
1719 if (data->err) |
|
1720 return; |
|
1721 |
|
1722 if (!data->marshaller (data->iter, eltval)) |
|
1723 data->err = TRUE; |
|
1724 } |
|
1725 |
|
1726 static gboolean |
|
1727 marshal_collection (DBusMessageIter *iter, |
|
1728 const GValue *value) |
|
1729 { |
|
1730 GType coltype; |
|
1731 GType subtype; |
|
1732 |
|
1733 coltype = G_VALUE_TYPE (value); |
|
1734 subtype = dbus_g_type_get_collection_specialization (coltype); |
|
1735 |
|
1736 if (_dbus_g_type_is_fixed (subtype)) |
|
1737 return marshal_collection_array (iter, value); |
|
1738 else |
|
1739 return marshal_collection_ptrarray (iter, value); |
|
1740 } |
|
1741 |
|
1742 static gboolean |
|
1743 marshal_collection_ptrarray (DBusMessageIter *iter, |
|
1744 const GValue *value) |
|
1745 { |
|
1746 GType coltype; |
|
1747 GType elt_gtype; |
|
1748 DBusGValueCollectionMarshalData data; |
|
1749 DBusMessageIter subiter; |
|
1750 char *elt_sig; |
|
1751 |
|
1752 coltype = G_VALUE_TYPE (value); |
|
1753 elt_gtype = dbus_g_type_get_collection_specialization (coltype); |
|
1754 data.marshaller = get_type_marshaller (elt_gtype); |
|
1755 if (!data.marshaller) |
|
1756 return FALSE; |
|
1757 |
|
1758 elt_sig = _dbus_gtype_to_signature (elt_gtype); |
|
1759 if (!elt_sig) |
|
1760 { |
|
1761 g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype)); |
|
1762 return FALSE; |
|
1763 } |
|
1764 |
|
1765 if (!dbus_message_iter_open_container (iter, |
|
1766 DBUS_TYPE_ARRAY, |
|
1767 elt_sig, |
|
1768 &subiter)) |
|
1769 goto oom; |
|
1770 g_free (elt_sig); |
|
1771 |
|
1772 data.iter = &subiter; |
|
1773 data.err = FALSE; |
|
1774 |
|
1775 dbus_g_type_collection_value_iterate (value, |
|
1776 collection_marshal_iterator, |
|
1777 &data); |
|
1778 |
|
1779 if (!dbus_message_iter_close_container (iter, &subiter)) |
|
1780 goto oom; |
|
1781 |
|
1782 return !data.err; |
|
1783 oom: |
|
1784 g_error ("out of memory"); |
|
1785 return FALSE; |
|
1786 } |
|
1787 |
|
1788 |
|
1789 static gboolean |
|
1790 marshal_collection_array (DBusMessageIter *iter, |
|
1791 const GValue *value) |
|
1792 { |
|
1793 GType elt_gtype; |
|
1794 DBusMessageIter subiter; |
|
1795 GArray *array; |
|
1796 guint elt_size; |
|
1797 char *subsignature_str; |
|
1798 |
|
1799 elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value)); |
|
1800 g_assert (_dbus_g_type_is_fixed (elt_gtype)); |
|
1801 subsignature_str = _dbus_gtype_to_signature (elt_gtype); |
|
1802 if (!subsignature_str) |
|
1803 { |
|
1804 g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype)); |
|
1805 return FALSE; |
|
1806 } |
|
1807 |
|
1808 elt_size = _dbus_g_type_fixed_get_size (elt_gtype); |
|
1809 |
|
1810 array = g_value_get_boxed (value); |
|
1811 |
|
1812 if (!dbus_message_iter_open_container (iter, |
|
1813 DBUS_TYPE_ARRAY, |
|
1814 subsignature_str, |
|
1815 &subiter)) |
|
1816 goto oom; |
|
1817 |
|
1818 /* TODO - This assumes that basic values are the same size |
|
1819 * is this always true? If it is we can probably avoid |
|
1820 * a lot of the overhead in _marshal_basic_instance... |
|
1821 */ |
|
1822 if (!array || !dbus_message_iter_append_fixed_array (&subiter, |
|
1823 subsignature_str[0], |
|
1824 &(array->data), |
|
1825 array->len)) |
|
1826 goto oom; |
|
1827 |
|
1828 if (!dbus_message_iter_close_container (iter, &subiter)) |
|
1829 goto oom; |
|
1830 g_free (subsignature_str); |
|
1831 return TRUE; |
|
1832 oom: |
|
1833 g_error ("out of memory"); |
|
1834 return FALSE; |
|
1835 } |
|
1836 |
|
1837 gboolean |
|
1838 _dbus_gvalue_marshal (DBusMessageIter *iter, |
|
1839 const GValue *value) |
|
1840 { |
|
1841 GType gtype; |
|
1842 DBusGValueMarshalFunc marshaller; |
|
1843 |
|
1844 gtype = G_VALUE_TYPE (value); |
|
1845 |
|
1846 marshaller = get_type_marshaller (gtype); |
|
1847 if (marshaller == NULL) |
|
1848 return FALSE; |
|
1849 return marshaller (iter, value); |
|
1850 } |
|
1851 |
|
1852 #ifdef DBUS_BUILD_TESTS |
|
1853 |
|
1854 static void |
|
1855 assert_type_maps_to (GType gtype, const char *expected_sig) |
|
1856 { |
|
1857 char *sig; |
|
1858 sig = _dbus_gtype_to_signature (gtype); |
|
1859 g_assert (sig != NULL); |
|
1860 g_assert (!strcmp (expected_sig, sig)); |
|
1861 g_free (sig); |
|
1862 } |
|
1863 |
|
1864 static void |
|
1865 assert_signature_maps_to (const char *sig, GType expected_gtype) |
|
1866 { |
|
1867 g_assert (_dbus_gtype_from_signature (sig, TRUE) == expected_gtype); |
|
1868 } |
|
1869 |
|
1870 static void |
|
1871 assert_bidirectional_mapping (GType gtype, const char *expected_sig) |
|
1872 { |
|
1873 assert_type_maps_to (gtype, expected_sig); |
|
1874 assert_signature_maps_to (expected_sig, gtype); |
|
1875 } |
|
1876 |
|
1877 /** |
|
1878 * @ingroup DBusGLibInternals |
|
1879 * @test_data_dir: |
|
1880 * |
|
1881 * Unit test for general glib stuff |
|
1882 * Returns: #TRUE on success. |
|
1883 */ |
|
1884 #ifdef __SYMBIAN32__ |
|
1885 EXPORT_C |
|
1886 #endif |
|
1887 gboolean |
|
1888 _dbus_gvalue_test (const char *test_data_dir) |
|
1889 { |
|
1890 _dbus_g_value_types_init (); |
|
1891 |
|
1892 assert_bidirectional_mapping (G_TYPE_STRING, DBUS_TYPE_STRING_AS_STRING); |
|
1893 assert_bidirectional_mapping (G_TYPE_UCHAR, DBUS_TYPE_BYTE_AS_STRING); |
|
1894 assert_bidirectional_mapping (G_TYPE_UINT, DBUS_TYPE_UINT32_AS_STRING); |
|
1895 |
|
1896 assert_bidirectional_mapping (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), |
|
1897 DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING); |
|
1898 assert_bidirectional_mapping (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), |
|
1899 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING); |
|
1900 assert_bidirectional_mapping (dbus_g_type_get_collection ("GArray", G_TYPE_INT), |
|
1901 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING); |
|
1902 |
|
1903 assert_bidirectional_mapping (dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID), |
|
1904 DBUS_STRUCT_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING DBUS_STRUCT_END_CHAR_AS_STRING ); |
|
1905 return TRUE; |
|
1906 } |
|
1907 |
|
1908 #endif /* DBUS_BUILD_TESTS */ |