Update contrib.
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-gvalue.c GValue to-from DBusMessageIter
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
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.
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.
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
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"
35 #include <glib/gi18n.h>
37 #define _(x) dgettext (GETTEXT_PACKAGE, x)
46 #include "dbus/dbus-signature.h"
48 #include "libdbus_glib_wsd_solution.h"
51 static gboolean demarshal_static_variant (DBusGValueMarshalCtx *context,
52 DBusMessageIter *iter,
57 static gboolean marshal_basic (DBusMessageIter *iter,
59 static gboolean demarshal_basic (DBusGValueMarshalCtx *context,
60 DBusMessageIter *iter,
63 static gboolean marshal_strv (DBusMessageIter *iter,
65 static gboolean demarshal_strv (DBusGValueMarshalCtx *context,
66 DBusMessageIter *iter,
69 static gboolean marshal_valuearray (DBusMessageIter *iter,
71 static gboolean demarshal_valuearray (DBusGValueMarshalCtx *context,
72 DBusMessageIter *iter,
75 static gboolean marshal_variant (DBusMessageIter *iter,
77 static gboolean demarshal_variant (DBusGValueMarshalCtx *context,
78 DBusMessageIter *iter,
81 static gboolean marshal_proxy (DBusMessageIter *iter,
83 static gboolean demarshal_proxy (DBusGValueMarshalCtx *context,
84 DBusMessageIter *iter,
87 static gboolean marshal_object_path (DBusMessageIter *iter,
89 static gboolean demarshal_object_path (DBusGValueMarshalCtx *context,
90 DBusMessageIter *iter,
93 static gboolean marshal_object (DBusMessageIter *iter,
95 static gboolean demarshal_object (DBusGValueMarshalCtx *context,
96 DBusMessageIter *iter,
99 static gboolean marshal_map (DBusMessageIter *iter,
100 const GValue *value);
101 static gboolean demarshal_map (DBusGValueMarshalCtx *context,
102 DBusMessageIter *iter,
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,
116 static gboolean demarshal_collection_ptrarray (DBusGValueMarshalCtx *context,
117 DBusMessageIter *iter,
120 static gboolean demarshal_collection_array (DBusGValueMarshalCtx *context,
121 DBusMessageIter *iter,
124 static gboolean marshal_struct (DBusMessageIter *iter,
125 const GValue *value);
126 static gboolean demarshal_struct (DBusGValueMarshalCtx *context,
127 DBusMessageIter *iter,
132 typedef gboolean (*DBusGValueMarshalFunc) (DBusMessageIter *iter,
133 const GValue *value);
134 typedef gboolean (*DBusGValueDemarshalFunc) (DBusGValueMarshalCtx *context,
135 DBusMessageIter *iter,
140 DBusGValueMarshalFunc marshaller;
141 DBusGValueDemarshalFunc demarshaller;
142 } DBusGTypeMarshalVtable;
146 const DBusGTypeMarshalVtable *vtable;
147 } DBusGTypeMarshalData;
151 GET_STATIC_VAR_FROM_TLS(quark,dbus_gvalue,GQuark )
152 #define quark (*GET_DBUS_WSD_VAR_NAME(quark,dbus_gvalue,s)())
156 dbus_g_type_metadata_data_quark ()
162 quark = g_quark_from_static_string ("DBusGTypeMetaData");
168 set_type_metadata (GType type, const DBusGTypeMarshalData *data)
170 g_type_set_qdata (type, dbus_g_type_metadata_data_quark (), (gpointer) data);
174 register_basic (int typecode, const DBusGTypeMarshalData *typedata)
176 set_type_metadata (_dbus_gtype_from_basic_typecode (typecode), typedata);
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)())
186 _dbus_g_value_types_init (void)
190 static gboolean types_initialized;
193 static const DBusGTypeMarshalVtable basic_vtable = {
198 if (types_initialized)
201 dbus_g_type_specialized_init ();
202 _dbus_g_type_specialized_builtins_init ();
204 /* Register basic types */
206 static const DBusGTypeMarshalData typedata = {
207 DBUS_TYPE_BOOLEAN_AS_STRING,
210 register_basic (DBUS_TYPE_BOOLEAN, &typedata);
213 static const DBusGTypeMarshalData typedata = {
214 DBUS_TYPE_BYTE_AS_STRING,
217 register_basic (DBUS_TYPE_BYTE, &typedata);
220 static const DBusGTypeMarshalData typedata = {
221 DBUS_TYPE_INT16_AS_STRING,
224 register_basic (DBUS_TYPE_INT16, &typedata);
227 static const DBusGTypeMarshalData typedata = {
228 DBUS_TYPE_UINT16_AS_STRING,
231 register_basic (DBUS_TYPE_UINT16, &typedata);
234 static const DBusGTypeMarshalData typedata = {
235 DBUS_TYPE_UINT32_AS_STRING,
238 register_basic (DBUS_TYPE_UINT32, &typedata);
241 static const DBusGTypeMarshalData typedata = {
242 DBUS_TYPE_INT32_AS_STRING,
245 register_basic (DBUS_TYPE_INT32, &typedata);
248 static const DBusGTypeMarshalData typedata = {
249 DBUS_TYPE_UINT64_AS_STRING,
252 register_basic (DBUS_TYPE_UINT64, &typedata);
255 static const DBusGTypeMarshalData typedata = {
256 DBUS_TYPE_INT64_AS_STRING,
259 register_basic (DBUS_TYPE_INT64, &typedata);
262 static const DBusGTypeMarshalData typedata = {
263 DBUS_TYPE_DOUBLE_AS_STRING,
266 register_basic (DBUS_TYPE_DOUBLE, &typedata);
269 static const DBusGTypeMarshalData typedata = {
270 DBUS_TYPE_STRING_AS_STRING,
273 register_basic (DBUS_TYPE_STRING, &typedata);
275 /* fundamental GTypes that don't map 1:1 with D-BUS types */
277 static const DBusGTypeMarshalData typedata = {
278 DBUS_TYPE_BYTE_AS_STRING,
281 set_type_metadata (G_TYPE_CHAR, &typedata);
284 static const DBusGTypeMarshalData typedata = {
285 DBUS_TYPE_INT32_AS_STRING,
288 set_type_metadata (G_TYPE_LONG, &typedata);
291 static const DBusGTypeMarshalData typedata = {
292 DBUS_TYPE_UINT32_AS_STRING,
295 set_type_metadata (G_TYPE_ULONG, &typedata);
298 static const DBusGTypeMarshalData typedata = {
299 DBUS_TYPE_DOUBLE_AS_STRING,
302 set_type_metadata (G_TYPE_FLOAT, &typedata);
305 /* Register complex types with builtin GType mappings */
307 static const DBusGTypeMarshalVtable vtable = {
311 static const DBusGTypeMarshalData typedata = {
312 DBUS_TYPE_VARIANT_AS_STRING,
315 set_type_metadata (G_TYPE_VALUE, &typedata);
318 static const DBusGTypeMarshalVtable vtable = {
322 static const DBusGTypeMarshalData typedata = {
323 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
326 set_type_metadata (G_TYPE_STRV, &typedata);
330 /* Register some types specific to the D-BUS GLib bindings */
332 static const DBusGTypeMarshalVtable vtable = {
336 static const DBusGTypeMarshalData typedata = {
337 DBUS_TYPE_OBJECT_PATH_AS_STRING,
340 set_type_metadata (DBUS_TYPE_G_PROXY, &typedata);
344 static const DBusGTypeMarshalVtable vtable = {
346 demarshal_object_path
348 static const DBusGTypeMarshalData typedata = {
349 DBUS_TYPE_OBJECT_PATH_AS_STRING,
352 set_type_metadata (DBUS_TYPE_G_OBJECT_PATH, &typedata);
356 static const DBusGTypeMarshalVtable vtable = {
360 static const DBusGTypeMarshalData typedata = {
361 DBUS_TYPE_OBJECT_PATH_AS_STRING,
364 set_type_metadata (G_TYPE_OBJECT, &typedata);
367 types_initialized = TRUE;
371 * Get the GLib type ID for a DBusGObjectPath boxed type.
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)())
384 dbus_g_object_path_get_g_type (void)
387 static GType type_id = 0;
393 type_id = g_boxed_type_register_static ("DBusGObjectPath",
394 (GBoxedCopyFunc) g_strdup,
395 (GBoxedFreeFunc) g_free);
401 _dbus_gtype_to_signature (GType gtype)
404 DBusGTypeMarshalData *typedata;
406 if (dbus_g_type_is_collection (gtype))
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);
416 else if (dbus_g_type_is_map (gtype))
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);
431 else if (dbus_g_type_is_struct (gtype))
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++)
441 subsig = _dbus_gtype_to_signature (
442 dbus_g_type_get_struct_member_type (gtype, i));
443 g_string_append (sig, subsig);
446 g_string_append (sig, DBUS_STRUCT_END_CHAR_AS_STRING);
447 ret = g_string_free (sig, FALSE);
451 typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
452 if (typedata == NULL)
454 ret = g_strdup (typedata->sig);
460 _dbus_gvalue_to_signature (const GValue *val)
464 gtype = G_VALUE_TYPE (val);
465 if (g_type_is_a (gtype, G_TYPE_VALUE_ARRAY))
471 array = g_value_get_boxed (val);
473 str = g_string_new (DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
474 for (i = 0; i < array->n_values; i++)
477 sig = _dbus_gvalue_to_signature (g_value_array_get_nth (array, i));
478 g_string_append (str, sig);
481 g_string_append (str, DBUS_STRUCT_END_CHAR_AS_STRING);
483 return g_string_free (str, FALSE);
486 return _dbus_gtype_to_signature (gtype);
490 demarshal_basic (DBusGValueMarshalCtx *context,
491 DBusMessageIter *iter,
497 current_type = dbus_message_iter_get_arg_type (iter);
498 g_assert (dbus_type_is_basic (current_type));
500 switch (current_type)
502 case DBUS_TYPE_BOOLEAN:
505 dbus_message_iter_get_basic (iter, &bool);
506 g_value_set_boolean (value, bool);
512 dbus_message_iter_get_basic (iter, &byte);
513 g_value_set_uchar (value, byte);
516 case DBUS_TYPE_INT32:
519 dbus_message_iter_get_basic (iter, &intval);
520 g_value_set_int (value, intval);
523 case DBUS_TYPE_UINT32:
525 dbus_uint32_t intval;
526 dbus_message_iter_get_basic (iter, &intval);
527 g_value_set_uint (value, intval);
530 case DBUS_TYPE_INT64:
533 dbus_message_iter_get_basic (iter, &intval);
534 g_value_set_int64 (value, intval);
537 case DBUS_TYPE_UINT64:
539 dbus_uint64_t intval;
540 dbus_message_iter_get_basic (iter, &intval);
541 g_value_set_uint64 (value, intval);
544 case DBUS_TYPE_DOUBLE:
547 dbus_message_iter_get_basic (iter, &dval);
548 g_value_set_double (value, dval);
551 case DBUS_TYPE_INT16:
554 dbus_message_iter_get_basic (iter, &v);
555 g_value_set_int (value, v);
558 case DBUS_TYPE_UINT16:
561 dbus_message_iter_get_basic (iter, &v);
562 g_value_set_uint (value, v);
565 case DBUS_TYPE_STRING:
568 dbus_message_iter_get_basic (iter, &s);
569 g_value_set_string (value, s);
573 g_assert_not_reached ();
579 demarshal_static_variant (DBusGValueMarshalCtx *context,
580 DBusMessageIter *iter,
586 DBusMessageIter subiter;
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);
593 variant_type = _dbus_gtype_from_signature (sig, context->proxy != NULL);
594 if (variant_type != G_TYPE_INVALID)
596 g_value_init (value, variant_type);
598 if (!_dbus_gvalue_demarshal (context, &subiter, value, error))
609 demarshal_variant (DBusGValueMarshalCtx *context,
610 DBusMessageIter *iter,
616 variant_val = g_new0 (GValue, 1);
618 if (!demarshal_static_variant (context, iter, variant_val, error))
621 g_value_set_boxed_take_ownership (value, variant_val);
626 demarshal_proxy (DBusGValueMarshalCtx *context,
627 DBusMessageIter *iter,
631 DBusGProxy *new_proxy;
635 current_type = dbus_message_iter_get_arg_type (iter);
636 if (current_type != DBUS_TYPE_OBJECT_PATH)
640 DBUS_GERROR_INVALID_ARGS,
641 _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type);
645 g_assert (context->proxy != NULL);
647 dbus_message_iter_get_basic (iter, &objpath);
649 new_proxy = dbus_g_proxy_new_from_proxy (context->proxy, NULL, objpath);
650 g_value_set_object_take_ownership (value, new_proxy);
656 demarshal_object_path (DBusGValueMarshalCtx *context,
657 DBusMessageIter *iter,
664 current_type = dbus_message_iter_get_arg_type (iter);
665 if (current_type != DBUS_TYPE_OBJECT_PATH)
669 DBUS_GERROR_INVALID_ARGS,
670 _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type);
674 dbus_message_iter_get_basic (iter, &objpath);
676 g_value_set_boxed_take_ownership (value, g_strdup (objpath));
682 demarshal_object (DBusGValueMarshalCtx *context,
683 DBusMessageIter *iter,
691 current_type = dbus_message_iter_get_arg_type (iter);
692 if (current_type != DBUS_TYPE_OBJECT_PATH)
696 DBUS_GERROR_INVALID_ARGS,
697 _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type);
700 g_assert (context->proxy == NULL);
702 dbus_message_iter_get_basic (iter, &objpath);
704 obj = dbus_g_connection_lookup_g_object (context->gconnection, objpath);
709 DBUS_GERROR_INVALID_ARGS,
710 _("Unregistered object at path '%s'"),
714 g_value_set_object (value, obj);
720 demarshal_strv (DBusGValueMarshalCtx *context,
721 DBusMessageIter *iter,
725 DBusMessageIter subiter;
731 current_type = dbus_message_iter_get_arg_type (iter);
732 if (current_type != DBUS_TYPE_ARRAY)
736 DBUS_GERROR_INVALID_ARGS,
737 _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type);
741 dbus_message_iter_recurse (iter, &subiter);
743 current_type = dbus_message_iter_get_arg_type (&subiter);
744 if (current_type != DBUS_TYPE_INVALID
745 && current_type != DBUS_TYPE_STRING)
749 DBUS_GERROR_INVALID_ARGS,
750 _("Expected D-BUS string, got type code \'%c\'"), (guchar) current_type);
754 len = dbus_message_iter_get_array_len (&subiter);
756 ret = g_malloc (sizeof (char *) * (len + 1));
759 while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
762 g_assert (current_type == DBUS_TYPE_STRING);
764 dbus_message_iter_get_basic (&subiter, &(ret[i]));
765 ret[i] = g_strdup (ret[i]);
767 dbus_message_iter_next (&subiter);
771 g_value_set_boxed_take_ownership (value, ret);
777 demarshal_valuearray (DBusGValueMarshalCtx *context,
778 DBusMessageIter *iter,
784 DBusMessageIter subiter;
786 current_type = dbus_message_iter_get_arg_type (iter);
787 if (current_type != DBUS_TYPE_STRUCT)
791 DBUS_GERROR_INVALID_ARGS,
792 _("Expected D-BUS struct, got type code \'%c\'"), (guchar) current_type);
796 dbus_message_iter_recurse (iter, &subiter);
798 ret = g_value_array_new (12);
800 while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
806 g_value_array_append (ret, NULL);
807 val = g_value_array_get_nth (ret, ret->n_values - 1);
809 current_sig = dbus_message_iter_get_signature (&subiter);
810 elt_type = _dbus_gtype_from_signature (current_sig, TRUE);
812 dbus_free (current_sig);
813 if (elt_type == G_TYPE_INVALID)
815 g_value_array_free (ret);
818 DBUS_GERROR_INVALID_ARGS,
819 _("Couldn't demarshal argument with signature \"%s\""), current_sig);
823 g_value_init (val, elt_type);
825 if (!_dbus_gvalue_demarshal (context, &subiter, val, error))
827 g_value_array_free (ret);
831 dbus_message_iter_next (&subiter);
834 g_value_set_boxed_take_ownership (value, ret);
840 demarshal_map (DBusGValueMarshalCtx *context,
841 DBusMessageIter *iter,
846 DBusMessageIter subiter;
851 DBusGTypeSpecializedAppendContext appendctx;
853 current_type = dbus_message_iter_get_arg_type (iter);
854 if (current_type != DBUS_TYPE_ARRAY)
858 DBUS_GERROR_INVALID_ARGS,
859 _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type);
863 gtype = G_VALUE_TYPE (value);
865 dbus_message_iter_recurse (iter, &subiter);
867 current_type = dbus_message_iter_get_arg_type (&subiter);
868 if (current_type != DBUS_TYPE_INVALID
869 && current_type != DBUS_TYPE_DICT_ENTRY)
873 DBUS_GERROR_INVALID_ARGS,
874 _("Expected D-BUS dict entry, got type code \'%c\'"), (guchar) current_type);
878 key_gtype = dbus_g_type_get_map_key_specialization (gtype);
879 value_gtype = dbus_g_type_get_map_value_specialization (gtype);
881 ret = dbus_g_type_specialized_construct (gtype);
882 g_value_set_boxed_take_ownership (value, ret);
884 dbus_g_type_specialized_init_append (value, &appendctx);
886 while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
888 DBusMessageIter entry_iter;
889 GValue key_value = {0,};
890 GValue value_value = {0,};
892 current_type = dbus_message_iter_get_arg_type (&subiter);
893 g_assert (current_type == DBUS_TYPE_DICT_ENTRY);
895 dbus_message_iter_recurse (&subiter, &entry_iter);
897 g_value_init (&key_value, key_gtype);
898 if (!_dbus_gvalue_demarshal (context,
904 dbus_message_iter_next (&entry_iter);
906 g_value_init (&value_value, value_gtype);
907 if (!_dbus_gvalue_demarshal (context,
913 dbus_g_type_specialized_map_append (&appendctx, &key_value, &value_value);
914 /* Ownership of values passes to map, don't unset */
916 dbus_message_iter_next (&subiter);
923 demarshal_struct (DBusGValueMarshalCtx *context,
924 DBusMessageIter *iter,
929 DBusMessageIter subiter;
934 current_type = dbus_message_iter_get_arg_type (iter);
935 if (current_type != DBUS_TYPE_STRUCT)
939 DBUS_GERROR_INVALID_ARGS,
940 _("Expected D-BUS struct, got type code \'%c\'"), (guchar) current_type);
944 dbus_message_iter_recurse (iter, &subiter);
946 g_value_set_boxed_take_ownership (value,
947 dbus_g_type_specialized_construct (G_VALUE_TYPE (value)));
949 size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
951 for (i=0; i < size; i++)
954 elt_type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE(value), i);
955 if (elt_type == G_TYPE_INVALID)
957 g_value_unset (value);
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);
967 g_value_init (&val, elt_type);
969 if (!_dbus_gvalue_demarshal (context, &subiter, &val, error))
971 g_value_unset (&val);
972 g_value_unset (value);
975 if (!dbus_g_type_struct_set_member (value, i, &val))
977 g_value_unset (&val);
978 g_value_unset (value);
982 dbus_message_iter_next (&subiter);
983 g_value_unset (&val);
986 g_assert (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_INVALID);
992 static DBusGValueDemarshalFunc
993 get_type_demarshaller (GType type)
995 DBusGTypeMarshalData *typedata;
997 typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ());
998 if (typedata == NULL)
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;
1009 g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type));
1012 g_assert (typedata->vtable);
1013 return typedata->vtable->demarshaller;
1017 demarshal_collection (DBusGValueMarshalCtx *context,
1018 DBusMessageIter *iter,
1025 coltype = G_VALUE_TYPE (value);
1026 subtype = dbus_g_type_get_collection_specialization (coltype);
1028 if (_dbus_g_type_is_fixed (subtype))
1029 return demarshal_collection_array (context, iter, value, error);
1031 return demarshal_collection_ptrarray (context, iter, value, error);
1035 demarshal_collection_ptrarray (DBusGValueMarshalCtx *context,
1036 DBusMessageIter *iter,
1043 DBusGTypeSpecializedAppendContext ctx;
1044 DBusGValueDemarshalFunc demarshaller;
1045 DBusMessageIter subiter;
1048 current_type = dbus_message_iter_get_arg_type (iter);
1050 if (current_type != DBUS_TYPE_ARRAY)
1054 DBUS_GERROR_INVALID_ARGS,
1055 _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type);
1059 dbus_message_iter_recurse (iter, &subiter);
1061 coltype = G_VALUE_TYPE (value);
1062 subtype = dbus_g_type_get_collection_specialization (coltype);
1064 demarshaller = get_type_demarshaller (subtype);
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));
1077 instance = dbus_g_type_specialized_construct (coltype);
1078 g_value_set_boxed_take_ownership (value, instance);
1080 dbus_g_type_specialized_init_append (value, &ctx);
1082 while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
1084 GValue eltval = {0, };
1086 g_value_init (&eltval, subtype);
1088 if (!demarshaller (context, &subiter, &eltval, error))
1090 dbus_g_type_specialized_collection_end_append (&ctx);
1091 g_value_unset (value);
1094 dbus_g_type_specialized_collection_append (&ctx, &eltval);
1096 dbus_message_iter_next (&subiter);
1098 dbus_g_type_specialized_collection_end_append (&ctx);
1104 demarshal_collection_array (DBusGValueMarshalCtx *context,
1105 DBusMessageIter *iter,
1109 DBusMessageIter subiter;
1116 dbus_message_iter_recurse (iter, &subiter);
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));
1122 elt_size = _dbus_g_type_fixed_get_size (elt_gtype);
1124 ret = g_array_new (FALSE, TRUE, elt_size);
1127 dbus_message_iter_get_fixed_array (&subiter,
1130 g_assert (msgarray != NULL || msgarray_len == 0);
1133 g_array_append_vals (ret, msgarray, (guint) msgarray_len);
1135 g_value_set_boxed_take_ownership (value, ret);
1141 _dbus_gvalue_demarshal (DBusGValueMarshalCtx *context,
1142 DBusMessageIter *iter,
1147 DBusGValueDemarshalFunc demarshaller;
1149 gtype = G_VALUE_TYPE (value);
1151 demarshaller = get_type_demarshaller (gtype);
1153 if (demarshaller == NULL)
1157 DBUS_GERROR_INVALID_ARGS,
1158 _("No demarshaller registered for type \"%s\""),
1159 g_type_name (gtype));
1163 return demarshaller (context, iter, value, error);
1167 _dbus_gvalue_demarshal_variant (DBusGValueMarshalCtx *context,
1168 DBusMessageIter *iter,
1172 return demarshal_static_variant (context, iter, value, error);
1176 _dbus_gvalue_demarshal_message (DBusGValueMarshalCtx *context,
1177 DBusMessage *message,
1183 DBusMessageIter iter;
1187 ret = g_value_array_new (6); /* 6 is a typical maximum for arguments */
1189 dbus_message_iter_init (message, &iter);
1191 while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
1196 if (index_ >= n_types)
1198 g_set_error (error, DBUS_GERROR,
1199 DBUS_GERROR_INVALID_ARGS,
1200 _("Too many arguments in message"));
1204 g_value_array_append (ret, NULL);
1205 value = g_value_array_get_nth (ret, index_);
1207 gtype = types[index_];
1208 g_value_init (value, gtype);
1210 if (!_dbus_gvalue_demarshal (context, &iter, value, error))
1212 dbus_message_iter_next (&iter);
1215 if (index_ < n_types)
1217 g_set_error (error, DBUS_GERROR,
1218 DBUS_GERROR_INVALID_ARGS,
1219 _("Too few arguments in message"));
1225 g_value_array_free (ret);
1230 marshal_basic (DBusMessageIter *iter, const GValue *value)
1234 value_type = G_VALUE_TYPE (value);
1240 char b = g_value_get_char (value);
1241 if (!dbus_message_iter_append_basic (iter,
1249 unsigned char b = g_value_get_uchar (value);
1250 if (!dbus_message_iter_append_basic (iter,
1256 case G_TYPE_BOOLEAN:
1258 dbus_bool_t b = g_value_get_boolean (value);
1259 if (!dbus_message_iter_append_basic (iter,
1267 dbus_int32_t v = g_value_get_int (value);
1268 if (!dbus_message_iter_append_basic (iter,
1276 dbus_uint32_t v = g_value_get_uint (value);
1277 if (!dbus_message_iter_append_basic (iter,
1285 dbus_int32_t v = g_value_get_long (value);
1286 if (!dbus_message_iter_append_basic (iter,
1294 dbus_uint32_t v = g_value_get_ulong (value);
1295 if (!dbus_message_iter_append_basic (iter,
1303 gint64 v = g_value_get_int64 (value);
1304 if (!dbus_message_iter_append_basic (iter,
1312 guint64 v = g_value_get_uint64 (value);
1313 if (!dbus_message_iter_append_basic (iter,
1321 double v = g_value_get_float (value);
1323 if (!dbus_message_iter_append_basic (iter,
1331 double v = g_value_get_double (value);
1333 if (!dbus_message_iter_append_basic (iter,
1340 /* FIXME, the GValue string may not be valid UTF-8 */
1342 const char *v = g_value_get_string (value);
1345 if (!dbus_message_iter_append_basic (iter,
1354 g_assert_not_reached ();
1360 g_error ("no memory");
1365 marshal_strv (DBusMessageIter *iter,
1366 const GValue *value)
1368 DBusMessageIter subiter;
1371 gboolean ret = FALSE;
1373 g_assert (G_VALUE_TYPE (value) == g_strv_get_type ());
1375 array = g_value_get_boxed (value);
1377 if (!dbus_message_iter_open_container (iter,
1385 for (elt = array; *elt; elt++)
1387 if (!dbus_message_iter_append_basic (&subiter,
1394 if (!dbus_message_iter_close_container (iter, &subiter))
1402 marshal_valuearray (DBusMessageIter *iter,
1403 const GValue *value)
1407 DBusMessageIter subiter;
1409 g_assert (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY);
1411 array = g_value_get_boxed (value);
1413 if (!dbus_message_iter_open_container (iter,
1421 for (i = 0; i < array->n_values; i++)
1423 if (!_dbus_gvalue_marshal (&subiter, g_value_array_get_nth (array, i)))
1428 if (!dbus_message_iter_close_container (iter, &subiter))
1433 g_error ("out of memory");
1438 marshal_proxy (DBusMessageIter *iter,
1439 const GValue *value)
1444 g_assert (G_VALUE_TYPE (value) == dbus_g_proxy_get_type ());
1446 proxy = g_value_get_object (value);
1447 path = dbus_g_proxy_get_path (proxy);
1449 if (!dbus_message_iter_append_basic (iter,
1450 DBUS_TYPE_OBJECT_PATH,
1457 marshal_object_path (DBusMessageIter *iter,
1458 const GValue *value)
1462 g_assert (G_VALUE_TYPE (value) == DBUS_TYPE_G_OBJECT_PATH);
1464 path = (const char*) g_value_get_boxed (value);
1466 if (!dbus_message_iter_append_basic (iter,
1467 DBUS_TYPE_OBJECT_PATH,
1474 marshal_object (DBusMessageIter *iter,
1475 const GValue *value)
1480 obj = g_value_get_object (value);
1481 path = _dbus_gobject_get_path (obj);
1484 /* FIXME should throw error */
1487 if (!dbus_message_iter_append_basic (iter,
1488 DBUS_TYPE_OBJECT_PATH,
1494 struct DBusGLibHashMarshalData
1496 const char *entry_sig;
1497 DBusMessageIter *iter;
1502 marshal_map_entry (const GValue *key,
1503 const GValue *value,
1506 struct DBusGLibHashMarshalData *hashdata = data;
1507 DBusMessageIter subiter;
1512 if (!dbus_message_iter_open_container (hashdata->iter,
1513 DBUS_TYPE_DICT_ENTRY,
1518 if (!_dbus_gvalue_marshal (&subiter, key))
1521 if (!_dbus_gvalue_marshal (&subiter, value))
1524 if (!dbus_message_iter_close_container (hashdata->iter, &subiter))
1529 hashdata->err = TRUE;
1533 marshal_map (DBusMessageIter *iter,
1534 const GValue *value)
1537 DBusMessageIter arr_iter;
1539 struct DBusGLibHashMarshalData hashdata;
1547 gtype = G_VALUE_TYPE (value);
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));
1556 key_sig = _dbus_gtype_to_signature (key_type);
1559 g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (key_type));
1562 value_sig = _dbus_gtype_to_signature (value_type);
1566 g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (value_type));
1569 entry_sig = g_strdup_printf ("%s%s", key_sig, value_sig);
1572 array_sig = g_strdup_printf ("%c%s%c",
1573 DBUS_DICT_ENTRY_BEGIN_CHAR,
1575 DBUS_DICT_ENTRY_END_CHAR);
1576 if (!dbus_message_iter_open_container (iter,
1582 hashdata.iter = &arr_iter;
1583 hashdata.err = FALSE;
1584 hashdata.entry_sig = entry_sig;
1586 dbus_g_type_map_value_iterate (value,
1590 if (!dbus_message_iter_close_container (iter, &arr_iter))
1596 return !hashdata.err;
1598 hashdata.err = TRUE;
1603 marshal_struct (DBusMessageIter *iter,
1604 const GValue *value)
1607 DBusMessageIter subiter;
1612 gtype = G_VALUE_TYPE (value);
1616 size = dbus_g_type_get_struct_size (gtype);
1618 if (!dbus_message_iter_open_container (iter,
1624 for (i = 0; i < size; i++)
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))
1630 if (!_dbus_gvalue_marshal (&subiter, &val))
1632 g_value_unset(&val);
1635 if (!dbus_message_iter_close_container (iter, &subiter))
1640 g_error ("out of memory");
1645 marshal_variant (DBusMessageIter *iter,
1646 const GValue *value)
1649 DBusMessageIter subiter;
1652 gboolean ret = FALSE;
1654 real_value = g_value_get_boxed (value);
1655 value_gtype = G_VALUE_TYPE (real_value);
1657 variant_sig = _dbus_gvalue_to_signature (real_value);
1658 if (variant_sig == NULL)
1660 g_warning ("Cannot marshal type \"%s\" in variant", g_type_name (value_gtype));
1664 if (!dbus_message_iter_open_container (iter,
1670 if (!_dbus_gvalue_marshal (&subiter, real_value))
1673 if (!dbus_message_iter_close_container (iter, &subiter))
1678 g_free (variant_sig);
1682 static DBusGValueMarshalFunc
1683 get_type_marshaller (GType type)
1685 DBusGTypeMarshalData *typedata;
1687 typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ());
1688 if (typedata == NULL)
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))
1696 if (dbus_g_type_is_struct (type))
1697 return marshal_struct;
1699 g_warning ("No marshaller registered for type \"%s\"", g_type_name (type));
1702 g_assert (typedata->vtable);
1703 return typedata->vtable->marshaller;
1708 DBusMessageIter *iter;
1709 DBusGValueMarshalFunc marshaller;
1711 } DBusGValueCollectionMarshalData;
1714 collection_marshal_iterator (const GValue *eltval,
1717 DBusGValueCollectionMarshalData *data = user_data;
1722 if (!data->marshaller (data->iter, eltval))
1727 marshal_collection (DBusMessageIter *iter,
1728 const GValue *value)
1733 coltype = G_VALUE_TYPE (value);
1734 subtype = dbus_g_type_get_collection_specialization (coltype);
1736 if (_dbus_g_type_is_fixed (subtype))
1737 return marshal_collection_array (iter, value);
1739 return marshal_collection_ptrarray (iter, value);
1743 marshal_collection_ptrarray (DBusMessageIter *iter,
1744 const GValue *value)
1748 DBusGValueCollectionMarshalData data;
1749 DBusMessageIter subiter;
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)
1758 elt_sig = _dbus_gtype_to_signature (elt_gtype);
1761 g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype));
1765 if (!dbus_message_iter_open_container (iter,
1772 data.iter = &subiter;
1775 dbus_g_type_collection_value_iterate (value,
1776 collection_marshal_iterator,
1779 if (!dbus_message_iter_close_container (iter, &subiter))
1784 g_error ("out of memory");
1790 marshal_collection_array (DBusMessageIter *iter,
1791 const GValue *value)
1794 DBusMessageIter subiter;
1797 char *subsignature_str;
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)
1804 g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype));
1808 elt_size = _dbus_g_type_fixed_get_size (elt_gtype);
1810 array = g_value_get_boxed (value);
1812 if (!dbus_message_iter_open_container (iter,
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...
1822 if (!array || !dbus_message_iter_append_fixed_array (&subiter,
1823 subsignature_str[0],
1828 if (!dbus_message_iter_close_container (iter, &subiter))
1830 g_free (subsignature_str);
1833 g_error ("out of memory");
1838 _dbus_gvalue_marshal (DBusMessageIter *iter,
1839 const GValue *value)
1842 DBusGValueMarshalFunc marshaller;
1844 gtype = G_VALUE_TYPE (value);
1846 marshaller = get_type_marshaller (gtype);
1847 if (marshaller == NULL)
1849 return marshaller (iter, value);
1852 #ifdef DBUS_BUILD_TESTS
1855 assert_type_maps_to (GType gtype, const char *expected_sig)
1858 sig = _dbus_gtype_to_signature (gtype);
1859 g_assert (sig != NULL);
1860 g_assert (!strcmp (expected_sig, sig));
1865 assert_signature_maps_to (const char *sig, GType expected_gtype)
1867 g_assert (_dbus_gtype_from_signature (sig, TRUE) == expected_gtype);
1871 assert_bidirectional_mapping (GType gtype, const char *expected_sig)
1873 assert_type_maps_to (gtype, expected_sig);
1874 assert_signature_maps_to (expected_sig, gtype);
1878 * @ingroup DBusGLibInternals
1881 * Unit test for general glib stuff
1882 * Returns: #TRUE on success.
1884 #ifdef __SYMBIAN32__
1888 _dbus_gvalue_test (const char *test_data_dir)
1890 _dbus_g_value_types_init ();
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);
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);
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 );
1908 #endif /* DBUS_BUILD_TESTS */