1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ofdbus/dbus-glib/dbus/dbus-gvalue.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1908 @@
1.4 +/* -*- mode: C; c-file-style: "gnu" -*- */
1.5 +/* dbus-gvalue.c GValue to-from DBusMessageIter
1.6 + *
1.7 + * Copyright (C) 2004 Ximian, Inc.
1.8 + * Copyright (C) 2005 Red Hat, Inc.
1.9 + * Portion Copyright © 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
1.10 + * Licensed under the Academic Free License version 2.1
1.11 + *
1.12 + * This program is free software; you can redistribute it and/or modify
1.13 + * it under the terms of the GNU General Public License as published by
1.14 + * the Free Software Foundation; either version 2 of the License, or
1.15 + * (at your option) any later version.
1.16 + *
1.17 + * This program is distributed in the hope that it will be useful,
1.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.20 + * GNU General Public License for more details.
1.21 + *
1.22 + * You should have received a copy of the GNU General Public License
1.23 + * along with this program; if not, write to the Free Software
1.24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.25 + *
1.26 + */
1.27 +
1.28 +#include "config.h"
1.29 +#include "dbus-gtest.h"
1.30 +#include "dbus-gvalue.h"
1.31 +#include "dbus-gsignature.h"
1.32 +#include "dbus-gobject.h"
1.33 +#include "dbus-gvalue-utils.h"
1.34 +#include "dbus/dbus-glib.h"
1.35 +#include <string.h>
1.36 +#include <glib.h>
1.37 +#ifndef __SYMBIAN32__
1.38 +#include <glib/gi18n.h>
1.39 +#include <libintl.h>
1.40 +#define _(x) dgettext (GETTEXT_PACKAGE, x)
1.41 +#define N_(x) x
1.42 +#else
1.43 +
1.44 +#define _(x) x
1.45 +#define N_(x) x
1.46 +#endif
1.47 +
1.48 +
1.49 +#include "dbus/dbus-signature.h"
1.50 +#ifdef __SYMBIAN32__
1.51 +#include "libdbus_glib_wsd_solution.h"
1.52 +#endif
1.53 +
1.54 +static gboolean demarshal_static_variant (DBusGValueMarshalCtx *context,
1.55 + DBusMessageIter *iter,
1.56 + GValue *value,
1.57 + GError **error);
1.58 +
1.59 +
1.60 +static gboolean marshal_basic (DBusMessageIter *iter,
1.61 + const GValue *value);
1.62 +static gboolean demarshal_basic (DBusGValueMarshalCtx *context,
1.63 + DBusMessageIter *iter,
1.64 + GValue *value,
1.65 + GError **error);
1.66 +static gboolean marshal_strv (DBusMessageIter *iter,
1.67 + const GValue *value);
1.68 +static gboolean demarshal_strv (DBusGValueMarshalCtx *context,
1.69 + DBusMessageIter *iter,
1.70 + GValue *value,
1.71 + GError **error);
1.72 +static gboolean marshal_valuearray (DBusMessageIter *iter,
1.73 + const GValue *value);
1.74 +static gboolean demarshal_valuearray (DBusGValueMarshalCtx *context,
1.75 + DBusMessageIter *iter,
1.76 + GValue *value,
1.77 + GError **error);
1.78 +static gboolean marshal_variant (DBusMessageIter *iter,
1.79 + const GValue *value);
1.80 +static gboolean demarshal_variant (DBusGValueMarshalCtx *context,
1.81 + DBusMessageIter *iter,
1.82 + GValue *value,
1.83 + GError **error);
1.84 +static gboolean marshal_proxy (DBusMessageIter *iter,
1.85 + const GValue *value);
1.86 +static gboolean demarshal_proxy (DBusGValueMarshalCtx *context,
1.87 + DBusMessageIter *iter,
1.88 + GValue *value,
1.89 + GError **error);
1.90 +static gboolean marshal_object_path (DBusMessageIter *iter,
1.91 + const GValue *value);
1.92 +static gboolean demarshal_object_path (DBusGValueMarshalCtx *context,
1.93 + DBusMessageIter *iter,
1.94 + GValue *value,
1.95 + GError **error);
1.96 +static gboolean marshal_object (DBusMessageIter *iter,
1.97 + const GValue *value);
1.98 +static gboolean demarshal_object (DBusGValueMarshalCtx *context,
1.99 + DBusMessageIter *iter,
1.100 + GValue *value,
1.101 + GError **error);
1.102 +static gboolean marshal_map (DBusMessageIter *iter,
1.103 + const GValue *value);
1.104 +static gboolean demarshal_map (DBusGValueMarshalCtx *context,
1.105 + DBusMessageIter *iter,
1.106 + GValue *value,
1.107 + GError **error);
1.108 +
1.109 +static gboolean marshal_collection (DBusMessageIter *iter,
1.110 + const GValue *value);
1.111 +static gboolean marshal_collection_ptrarray (DBusMessageIter *iter,
1.112 + const GValue *value);
1.113 +static gboolean marshal_collection_array (DBusMessageIter *iter,
1.114 + const GValue *value);
1.115 +static gboolean demarshal_collection (DBusGValueMarshalCtx *context,
1.116 + DBusMessageIter *iter,
1.117 + GValue *value,
1.118 + GError **error);
1.119 +static gboolean demarshal_collection_ptrarray (DBusGValueMarshalCtx *context,
1.120 + DBusMessageIter *iter,
1.121 + GValue *value,
1.122 + GError **error);
1.123 +static gboolean demarshal_collection_array (DBusGValueMarshalCtx *context,
1.124 + DBusMessageIter *iter,
1.125 + GValue *value,
1.126 + GError **error);
1.127 +static gboolean marshal_struct (DBusMessageIter *iter,
1.128 + const GValue *value);
1.129 +static gboolean demarshal_struct (DBusGValueMarshalCtx *context,
1.130 + DBusMessageIter *iter,
1.131 + GValue *value,
1.132 + GError **error);
1.133 +
1.134 +
1.135 +typedef gboolean (*DBusGValueMarshalFunc) (DBusMessageIter *iter,
1.136 + const GValue *value);
1.137 +typedef gboolean (*DBusGValueDemarshalFunc) (DBusGValueMarshalCtx *context,
1.138 + DBusMessageIter *iter,
1.139 + GValue *value,
1.140 + GError **error);
1.141 +
1.142 +typedef struct {
1.143 + DBusGValueMarshalFunc marshaller;
1.144 + DBusGValueDemarshalFunc demarshaller;
1.145 +} DBusGTypeMarshalVtable;
1.146 +
1.147 +typedef struct {
1.148 + const char *sig;
1.149 + const DBusGTypeMarshalVtable *vtable;
1.150 +} DBusGTypeMarshalData;
1.151 +
1.152 +
1.153 +#if EMULATOR
1.154 +GET_STATIC_VAR_FROM_TLS(quark,dbus_gvalue,GQuark )
1.155 +#define quark (*GET_DBUS_WSD_VAR_NAME(quark,dbus_gvalue,s)())
1.156 +#endif
1.157 +
1.158 +static GQuark
1.159 +dbus_g_type_metadata_data_quark ()
1.160 +{
1.161 +#ifndef EMULATOR
1.162 + static GQuark quark;
1.163 +#endif
1.164 + if (!quark)
1.165 + quark = g_quark_from_static_string ("DBusGTypeMetaData");
1.166 +
1.167 + return quark;
1.168 +}
1.169 +
1.170 +static void
1.171 +set_type_metadata (GType type, const DBusGTypeMarshalData *data)
1.172 +{
1.173 + g_type_set_qdata (type, dbus_g_type_metadata_data_quark (), (gpointer) data);
1.174 +}
1.175 +
1.176 +static void
1.177 +register_basic (int typecode, const DBusGTypeMarshalData *typedata)
1.178 +{
1.179 + set_type_metadata (_dbus_gtype_from_basic_typecode (typecode), typedata);
1.180 +}
1.181 +
1.182 +#if EMULATOR
1.183 +GET_STATIC_VAR_FROM_TLS(types_initialized,dbus_gvalue,gboolean )
1.184 +#define types_initialized (*GET_DBUS_WSD_VAR_NAME(types_initialized,dbus_gvalue,s)())
1.185 +
1.186 +#endif
1.187 +
1.188 +void
1.189 +_dbus_g_value_types_init (void)
1.190 +{
1.191 +
1.192 +#ifndef EMULATOR
1.193 + static gboolean types_initialized;
1.194 +#endif
1.195 +
1.196 + static const DBusGTypeMarshalVtable basic_vtable = {
1.197 + marshal_basic,
1.198 + demarshal_basic
1.199 + };
1.200 +
1.201 + if (types_initialized)
1.202 + return;
1.203 +
1.204 + dbus_g_type_specialized_init ();
1.205 + _dbus_g_type_specialized_builtins_init ();
1.206 +
1.207 + /* Register basic types */
1.208 + {
1.209 + static const DBusGTypeMarshalData typedata = {
1.210 + DBUS_TYPE_BOOLEAN_AS_STRING,
1.211 + &basic_vtable,
1.212 + };
1.213 + register_basic (DBUS_TYPE_BOOLEAN, &typedata);
1.214 + }
1.215 + {
1.216 + static const DBusGTypeMarshalData typedata = {
1.217 + DBUS_TYPE_BYTE_AS_STRING,
1.218 + &basic_vtable,
1.219 + };
1.220 + register_basic (DBUS_TYPE_BYTE, &typedata);
1.221 + }
1.222 + {
1.223 + static const DBusGTypeMarshalData typedata = {
1.224 + DBUS_TYPE_INT16_AS_STRING,
1.225 + &basic_vtable,
1.226 + };
1.227 + register_basic (DBUS_TYPE_INT16, &typedata);
1.228 + }
1.229 + {
1.230 + static const DBusGTypeMarshalData typedata = {
1.231 + DBUS_TYPE_UINT16_AS_STRING,
1.232 + &basic_vtable,
1.233 + };
1.234 + register_basic (DBUS_TYPE_UINT16, &typedata);
1.235 + }
1.236 + {
1.237 + static const DBusGTypeMarshalData typedata = {
1.238 + DBUS_TYPE_UINT32_AS_STRING,
1.239 + &basic_vtable,
1.240 + };
1.241 + register_basic (DBUS_TYPE_UINT32, &typedata);
1.242 + }
1.243 + {
1.244 + static const DBusGTypeMarshalData typedata = {
1.245 + DBUS_TYPE_INT32_AS_STRING,
1.246 + &basic_vtable,
1.247 + };
1.248 + register_basic (DBUS_TYPE_INT32, &typedata);
1.249 + }
1.250 + {
1.251 + static const DBusGTypeMarshalData typedata = {
1.252 + DBUS_TYPE_UINT64_AS_STRING,
1.253 + &basic_vtable,
1.254 + };
1.255 + register_basic (DBUS_TYPE_UINT64, &typedata);
1.256 + }
1.257 + {
1.258 + static const DBusGTypeMarshalData typedata = {
1.259 + DBUS_TYPE_INT64_AS_STRING,
1.260 + &basic_vtable,
1.261 + };
1.262 + register_basic (DBUS_TYPE_INT64, &typedata);
1.263 + }
1.264 + {
1.265 + static const DBusGTypeMarshalData typedata = {
1.266 + DBUS_TYPE_DOUBLE_AS_STRING,
1.267 + &basic_vtable,
1.268 + };
1.269 + register_basic (DBUS_TYPE_DOUBLE, &typedata);
1.270 + }
1.271 + {
1.272 + static const DBusGTypeMarshalData typedata = {
1.273 + DBUS_TYPE_STRING_AS_STRING,
1.274 + &basic_vtable,
1.275 + };
1.276 + register_basic (DBUS_TYPE_STRING, &typedata);
1.277 + }
1.278 + /* fundamental GTypes that don't map 1:1 with D-BUS types */
1.279 + {
1.280 + static const DBusGTypeMarshalData typedata = {
1.281 + DBUS_TYPE_BYTE_AS_STRING,
1.282 + &basic_vtable,
1.283 + };
1.284 + set_type_metadata (G_TYPE_CHAR, &typedata);
1.285 + }
1.286 + {
1.287 + static const DBusGTypeMarshalData typedata = {
1.288 + DBUS_TYPE_INT32_AS_STRING,
1.289 + &basic_vtable,
1.290 + };
1.291 + set_type_metadata (G_TYPE_LONG, &typedata);
1.292 + }
1.293 + {
1.294 + static const DBusGTypeMarshalData typedata = {
1.295 + DBUS_TYPE_UINT32_AS_STRING,
1.296 + &basic_vtable,
1.297 + };
1.298 + set_type_metadata (G_TYPE_ULONG, &typedata);
1.299 + }
1.300 + {
1.301 + static const DBusGTypeMarshalData typedata = {
1.302 + DBUS_TYPE_DOUBLE_AS_STRING,
1.303 + &basic_vtable,
1.304 + };
1.305 + set_type_metadata (G_TYPE_FLOAT, &typedata);
1.306 + }
1.307 +
1.308 + /* Register complex types with builtin GType mappings */
1.309 + {
1.310 + static const DBusGTypeMarshalVtable vtable = {
1.311 + marshal_variant,
1.312 + demarshal_variant
1.313 + };
1.314 + static const DBusGTypeMarshalData typedata = {
1.315 + DBUS_TYPE_VARIANT_AS_STRING,
1.316 + &vtable
1.317 + };
1.318 + set_type_metadata (G_TYPE_VALUE, &typedata);
1.319 + };
1.320 + {
1.321 + static const DBusGTypeMarshalVtable vtable = {
1.322 + marshal_strv,
1.323 + demarshal_strv
1.324 + };
1.325 + static const DBusGTypeMarshalData typedata = {
1.326 + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
1.327 + &vtable
1.328 + };
1.329 + set_type_metadata (G_TYPE_STRV, &typedata);
1.330 + };
1.331 +
1.332 +
1.333 + /* Register some types specific to the D-BUS GLib bindings */
1.334 + {
1.335 + static const DBusGTypeMarshalVtable vtable = {
1.336 + marshal_proxy,
1.337 + demarshal_proxy
1.338 + };
1.339 + static const DBusGTypeMarshalData typedata = {
1.340 + DBUS_TYPE_OBJECT_PATH_AS_STRING,
1.341 + &vtable
1.342 + };
1.343 + set_type_metadata (DBUS_TYPE_G_PROXY, &typedata);
1.344 + }
1.345 +
1.346 + {
1.347 + static const DBusGTypeMarshalVtable vtable = {
1.348 + marshal_object_path,
1.349 + demarshal_object_path
1.350 + };
1.351 + static const DBusGTypeMarshalData typedata = {
1.352 + DBUS_TYPE_OBJECT_PATH_AS_STRING,
1.353 + &vtable
1.354 + };
1.355 + set_type_metadata (DBUS_TYPE_G_OBJECT_PATH, &typedata);
1.356 + }
1.357 +
1.358 + {
1.359 + static const DBusGTypeMarshalVtable vtable = {
1.360 + marshal_object,
1.361 + demarshal_object
1.362 + };
1.363 + static const DBusGTypeMarshalData typedata = {
1.364 + DBUS_TYPE_OBJECT_PATH_AS_STRING,
1.365 + &vtable
1.366 + };
1.367 + set_type_metadata (G_TYPE_OBJECT, &typedata);
1.368 + }
1.369 +
1.370 + types_initialized = TRUE;
1.371 +}
1.372 +
1.373 +/**
1.374 + * Get the GLib type ID for a DBusGObjectPath boxed type.
1.375 + *
1.376 + * Returns: GLib type
1.377 + */
1.378 + #if EMULATOR
1.379 +GET_STATIC_VAR_FROM_TLS(type_id,dbus_gvalue,GType )
1.380 +#define type_id (*GET_DBUS_WSD_VAR_NAME(type_id,dbus_gvalue,s)())
1.381 +#endif
1.382 +
1.383 + #ifdef __SYMBIAN32__
1.384 + EXPORT_C
1.385 + #endif
1.386 +GType
1.387 +dbus_g_object_path_get_g_type (void)
1.388 +{
1.389 + #ifndef EMULATOR
1.390 + static GType type_id = 0;
1.391 +#endif
1.392 +
1.393 +
1.394 +
1.395 + if (!type_id)
1.396 + type_id = g_boxed_type_register_static ("DBusGObjectPath",
1.397 + (GBoxedCopyFunc) g_strdup,
1.398 + (GBoxedFreeFunc) g_free);
1.399 + return type_id;
1.400 +}
1.401 +
1.402 +
1.403 +char *
1.404 +_dbus_gtype_to_signature (GType gtype)
1.405 +{
1.406 + char *ret;
1.407 + DBusGTypeMarshalData *typedata;
1.408 +
1.409 + if (dbus_g_type_is_collection (gtype))
1.410 + {
1.411 + GType elt_gtype;
1.412 + char *subsig;
1.413 +
1.414 + elt_gtype = dbus_g_type_get_collection_specialization (gtype);
1.415 + subsig = _dbus_gtype_to_signature (elt_gtype);
1.416 + ret = g_strconcat (DBUS_TYPE_ARRAY_AS_STRING, subsig, NULL);
1.417 + g_free (subsig);
1.418 + }
1.419 + else if (dbus_g_type_is_map (gtype))
1.420 + {
1.421 + GType key_gtype;
1.422 + GType val_gtype;
1.423 + char *key_subsig;
1.424 + char *val_subsig;
1.425 +
1.426 + key_gtype = dbus_g_type_get_map_key_specialization (gtype);
1.427 + val_gtype = dbus_g_type_get_map_value_specialization (gtype);
1.428 + key_subsig = _dbus_gtype_to_signature (key_gtype);
1.429 + val_subsig = _dbus_gtype_to_signature (val_gtype);
1.430 + 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);
1.431 + g_free (key_subsig);
1.432 + g_free (val_subsig);
1.433 + }
1.434 + else if (dbus_g_type_is_struct (gtype))
1.435 + {
1.436 + guint i, size;
1.437 + GString *sig;
1.438 + size = dbus_g_type_get_struct_size (gtype);
1.439 + sig = g_string_sized_new (size+2); /*some sensible starting size*/
1.440 + g_string_assign (sig, DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
1.441 + for (i = 0; i < size; i++)
1.442 + {
1.443 + gchar *subsig;
1.444 + subsig = _dbus_gtype_to_signature (
1.445 + dbus_g_type_get_struct_member_type (gtype, i));
1.446 + g_string_append (sig, subsig);
1.447 + g_free (subsig);
1.448 + }
1.449 + g_string_append (sig, DBUS_STRUCT_END_CHAR_AS_STRING);
1.450 + ret = g_string_free (sig, FALSE);
1.451 + }
1.452 + else
1.453 + {
1.454 + typedata = g_type_get_qdata (gtype, dbus_g_type_metadata_data_quark ());
1.455 + if (typedata == NULL)
1.456 + return NULL;
1.457 + ret = g_strdup (typedata->sig);
1.458 + }
1.459 + return ret;
1.460 +}
1.461 +
1.462 +char *
1.463 +_dbus_gvalue_to_signature (const GValue *val)
1.464 +{
1.465 + GType gtype;
1.466 +
1.467 + gtype = G_VALUE_TYPE (val);
1.468 + if (g_type_is_a (gtype, G_TYPE_VALUE_ARRAY))
1.469 + {
1.470 + GString *str;
1.471 + guint i;
1.472 + GValueArray *array;
1.473 +
1.474 + array = g_value_get_boxed (val);
1.475 +
1.476 + str = g_string_new (DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
1.477 + for (i = 0; i < array->n_values; i++)
1.478 + {
1.479 + char *sig;
1.480 + sig = _dbus_gvalue_to_signature (g_value_array_get_nth (array, i));
1.481 + g_string_append (str, sig);
1.482 + g_free (sig);
1.483 + }
1.484 + g_string_append (str, DBUS_STRUCT_END_CHAR_AS_STRING);
1.485 +
1.486 + return g_string_free (str, FALSE);
1.487 + }
1.488 + else
1.489 + return _dbus_gtype_to_signature (gtype);
1.490 +}
1.491 +
1.492 +static gboolean
1.493 +demarshal_basic (DBusGValueMarshalCtx *context,
1.494 + DBusMessageIter *iter,
1.495 + GValue *value,
1.496 + GError **error)
1.497 +{
1.498 + int current_type;
1.499 +
1.500 + current_type = dbus_message_iter_get_arg_type (iter);
1.501 + g_assert (dbus_type_is_basic (current_type));
1.502 +
1.503 + switch (current_type)
1.504 + {
1.505 + case DBUS_TYPE_BOOLEAN:
1.506 + {
1.507 + dbus_bool_t bool;
1.508 + dbus_message_iter_get_basic (iter, &bool);
1.509 + g_value_set_boolean (value, bool);
1.510 + return TRUE;
1.511 + }
1.512 + case DBUS_TYPE_BYTE:
1.513 + {
1.514 + unsigned char byte;
1.515 + dbus_message_iter_get_basic (iter, &byte);
1.516 + g_value_set_uchar (value, byte);
1.517 + return TRUE;
1.518 + }
1.519 + case DBUS_TYPE_INT32:
1.520 + {
1.521 + dbus_int32_t intval;
1.522 + dbus_message_iter_get_basic (iter, &intval);
1.523 + g_value_set_int (value, intval);
1.524 + return TRUE;
1.525 + }
1.526 + case DBUS_TYPE_UINT32:
1.527 + {
1.528 + dbus_uint32_t intval;
1.529 + dbus_message_iter_get_basic (iter, &intval);
1.530 + g_value_set_uint (value, intval);
1.531 + return TRUE;
1.532 + }
1.533 + case DBUS_TYPE_INT64:
1.534 + {
1.535 + dbus_int64_t intval;
1.536 + dbus_message_iter_get_basic (iter, &intval);
1.537 + g_value_set_int64 (value, intval);
1.538 + return TRUE;
1.539 + }
1.540 + case DBUS_TYPE_UINT64:
1.541 + {
1.542 + dbus_uint64_t intval;
1.543 + dbus_message_iter_get_basic (iter, &intval);
1.544 + g_value_set_uint64 (value, intval);
1.545 + return TRUE;
1.546 + }
1.547 + case DBUS_TYPE_DOUBLE:
1.548 + {
1.549 + double dval;
1.550 + dbus_message_iter_get_basic (iter, &dval);
1.551 + g_value_set_double (value, dval);
1.552 + return TRUE;
1.553 + }
1.554 + case DBUS_TYPE_INT16:
1.555 + {
1.556 + dbus_int16_t v;
1.557 + dbus_message_iter_get_basic (iter, &v);
1.558 + g_value_set_int (value, v);
1.559 + return TRUE;
1.560 + }
1.561 + case DBUS_TYPE_UINT16:
1.562 + {
1.563 + dbus_uint16_t v;
1.564 + dbus_message_iter_get_basic (iter, &v);
1.565 + g_value_set_uint (value, v);
1.566 + return TRUE;
1.567 + }
1.568 + case DBUS_TYPE_STRING:
1.569 + {
1.570 + const char *s;
1.571 + dbus_message_iter_get_basic (iter, &s);
1.572 + g_value_set_string (value, s);
1.573 + return TRUE;
1.574 + }
1.575 + default:
1.576 + g_assert_not_reached ();
1.577 + return FALSE;
1.578 + }
1.579 +}
1.580 +
1.581 +static gboolean
1.582 +demarshal_static_variant (DBusGValueMarshalCtx *context,
1.583 + DBusMessageIter *iter,
1.584 + GValue *value,
1.585 + GError **error)
1.586 +{
1.587 + char *sig;
1.588 + int current_type;
1.589 + DBusMessageIter subiter;
1.590 + GType variant_type;
1.591 +
1.592 + current_type = dbus_message_iter_get_arg_type (iter);
1.593 + dbus_message_iter_recurse (iter, &subiter);
1.594 + sig = dbus_message_iter_get_signature (&subiter);
1.595 +
1.596 + variant_type = _dbus_gtype_from_signature (sig, context->proxy != NULL);
1.597 + if (variant_type != G_TYPE_INVALID)
1.598 + {
1.599 + g_value_init (value, variant_type);
1.600 +
1.601 + if (!_dbus_gvalue_demarshal (context, &subiter, value, error))
1.602 + {
1.603 + dbus_free (sig);
1.604 + return FALSE;
1.605 + }
1.606 + }
1.607 + dbus_free (sig);
1.608 + return TRUE;
1.609 +}
1.610 +
1.611 +static gboolean
1.612 +demarshal_variant (DBusGValueMarshalCtx *context,
1.613 + DBusMessageIter *iter,
1.614 + GValue *value,
1.615 + GError **error)
1.616 +
1.617 +{
1.618 + GValue *variant_val;
1.619 + variant_val = g_new0 (GValue, 1);
1.620 +
1.621 + if (!demarshal_static_variant (context, iter, variant_val, error))
1.622 + return FALSE;
1.623 +
1.624 + g_value_set_boxed_take_ownership (value, variant_val);
1.625 + return TRUE;
1.626 +}
1.627 +
1.628 +static gboolean
1.629 +demarshal_proxy (DBusGValueMarshalCtx *context,
1.630 + DBusMessageIter *iter,
1.631 + GValue *value,
1.632 + GError **error)
1.633 +{
1.634 + DBusGProxy *new_proxy;
1.635 + const char *objpath;
1.636 + int current_type;
1.637 +
1.638 + current_type = dbus_message_iter_get_arg_type (iter);
1.639 + if (current_type != DBUS_TYPE_OBJECT_PATH)
1.640 + {
1.641 + g_set_error (error,
1.642 + DBUS_GERROR,
1.643 + DBUS_GERROR_INVALID_ARGS,
1.644 + _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type);
1.645 + return FALSE;
1.646 + }
1.647 +
1.648 + g_assert (context->proxy != NULL);
1.649 +
1.650 + dbus_message_iter_get_basic (iter, &objpath);
1.651 +
1.652 + new_proxy = dbus_g_proxy_new_from_proxy (context->proxy, NULL, objpath);
1.653 + g_value_set_object_take_ownership (value, new_proxy);
1.654 +
1.655 + return TRUE;
1.656 +}
1.657 +
1.658 +static gboolean
1.659 +demarshal_object_path (DBusGValueMarshalCtx *context,
1.660 + DBusMessageIter *iter,
1.661 + GValue *value,
1.662 + GError **error)
1.663 +{
1.664 + const char *objpath;
1.665 + int current_type;
1.666 +
1.667 + current_type = dbus_message_iter_get_arg_type (iter);
1.668 + if (current_type != DBUS_TYPE_OBJECT_PATH)
1.669 + {
1.670 + g_set_error (error,
1.671 + DBUS_GERROR,
1.672 + DBUS_GERROR_INVALID_ARGS,
1.673 + _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type);
1.674 + return FALSE;
1.675 + }
1.676 +
1.677 + dbus_message_iter_get_basic (iter, &objpath);
1.678 +
1.679 + g_value_set_boxed_take_ownership (value, g_strdup (objpath));
1.680 +
1.681 + return TRUE;
1.682 +}
1.683 +
1.684 +static gboolean
1.685 +demarshal_object (DBusGValueMarshalCtx *context,
1.686 + DBusMessageIter *iter,
1.687 + GValue *value,
1.688 + GError **error)
1.689 +{
1.690 + const char *objpath;
1.691 + int current_type;
1.692 + GObject *obj;
1.693 +
1.694 + current_type = dbus_message_iter_get_arg_type (iter);
1.695 + if (current_type != DBUS_TYPE_OBJECT_PATH)
1.696 + {
1.697 + g_set_error (error,
1.698 + DBUS_GERROR,
1.699 + DBUS_GERROR_INVALID_ARGS,
1.700 + _("Expected D-BUS object path, got type code \'%c\'"), (guchar) current_type);
1.701 + return FALSE;
1.702 + }
1.703 + g_assert (context->proxy == NULL);
1.704 +
1.705 + dbus_message_iter_get_basic (iter, &objpath);
1.706 +
1.707 + obj = dbus_g_connection_lookup_g_object (context->gconnection, objpath);
1.708 + if (obj == NULL)
1.709 + {
1.710 + g_set_error (error,
1.711 + DBUS_GERROR,
1.712 + DBUS_GERROR_INVALID_ARGS,
1.713 + _("Unregistered object at path '%s'"),
1.714 + objpath);
1.715 + return FALSE;
1.716 + }
1.717 + g_value_set_object (value, obj);
1.718 +
1.719 + return TRUE;
1.720 +}
1.721 +
1.722 +static gboolean
1.723 +demarshal_strv (DBusGValueMarshalCtx *context,
1.724 + DBusMessageIter *iter,
1.725 + GValue *value,
1.726 + GError **error)
1.727 +{
1.728 + DBusMessageIter subiter;
1.729 + int current_type;
1.730 + char **ret;
1.731 + int len;
1.732 + int i;
1.733 +
1.734 + current_type = dbus_message_iter_get_arg_type (iter);
1.735 + if (current_type != DBUS_TYPE_ARRAY)
1.736 + {
1.737 + g_set_error (error,
1.738 + DBUS_GERROR,
1.739 + DBUS_GERROR_INVALID_ARGS,
1.740 + _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type);
1.741 + return FALSE;
1.742 + }
1.743 +
1.744 + dbus_message_iter_recurse (iter, &subiter);
1.745 +
1.746 + current_type = dbus_message_iter_get_arg_type (&subiter);
1.747 + if (current_type != DBUS_TYPE_INVALID
1.748 + && current_type != DBUS_TYPE_STRING)
1.749 + {
1.750 + g_set_error (error,
1.751 + DBUS_GERROR,
1.752 + DBUS_GERROR_INVALID_ARGS,
1.753 + _("Expected D-BUS string, got type code \'%c\'"), (guchar) current_type);
1.754 + return FALSE;
1.755 + }
1.756 +
1.757 + len = dbus_message_iter_get_array_len (&subiter);
1.758 + g_assert (len >= 0);
1.759 + ret = g_malloc (sizeof (char *) * (len + 1));
1.760 +
1.761 + i = 0;
1.762 + while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
1.763 + {
1.764 + g_assert (i < len);
1.765 + g_assert (current_type == DBUS_TYPE_STRING);
1.766 +
1.767 + dbus_message_iter_get_basic (&subiter, &(ret[i]));
1.768 + ret[i] = g_strdup (ret[i]);
1.769 +
1.770 + dbus_message_iter_next (&subiter);
1.771 + i++;
1.772 + }
1.773 + ret[i] = NULL;
1.774 + g_value_set_boxed_take_ownership (value, ret);
1.775 +
1.776 + return TRUE;
1.777 +}
1.778 +
1.779 +static gboolean
1.780 +demarshal_valuearray (DBusGValueMarshalCtx *context,
1.781 + DBusMessageIter *iter,
1.782 + GValue *value,
1.783 + GError **error)
1.784 +{
1.785 + int current_type;
1.786 + GValueArray *ret;
1.787 + DBusMessageIter subiter;
1.788 +
1.789 + current_type = dbus_message_iter_get_arg_type (iter);
1.790 + if (current_type != DBUS_TYPE_STRUCT)
1.791 + {
1.792 + g_set_error (error,
1.793 + DBUS_GERROR,
1.794 + DBUS_GERROR_INVALID_ARGS,
1.795 + _("Expected D-BUS struct, got type code \'%c\'"), (guchar) current_type);
1.796 + return FALSE;
1.797 + }
1.798 +
1.799 + dbus_message_iter_recurse (iter, &subiter);
1.800 +
1.801 + ret = g_value_array_new (12);
1.802 +
1.803 + while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
1.804 + {
1.805 + GValue *val;
1.806 + GType elt_type;
1.807 + char *current_sig;
1.808 +
1.809 + g_value_array_append (ret, NULL);
1.810 + val = g_value_array_get_nth (ret, ret->n_values - 1);
1.811 +
1.812 + current_sig = dbus_message_iter_get_signature (&subiter);
1.813 + elt_type = _dbus_gtype_from_signature (current_sig, TRUE);
1.814 +
1.815 + dbus_free (current_sig);
1.816 + if (elt_type == G_TYPE_INVALID)
1.817 + {
1.818 + g_value_array_free (ret);
1.819 + g_set_error (error,
1.820 + DBUS_GERROR,
1.821 + DBUS_GERROR_INVALID_ARGS,
1.822 + _("Couldn't demarshal argument with signature \"%s\""), current_sig);
1.823 + return FALSE;
1.824 + }
1.825 +
1.826 + g_value_init (val, elt_type);
1.827 +
1.828 + if (!_dbus_gvalue_demarshal (context, &subiter, val, error))
1.829 + {
1.830 + g_value_array_free (ret);
1.831 + return FALSE;
1.832 + }
1.833 +
1.834 + dbus_message_iter_next (&subiter);
1.835 + }
1.836 +
1.837 + g_value_set_boxed_take_ownership (value, ret);
1.838 +
1.839 + return TRUE;
1.840 +}
1.841 +
1.842 +static gboolean
1.843 +demarshal_map (DBusGValueMarshalCtx *context,
1.844 + DBusMessageIter *iter,
1.845 + GValue *value,
1.846 + GError **error)
1.847 +{
1.848 + GType gtype;
1.849 + DBusMessageIter subiter;
1.850 + int current_type;
1.851 + gpointer ret;
1.852 + GType key_gtype;
1.853 + GType value_gtype;
1.854 + DBusGTypeSpecializedAppendContext appendctx;
1.855 +
1.856 + current_type = dbus_message_iter_get_arg_type (iter);
1.857 + if (current_type != DBUS_TYPE_ARRAY)
1.858 + {
1.859 + g_set_error (error,
1.860 + DBUS_GERROR,
1.861 + DBUS_GERROR_INVALID_ARGS,
1.862 + _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type);
1.863 + return FALSE;
1.864 + }
1.865 +
1.866 + gtype = G_VALUE_TYPE (value);
1.867 +
1.868 + dbus_message_iter_recurse (iter, &subiter);
1.869 +
1.870 + current_type = dbus_message_iter_get_arg_type (&subiter);
1.871 + if (current_type != DBUS_TYPE_INVALID
1.872 + && current_type != DBUS_TYPE_DICT_ENTRY)
1.873 + {
1.874 + g_set_error (error,
1.875 + DBUS_GERROR,
1.876 + DBUS_GERROR_INVALID_ARGS,
1.877 + _("Expected D-BUS dict entry, got type code \'%c\'"), (guchar) current_type);
1.878 + return FALSE;
1.879 + }
1.880 +
1.881 + key_gtype = dbus_g_type_get_map_key_specialization (gtype);
1.882 + value_gtype = dbus_g_type_get_map_value_specialization (gtype);
1.883 +
1.884 + ret = dbus_g_type_specialized_construct (gtype);
1.885 + g_value_set_boxed_take_ownership (value, ret);
1.886 +
1.887 + dbus_g_type_specialized_init_append (value, &appendctx);
1.888 +
1.889 + while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
1.890 + {
1.891 + DBusMessageIter entry_iter;
1.892 + GValue key_value = {0,};
1.893 + GValue value_value = {0,};
1.894 +
1.895 + current_type = dbus_message_iter_get_arg_type (&subiter);
1.896 + g_assert (current_type == DBUS_TYPE_DICT_ENTRY);
1.897 +
1.898 + dbus_message_iter_recurse (&subiter, &entry_iter);
1.899 +
1.900 + g_value_init (&key_value, key_gtype);
1.901 + if (!_dbus_gvalue_demarshal (context,
1.902 + &entry_iter,
1.903 + &key_value,
1.904 + error))
1.905 + return FALSE;
1.906 +
1.907 + dbus_message_iter_next (&entry_iter);
1.908 +
1.909 + g_value_init (&value_value, value_gtype);
1.910 + if (!_dbus_gvalue_demarshal (context,
1.911 + &entry_iter,
1.912 + &value_value,
1.913 + error))
1.914 + return FALSE;
1.915 +
1.916 + dbus_g_type_specialized_map_append (&appendctx, &key_value, &value_value);
1.917 + /* Ownership of values passes to map, don't unset */
1.918 +
1.919 + dbus_message_iter_next (&subiter);
1.920 + }
1.921 +
1.922 + return TRUE;
1.923 +}
1.924 +
1.925 +static gboolean
1.926 +demarshal_struct (DBusGValueMarshalCtx *context,
1.927 + DBusMessageIter *iter,
1.928 + GValue *value,
1.929 + GError **error)
1.930 +{
1.931 + int current_type;
1.932 + DBusMessageIter subiter;
1.933 + guint i, size;
1.934 + GValue val = {0,};
1.935 + GType elt_type;
1.936 +
1.937 + current_type = dbus_message_iter_get_arg_type (iter);
1.938 + if (current_type != DBUS_TYPE_STRUCT)
1.939 + {
1.940 + g_set_error (error,
1.941 + DBUS_GERROR,
1.942 + DBUS_GERROR_INVALID_ARGS,
1.943 + _("Expected D-BUS struct, got type code \'%c\'"), (guchar) current_type);
1.944 + return FALSE;
1.945 + }
1.946 +
1.947 + dbus_message_iter_recurse (iter, &subiter);
1.948 +
1.949 + g_value_set_boxed_take_ownership (value,
1.950 + dbus_g_type_specialized_construct (G_VALUE_TYPE (value)));
1.951 +
1.952 + size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
1.953 +
1.954 + for (i=0; i < size; i++)
1.955 + {
1.956 +
1.957 + elt_type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE(value), i);
1.958 + if (elt_type == G_TYPE_INVALID)
1.959 + {
1.960 + g_value_unset (value);
1.961 + g_set_error (error,
1.962 + DBUS_GERROR,
1.963 + DBUS_GERROR_INVALID_ARGS,
1.964 + _("Couldn't demarshal argument, "
1.965 + "struct type %s has no member %d"),
1.966 + g_type_name (G_VALUE_TYPE(value)), i);
1.967 + return FALSE;
1.968 + }
1.969 +
1.970 + g_value_init (&val, elt_type);
1.971 +
1.972 + if (!_dbus_gvalue_demarshal (context, &subiter, &val, error))
1.973 + {
1.974 + g_value_unset (&val);
1.975 + g_value_unset (value);
1.976 + return FALSE;
1.977 + }
1.978 + if (!dbus_g_type_struct_set_member (value, i, &val))
1.979 + {
1.980 + g_value_unset (&val);
1.981 + g_value_unset (value);
1.982 + return FALSE;
1.983 + }
1.984 +
1.985 + dbus_message_iter_next (&subiter);
1.986 + g_value_unset (&val);
1.987 + }
1.988 +
1.989 + g_assert (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_INVALID);
1.990 +
1.991 + return TRUE;
1.992 +}
1.993 +
1.994 +
1.995 +static DBusGValueDemarshalFunc
1.996 +get_type_demarshaller (GType type)
1.997 +{
1.998 + DBusGTypeMarshalData *typedata;
1.999 +
1.1000 + typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ());
1.1001 + if (typedata == NULL)
1.1002 + {
1.1003 + if (g_type_is_a (type, G_TYPE_VALUE_ARRAY))
1.1004 + return demarshal_valuearray;
1.1005 + if (dbus_g_type_is_collection (type))
1.1006 + return demarshal_collection;
1.1007 + if (dbus_g_type_is_map (type))
1.1008 + return demarshal_map;
1.1009 + if (dbus_g_type_is_struct (type))
1.1010 + return demarshal_struct;
1.1011 +
1.1012 + g_warning ("No demarshaller registered for type \"%s\"", g_type_name (type));
1.1013 + return NULL;
1.1014 + }
1.1015 + g_assert (typedata->vtable);
1.1016 + return typedata->vtable->demarshaller;
1.1017 +}
1.1018 +
1.1019 +static gboolean
1.1020 +demarshal_collection (DBusGValueMarshalCtx *context,
1.1021 + DBusMessageIter *iter,
1.1022 + GValue *value,
1.1023 + GError **error)
1.1024 +{
1.1025 + GType coltype;
1.1026 + GType subtype;
1.1027 +
1.1028 + coltype = G_VALUE_TYPE (value);
1.1029 + subtype = dbus_g_type_get_collection_specialization (coltype);
1.1030 +
1.1031 + if (_dbus_g_type_is_fixed (subtype))
1.1032 + return demarshal_collection_array (context, iter, value, error);
1.1033 + else
1.1034 + return demarshal_collection_ptrarray (context, iter, value, error);
1.1035 +}
1.1036 +
1.1037 +static gboolean
1.1038 +demarshal_collection_ptrarray (DBusGValueMarshalCtx *context,
1.1039 + DBusMessageIter *iter,
1.1040 + GValue *value,
1.1041 + GError **error)
1.1042 +{
1.1043 + GType coltype;
1.1044 + GType subtype;
1.1045 + gpointer instance;
1.1046 + DBusGTypeSpecializedAppendContext ctx;
1.1047 + DBusGValueDemarshalFunc demarshaller;
1.1048 + DBusMessageIter subiter;
1.1049 + int current_type;
1.1050 +
1.1051 + current_type = dbus_message_iter_get_arg_type (iter);
1.1052 +
1.1053 + if (current_type != DBUS_TYPE_ARRAY)
1.1054 + {
1.1055 + g_set_error (error,
1.1056 + DBUS_GERROR,
1.1057 + DBUS_GERROR_INVALID_ARGS,
1.1058 + _("Expected D-BUS array, got type code \'%c\'"), (guchar) current_type);
1.1059 + return FALSE;
1.1060 + }
1.1061 +
1.1062 + dbus_message_iter_recurse (iter, &subiter);
1.1063 +
1.1064 + coltype = G_VALUE_TYPE (value);
1.1065 + subtype = dbus_g_type_get_collection_specialization (coltype);
1.1066 +
1.1067 + demarshaller = get_type_demarshaller (subtype);
1.1068 +
1.1069 + if (!demarshaller)
1.1070 + {
1.1071 + g_set_error (error,
1.1072 + DBUS_GERROR,
1.1073 + DBUS_GERROR_INVALID_ARGS,
1.1074 + _("No demarshaller registered for type \"%s\" of collection \"%s\""),
1.1075 + g_type_name (coltype),
1.1076 + g_type_name (subtype));
1.1077 + return FALSE;
1.1078 + }
1.1079 +
1.1080 + instance = dbus_g_type_specialized_construct (coltype);
1.1081 + g_value_set_boxed_take_ownership (value, instance);
1.1082 +
1.1083 + dbus_g_type_specialized_init_append (value, &ctx);
1.1084 +
1.1085 + while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID)
1.1086 + {
1.1087 + GValue eltval = {0, };
1.1088 +
1.1089 + g_value_init (&eltval, subtype);
1.1090 +
1.1091 + if (!demarshaller (context, &subiter, &eltval, error))
1.1092 + {
1.1093 + dbus_g_type_specialized_collection_end_append (&ctx);
1.1094 + g_value_unset (value);
1.1095 + return FALSE;
1.1096 + }
1.1097 + dbus_g_type_specialized_collection_append (&ctx, &eltval);
1.1098 +
1.1099 + dbus_message_iter_next (&subiter);
1.1100 + }
1.1101 + dbus_g_type_specialized_collection_end_append (&ctx);
1.1102 +
1.1103 + return TRUE;
1.1104 +}
1.1105 +
1.1106 +static gboolean
1.1107 +demarshal_collection_array (DBusGValueMarshalCtx *context,
1.1108 + DBusMessageIter *iter,
1.1109 + GValue *value,
1.1110 + GError **error)
1.1111 +{
1.1112 + DBusMessageIter subiter;
1.1113 + GArray *ret;
1.1114 + GType elt_gtype;
1.1115 + int elt_size;
1.1116 + void *msgarray;
1.1117 + int msgarray_len;
1.1118 +
1.1119 + dbus_message_iter_recurse (iter, &subiter);
1.1120 +
1.1121 + elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
1.1122 + g_assert (elt_gtype != G_TYPE_INVALID);
1.1123 + g_assert (_dbus_g_type_is_fixed (elt_gtype));
1.1124 +
1.1125 + elt_size = _dbus_g_type_fixed_get_size (elt_gtype);
1.1126 +
1.1127 + ret = g_array_new (FALSE, TRUE, elt_size);
1.1128 +
1.1129 + msgarray = NULL;
1.1130 + dbus_message_iter_get_fixed_array (&subiter,
1.1131 + &msgarray,
1.1132 + &msgarray_len);
1.1133 + g_assert (msgarray != NULL || msgarray_len == 0);
1.1134 +
1.1135 + if (msgarray_len)
1.1136 + g_array_append_vals (ret, msgarray, (guint) msgarray_len);
1.1137 +
1.1138 + g_value_set_boxed_take_ownership (value, ret);
1.1139 +
1.1140 + return TRUE;
1.1141 +}
1.1142 +
1.1143 +gboolean
1.1144 +_dbus_gvalue_demarshal (DBusGValueMarshalCtx *context,
1.1145 + DBusMessageIter *iter,
1.1146 + GValue *value,
1.1147 + GError **error)
1.1148 +{
1.1149 + GType gtype;
1.1150 + DBusGValueDemarshalFunc demarshaller;
1.1151 +
1.1152 + gtype = G_VALUE_TYPE (value);
1.1153 +
1.1154 + demarshaller = get_type_demarshaller (gtype);
1.1155 +
1.1156 + if (demarshaller == NULL)
1.1157 + {
1.1158 + g_set_error (error,
1.1159 + DBUS_GERROR,
1.1160 + DBUS_GERROR_INVALID_ARGS,
1.1161 + _("No demarshaller registered for type \"%s\""),
1.1162 + g_type_name (gtype));
1.1163 + return FALSE;
1.1164 + }
1.1165 +
1.1166 + return demarshaller (context, iter, value, error);
1.1167 +}
1.1168 +
1.1169 +gboolean
1.1170 +_dbus_gvalue_demarshal_variant (DBusGValueMarshalCtx *context,
1.1171 + DBusMessageIter *iter,
1.1172 + GValue *value,
1.1173 + GError **error)
1.1174 +{
1.1175 + return demarshal_static_variant (context, iter, value, error);
1.1176 +}
1.1177 +
1.1178 +GValueArray *
1.1179 +_dbus_gvalue_demarshal_message (DBusGValueMarshalCtx *context,
1.1180 + DBusMessage *message,
1.1181 + guint n_types,
1.1182 + const GType *types,
1.1183 + GError **error)
1.1184 +{
1.1185 + GValueArray *ret;
1.1186 + DBusMessageIter iter;
1.1187 + int current_type;
1.1188 + guint index_;
1.1189 +
1.1190 + ret = g_value_array_new (6); /* 6 is a typical maximum for arguments */
1.1191 +
1.1192 + dbus_message_iter_init (message, &iter);
1.1193 + index_ = 0;
1.1194 + while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID)
1.1195 + {
1.1196 + GValue *value;
1.1197 + GType gtype;
1.1198 +
1.1199 + if (index_ >= n_types)
1.1200 + {
1.1201 + g_set_error (error, DBUS_GERROR,
1.1202 + DBUS_GERROR_INVALID_ARGS,
1.1203 + _("Too many arguments in message"));
1.1204 + goto lose;
1.1205 + }
1.1206 +
1.1207 + g_value_array_append (ret, NULL);
1.1208 + value = g_value_array_get_nth (ret, index_);
1.1209 +
1.1210 + gtype = types[index_];
1.1211 + g_value_init (value, gtype);
1.1212 +
1.1213 + if (!_dbus_gvalue_demarshal (context, &iter, value, error))
1.1214 + goto lose;
1.1215 + dbus_message_iter_next (&iter);
1.1216 + index_++;
1.1217 + }
1.1218 + if (index_ < n_types)
1.1219 + {
1.1220 + g_set_error (error, DBUS_GERROR,
1.1221 + DBUS_GERROR_INVALID_ARGS,
1.1222 + _("Too few arguments in message"));
1.1223 + goto lose;
1.1224 + }
1.1225 +
1.1226 + return ret;
1.1227 + lose:
1.1228 + g_value_array_free (ret);
1.1229 + return NULL;
1.1230 +}
1.1231 +
1.1232 +static gboolean
1.1233 +marshal_basic (DBusMessageIter *iter, const GValue *value)
1.1234 +{
1.1235 + GType value_type;
1.1236 +
1.1237 + value_type = G_VALUE_TYPE (value);
1.1238 +
1.1239 + switch (value_type)
1.1240 + {
1.1241 + case G_TYPE_CHAR:
1.1242 + {
1.1243 + char b = g_value_get_char (value);
1.1244 + if (!dbus_message_iter_append_basic (iter,
1.1245 + DBUS_TYPE_BYTE,
1.1246 + &b))
1.1247 + goto nomem;
1.1248 + }
1.1249 + return TRUE;
1.1250 + case G_TYPE_UCHAR:
1.1251 + {
1.1252 + unsigned char b = g_value_get_uchar (value);
1.1253 + if (!dbus_message_iter_append_basic (iter,
1.1254 + DBUS_TYPE_BYTE,
1.1255 + &b))
1.1256 + goto nomem;
1.1257 + }
1.1258 + return TRUE;
1.1259 + case G_TYPE_BOOLEAN:
1.1260 + {
1.1261 + dbus_bool_t b = g_value_get_boolean (value);
1.1262 + if (!dbus_message_iter_append_basic (iter,
1.1263 + DBUS_TYPE_BOOLEAN,
1.1264 + &b))
1.1265 + goto nomem;
1.1266 + }
1.1267 + return TRUE;
1.1268 + case G_TYPE_INT:
1.1269 + {
1.1270 + dbus_int32_t v = g_value_get_int (value);
1.1271 + if (!dbus_message_iter_append_basic (iter,
1.1272 + DBUS_TYPE_INT32,
1.1273 + &v))
1.1274 + goto nomem;
1.1275 + }
1.1276 + return TRUE;
1.1277 + case G_TYPE_UINT:
1.1278 + {
1.1279 + dbus_uint32_t v = g_value_get_uint (value);
1.1280 + if (!dbus_message_iter_append_basic (iter,
1.1281 + DBUS_TYPE_UINT32,
1.1282 + &v))
1.1283 + goto nomem;
1.1284 + }
1.1285 + return TRUE;
1.1286 + case G_TYPE_LONG:
1.1287 + {
1.1288 + dbus_int32_t v = g_value_get_long (value);
1.1289 + if (!dbus_message_iter_append_basic (iter,
1.1290 + DBUS_TYPE_INT32,
1.1291 + &v))
1.1292 + goto nomem;
1.1293 + }
1.1294 + return TRUE;
1.1295 + case G_TYPE_ULONG:
1.1296 + {
1.1297 + dbus_uint32_t v = g_value_get_ulong (value);
1.1298 + if (!dbus_message_iter_append_basic (iter,
1.1299 + DBUS_TYPE_UINT32,
1.1300 + &v))
1.1301 + goto nomem;
1.1302 + }
1.1303 + return TRUE;
1.1304 + case G_TYPE_INT64:
1.1305 + {
1.1306 + gint64 v = g_value_get_int64 (value);
1.1307 + if (!dbus_message_iter_append_basic (iter,
1.1308 + DBUS_TYPE_INT64,
1.1309 + &v))
1.1310 + goto nomem;
1.1311 + }
1.1312 + return TRUE;
1.1313 + case G_TYPE_UINT64:
1.1314 + {
1.1315 + guint64 v = g_value_get_uint64 (value);
1.1316 + if (!dbus_message_iter_append_basic (iter,
1.1317 + DBUS_TYPE_UINT64,
1.1318 + &v))
1.1319 + goto nomem;
1.1320 + }
1.1321 + return TRUE;
1.1322 + case G_TYPE_FLOAT:
1.1323 + {
1.1324 + double v = g_value_get_float (value);
1.1325 +
1.1326 + if (!dbus_message_iter_append_basic (iter,
1.1327 + DBUS_TYPE_DOUBLE,
1.1328 + &v))
1.1329 + goto nomem;
1.1330 + }
1.1331 + return TRUE;
1.1332 + case G_TYPE_DOUBLE:
1.1333 + {
1.1334 + double v = g_value_get_double (value);
1.1335 +
1.1336 + if (!dbus_message_iter_append_basic (iter,
1.1337 + DBUS_TYPE_DOUBLE,
1.1338 + &v))
1.1339 + goto nomem;
1.1340 + }
1.1341 + return TRUE;
1.1342 + case G_TYPE_STRING:
1.1343 + /* FIXME, the GValue string may not be valid UTF-8 */
1.1344 + {
1.1345 + const char *v = g_value_get_string (value);
1.1346 + if (!v)
1.1347 + v = "";
1.1348 + if (!dbus_message_iter_append_basic (iter,
1.1349 + DBUS_TYPE_STRING,
1.1350 + &v))
1.1351 + goto nomem;
1.1352 + }
1.1353 + return TRUE;
1.1354 +
1.1355 + default:
1.1356 + {
1.1357 + g_assert_not_reached ();
1.1358 + return FALSE;
1.1359 + }
1.1360 + }
1.1361 +
1.1362 + nomem:
1.1363 + g_error ("no memory");
1.1364 + return FALSE;
1.1365 +}
1.1366 +
1.1367 +static gboolean
1.1368 +marshal_strv (DBusMessageIter *iter,
1.1369 + const GValue *value)
1.1370 +{
1.1371 + DBusMessageIter subiter;
1.1372 + char **array;
1.1373 + char **elt;
1.1374 + gboolean ret = FALSE;
1.1375 +
1.1376 + g_assert (G_VALUE_TYPE (value) == g_strv_get_type ());
1.1377 +
1.1378 + array = g_value_get_boxed (value);
1.1379 +
1.1380 + if (!dbus_message_iter_open_container (iter,
1.1381 + DBUS_TYPE_ARRAY,
1.1382 + "s",
1.1383 + &subiter))
1.1384 + goto out;
1.1385 +
1.1386 + if (array)
1.1387 + {
1.1388 + for (elt = array; *elt; elt++)
1.1389 + {
1.1390 + if (!dbus_message_iter_append_basic (&subiter,
1.1391 + DBUS_TYPE_STRING,
1.1392 + elt))
1.1393 + goto out;
1.1394 + }
1.1395 + }
1.1396 +
1.1397 + if (!dbus_message_iter_close_container (iter, &subiter))
1.1398 + goto out;
1.1399 + ret = TRUE;
1.1400 + out:
1.1401 + return ret;
1.1402 +}
1.1403 +
1.1404 +static gboolean
1.1405 +marshal_valuearray (DBusMessageIter *iter,
1.1406 + const GValue *value)
1.1407 +{
1.1408 + GValueArray *array;
1.1409 + guint i;
1.1410 + DBusMessageIter subiter;
1.1411 +
1.1412 + g_assert (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY);
1.1413 +
1.1414 + array = g_value_get_boxed (value);
1.1415 +
1.1416 + if (!dbus_message_iter_open_container (iter,
1.1417 + DBUS_TYPE_STRUCT,
1.1418 + NULL,
1.1419 + &subiter))
1.1420 + goto oom;
1.1421 +
1.1422 + if (array)
1.1423 + {
1.1424 + for (i = 0; i < array->n_values; i++)
1.1425 + {
1.1426 + if (!_dbus_gvalue_marshal (&subiter, g_value_array_get_nth (array, i)))
1.1427 + return FALSE;
1.1428 + }
1.1429 + }
1.1430 +
1.1431 + if (!dbus_message_iter_close_container (iter, &subiter))
1.1432 + goto oom;
1.1433 +
1.1434 + return TRUE;
1.1435 + oom:
1.1436 + g_error ("out of memory");
1.1437 + return FALSE;
1.1438 +}
1.1439 +
1.1440 +static gboolean
1.1441 +marshal_proxy (DBusMessageIter *iter,
1.1442 + const GValue *value)
1.1443 +{
1.1444 + const char *path;
1.1445 + DBusGProxy *proxy;
1.1446 +
1.1447 + g_assert (G_VALUE_TYPE (value) == dbus_g_proxy_get_type ());
1.1448 +
1.1449 + proxy = g_value_get_object (value);
1.1450 + path = dbus_g_proxy_get_path (proxy);
1.1451 +
1.1452 + if (!dbus_message_iter_append_basic (iter,
1.1453 + DBUS_TYPE_OBJECT_PATH,
1.1454 + &path))
1.1455 + return FALSE;
1.1456 + return TRUE;
1.1457 +}
1.1458 +
1.1459 +static gboolean
1.1460 +marshal_object_path (DBusMessageIter *iter,
1.1461 + const GValue *value)
1.1462 +{
1.1463 + const char *path;
1.1464 +
1.1465 + g_assert (G_VALUE_TYPE (value) == DBUS_TYPE_G_OBJECT_PATH);
1.1466 +
1.1467 + path = (const char*) g_value_get_boxed (value);
1.1468 +
1.1469 + if (!dbus_message_iter_append_basic (iter,
1.1470 + DBUS_TYPE_OBJECT_PATH,
1.1471 + &path))
1.1472 + return FALSE;
1.1473 + return TRUE;
1.1474 +}
1.1475 +
1.1476 +static gboolean
1.1477 +marshal_object (DBusMessageIter *iter,
1.1478 + const GValue *value)
1.1479 +{
1.1480 + const char *path;
1.1481 + GObject *obj;
1.1482 +
1.1483 + obj = g_value_get_object (value);
1.1484 + path = _dbus_gobject_get_path (obj);
1.1485 +
1.1486 + if (path == NULL)
1.1487 + /* FIXME should throw error */
1.1488 + return FALSE;
1.1489 +
1.1490 + if (!dbus_message_iter_append_basic (iter,
1.1491 + DBUS_TYPE_OBJECT_PATH,
1.1492 + &path))
1.1493 + return FALSE;
1.1494 + return TRUE;
1.1495 +}
1.1496 +
1.1497 +struct DBusGLibHashMarshalData
1.1498 +{
1.1499 + const char *entry_sig;
1.1500 + DBusMessageIter *iter;
1.1501 + gboolean err;
1.1502 +};
1.1503 +
1.1504 +static void
1.1505 +marshal_map_entry (const GValue *key,
1.1506 + const GValue *value,
1.1507 + gpointer data)
1.1508 +{
1.1509 + struct DBusGLibHashMarshalData *hashdata = data;
1.1510 + DBusMessageIter subiter;
1.1511 +
1.1512 + if (hashdata->err)
1.1513 + return;
1.1514 +
1.1515 + if (!dbus_message_iter_open_container (hashdata->iter,
1.1516 + DBUS_TYPE_DICT_ENTRY,
1.1517 + NULL,
1.1518 + &subiter))
1.1519 + goto lose;
1.1520 +
1.1521 + if (!_dbus_gvalue_marshal (&subiter, key))
1.1522 + goto lose;
1.1523 +
1.1524 + if (!_dbus_gvalue_marshal (&subiter, value))
1.1525 + goto lose;
1.1526 +
1.1527 + if (!dbus_message_iter_close_container (hashdata->iter, &subiter))
1.1528 + goto lose;
1.1529 +
1.1530 + return;
1.1531 + lose:
1.1532 + hashdata->err = TRUE;
1.1533 +}
1.1534 +
1.1535 +static gboolean
1.1536 +marshal_map (DBusMessageIter *iter,
1.1537 + const GValue *value)
1.1538 +{
1.1539 + GType gtype;
1.1540 + DBusMessageIter arr_iter;
1.1541 + gboolean ret;
1.1542 + struct DBusGLibHashMarshalData hashdata;
1.1543 + char *key_sig;
1.1544 + char *value_sig;
1.1545 + GType key_type;
1.1546 + GType value_type;
1.1547 + char *entry_sig;
1.1548 + char *array_sig;
1.1549 +
1.1550 + gtype = G_VALUE_TYPE (value);
1.1551 +
1.1552 + ret = FALSE;
1.1553 +
1.1554 + key_type = dbus_g_type_get_map_key_specialization (gtype);
1.1555 + g_assert (_dbus_gtype_is_valid_hash_key (key_type));
1.1556 + value_type = dbus_g_type_get_map_value_specialization (gtype);
1.1557 + g_assert (_dbus_gtype_is_valid_hash_value (value_type));
1.1558 +
1.1559 + key_sig = _dbus_gtype_to_signature (key_type);
1.1560 + if (!key_sig)
1.1561 + {
1.1562 + g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (key_type));
1.1563 + return FALSE;
1.1564 + }
1.1565 + value_sig = _dbus_gtype_to_signature (value_type);
1.1566 + if (!value_sig)
1.1567 + {
1.1568 + g_free (key_sig);
1.1569 + g_warning ("Cannot marshal type \"%s\" in map\n", g_type_name (value_type));
1.1570 + return FALSE;
1.1571 + }
1.1572 + entry_sig = g_strdup_printf ("%s%s", key_sig, value_sig);
1.1573 + g_free (key_sig);
1.1574 + g_free (value_sig);
1.1575 + array_sig = g_strdup_printf ("%c%s%c",
1.1576 + DBUS_DICT_ENTRY_BEGIN_CHAR,
1.1577 + entry_sig,
1.1578 + DBUS_DICT_ENTRY_END_CHAR);
1.1579 + if (!dbus_message_iter_open_container (iter,
1.1580 + DBUS_TYPE_ARRAY,
1.1581 + array_sig,
1.1582 + &arr_iter))
1.1583 + goto lose;
1.1584 +
1.1585 + hashdata.iter = &arr_iter;
1.1586 + hashdata.err = FALSE;
1.1587 + hashdata.entry_sig = entry_sig;
1.1588 +
1.1589 + dbus_g_type_map_value_iterate (value,
1.1590 + marshal_map_entry,
1.1591 + &hashdata);
1.1592 +
1.1593 + if (!dbus_message_iter_close_container (iter, &arr_iter))
1.1594 + goto lose;
1.1595 +
1.1596 + out:
1.1597 + g_free (entry_sig);
1.1598 + g_free (array_sig);
1.1599 + return !hashdata.err;
1.1600 + lose:
1.1601 + hashdata.err = TRUE;
1.1602 + goto out;
1.1603 +}
1.1604 +
1.1605 +static gboolean
1.1606 +marshal_struct (DBusMessageIter *iter,
1.1607 + const GValue *value)
1.1608 +{
1.1609 + GType gtype;
1.1610 + DBusMessageIter subiter;
1.1611 + gboolean ret;
1.1612 + guint size, i;
1.1613 + GValue val = {0,};
1.1614 +
1.1615 + gtype = G_VALUE_TYPE (value);
1.1616 +
1.1617 + ret = FALSE;
1.1618 +
1.1619 + size = dbus_g_type_get_struct_size (gtype);
1.1620 +
1.1621 + if (!dbus_message_iter_open_container (iter,
1.1622 + DBUS_TYPE_STRUCT,
1.1623 + NULL,
1.1624 + &subiter))
1.1625 + goto oom;
1.1626 +
1.1627 + for (i = 0; i < size; i++)
1.1628 + {
1.1629 + g_value_init (&val, dbus_g_type_get_struct_member_type
1.1630 + (G_VALUE_TYPE(value), i));
1.1631 + if (!dbus_g_type_struct_get_member (value, i, &val))
1.1632 + return FALSE;
1.1633 + if (!_dbus_gvalue_marshal (&subiter, &val))
1.1634 + return FALSE;
1.1635 + g_value_unset(&val);
1.1636 + }
1.1637 +
1.1638 + if (!dbus_message_iter_close_container (iter, &subiter))
1.1639 + goto oom;
1.1640 +
1.1641 + return TRUE;
1.1642 + oom:
1.1643 + g_error ("out of memory");
1.1644 + return FALSE;
1.1645 +}
1.1646 +
1.1647 +static gboolean
1.1648 +marshal_variant (DBusMessageIter *iter,
1.1649 + const GValue *value)
1.1650 +{
1.1651 + GType value_gtype;
1.1652 + DBusMessageIter subiter;
1.1653 + char *variant_sig;
1.1654 + GValue *real_value;
1.1655 + gboolean ret = FALSE;
1.1656 +
1.1657 + real_value = g_value_get_boxed (value);
1.1658 + value_gtype = G_VALUE_TYPE (real_value);
1.1659 +
1.1660 + variant_sig = _dbus_gvalue_to_signature (real_value);
1.1661 + if (variant_sig == NULL)
1.1662 + {
1.1663 + g_warning ("Cannot marshal type \"%s\" in variant", g_type_name (value_gtype));
1.1664 + return FALSE;
1.1665 + }
1.1666 +
1.1667 + if (!dbus_message_iter_open_container (iter,
1.1668 + DBUS_TYPE_VARIANT,
1.1669 + variant_sig,
1.1670 + &subiter))
1.1671 + goto out;
1.1672 +
1.1673 + if (!_dbus_gvalue_marshal (&subiter, real_value))
1.1674 + goto out;
1.1675 +
1.1676 + if (!dbus_message_iter_close_container (iter, &subiter))
1.1677 + goto out;
1.1678 +
1.1679 + ret = TRUE;
1.1680 + out:
1.1681 + g_free (variant_sig);
1.1682 + return ret;
1.1683 +}
1.1684 +
1.1685 +static DBusGValueMarshalFunc
1.1686 +get_type_marshaller (GType type)
1.1687 +{
1.1688 + DBusGTypeMarshalData *typedata;
1.1689 +
1.1690 + typedata = g_type_get_qdata (type, dbus_g_type_metadata_data_quark ());
1.1691 + if (typedata == NULL)
1.1692 + {
1.1693 + if (g_type_is_a (type, G_TYPE_VALUE_ARRAY))
1.1694 + return marshal_valuearray;
1.1695 + if (dbus_g_type_is_collection (type))
1.1696 + return marshal_collection;
1.1697 + if (dbus_g_type_is_map (type))
1.1698 + return marshal_map;
1.1699 + if (dbus_g_type_is_struct (type))
1.1700 + return marshal_struct;
1.1701 +
1.1702 + g_warning ("No marshaller registered for type \"%s\"", g_type_name (type));
1.1703 + return NULL;
1.1704 + }
1.1705 + g_assert (typedata->vtable);
1.1706 + return typedata->vtable->marshaller;
1.1707 +}
1.1708 +
1.1709 +typedef struct
1.1710 +{
1.1711 + DBusMessageIter *iter;
1.1712 + DBusGValueMarshalFunc marshaller;
1.1713 + gboolean err;
1.1714 +} DBusGValueCollectionMarshalData;
1.1715 +
1.1716 +static void
1.1717 +collection_marshal_iterator (const GValue *eltval,
1.1718 + gpointer user_data)
1.1719 +{
1.1720 + DBusGValueCollectionMarshalData *data = user_data;
1.1721 +
1.1722 + if (data->err)
1.1723 + return;
1.1724 +
1.1725 + if (!data->marshaller (data->iter, eltval))
1.1726 + data->err = TRUE;
1.1727 +}
1.1728 +
1.1729 +static gboolean
1.1730 +marshal_collection (DBusMessageIter *iter,
1.1731 + const GValue *value)
1.1732 +{
1.1733 + GType coltype;
1.1734 + GType subtype;
1.1735 +
1.1736 + coltype = G_VALUE_TYPE (value);
1.1737 + subtype = dbus_g_type_get_collection_specialization (coltype);
1.1738 +
1.1739 + if (_dbus_g_type_is_fixed (subtype))
1.1740 + return marshal_collection_array (iter, value);
1.1741 + else
1.1742 + return marshal_collection_ptrarray (iter, value);
1.1743 +}
1.1744 +
1.1745 +static gboolean
1.1746 +marshal_collection_ptrarray (DBusMessageIter *iter,
1.1747 + const GValue *value)
1.1748 +{
1.1749 + GType coltype;
1.1750 + GType elt_gtype;
1.1751 + DBusGValueCollectionMarshalData data;
1.1752 + DBusMessageIter subiter;
1.1753 + char *elt_sig;
1.1754 +
1.1755 + coltype = G_VALUE_TYPE (value);
1.1756 + elt_gtype = dbus_g_type_get_collection_specialization (coltype);
1.1757 + data.marshaller = get_type_marshaller (elt_gtype);
1.1758 + if (!data.marshaller)
1.1759 + return FALSE;
1.1760 +
1.1761 + elt_sig = _dbus_gtype_to_signature (elt_gtype);
1.1762 + if (!elt_sig)
1.1763 + {
1.1764 + g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype));
1.1765 + return FALSE;
1.1766 + }
1.1767 +
1.1768 + if (!dbus_message_iter_open_container (iter,
1.1769 + DBUS_TYPE_ARRAY,
1.1770 + elt_sig,
1.1771 + &subiter))
1.1772 + goto oom;
1.1773 + g_free (elt_sig);
1.1774 +
1.1775 + data.iter = &subiter;
1.1776 + data.err = FALSE;
1.1777 +
1.1778 + dbus_g_type_collection_value_iterate (value,
1.1779 + collection_marshal_iterator,
1.1780 + &data);
1.1781 +
1.1782 + if (!dbus_message_iter_close_container (iter, &subiter))
1.1783 + goto oom;
1.1784 +
1.1785 + return !data.err;
1.1786 + oom:
1.1787 + g_error ("out of memory");
1.1788 + return FALSE;
1.1789 +}
1.1790 +
1.1791 +
1.1792 +static gboolean
1.1793 +marshal_collection_array (DBusMessageIter *iter,
1.1794 + const GValue *value)
1.1795 +{
1.1796 + GType elt_gtype;
1.1797 + DBusMessageIter subiter;
1.1798 + GArray *array;
1.1799 + guint elt_size;
1.1800 + char *subsignature_str;
1.1801 +
1.1802 + elt_gtype = dbus_g_type_get_collection_specialization (G_VALUE_TYPE (value));
1.1803 + g_assert (_dbus_g_type_is_fixed (elt_gtype));
1.1804 + subsignature_str = _dbus_gtype_to_signature (elt_gtype);
1.1805 + if (!subsignature_str)
1.1806 + {
1.1807 + g_warning ("Cannot marshal type \"%s\" in collection\n", g_type_name (elt_gtype));
1.1808 + return FALSE;
1.1809 + }
1.1810 +
1.1811 + elt_size = _dbus_g_type_fixed_get_size (elt_gtype);
1.1812 +
1.1813 + array = g_value_get_boxed (value);
1.1814 +
1.1815 + if (!dbus_message_iter_open_container (iter,
1.1816 + DBUS_TYPE_ARRAY,
1.1817 + subsignature_str,
1.1818 + &subiter))
1.1819 + goto oom;
1.1820 +
1.1821 + /* TODO - This assumes that basic values are the same size
1.1822 + * is this always true? If it is we can probably avoid
1.1823 + * a lot of the overhead in _marshal_basic_instance...
1.1824 + */
1.1825 + if (!array || !dbus_message_iter_append_fixed_array (&subiter,
1.1826 + subsignature_str[0],
1.1827 + &(array->data),
1.1828 + array->len))
1.1829 + goto oom;
1.1830 +
1.1831 + if (!dbus_message_iter_close_container (iter, &subiter))
1.1832 + goto oom;
1.1833 + g_free (subsignature_str);
1.1834 + return TRUE;
1.1835 + oom:
1.1836 + g_error ("out of memory");
1.1837 + return FALSE;
1.1838 +}
1.1839 +
1.1840 +gboolean
1.1841 +_dbus_gvalue_marshal (DBusMessageIter *iter,
1.1842 + const GValue *value)
1.1843 +{
1.1844 + GType gtype;
1.1845 + DBusGValueMarshalFunc marshaller;
1.1846 +
1.1847 + gtype = G_VALUE_TYPE (value);
1.1848 +
1.1849 + marshaller = get_type_marshaller (gtype);
1.1850 + if (marshaller == NULL)
1.1851 + return FALSE;
1.1852 + return marshaller (iter, value);
1.1853 +}
1.1854 +
1.1855 +#ifdef DBUS_BUILD_TESTS
1.1856 +
1.1857 +static void
1.1858 +assert_type_maps_to (GType gtype, const char *expected_sig)
1.1859 +{
1.1860 + char *sig;
1.1861 + sig = _dbus_gtype_to_signature (gtype);
1.1862 + g_assert (sig != NULL);
1.1863 + g_assert (!strcmp (expected_sig, sig));
1.1864 + g_free (sig);
1.1865 +}
1.1866 +
1.1867 +static void
1.1868 +assert_signature_maps_to (const char *sig, GType expected_gtype)
1.1869 +{
1.1870 + g_assert (_dbus_gtype_from_signature (sig, TRUE) == expected_gtype);
1.1871 +}
1.1872 +
1.1873 +static void
1.1874 +assert_bidirectional_mapping (GType gtype, const char *expected_sig)
1.1875 +{
1.1876 + assert_type_maps_to (gtype, expected_sig);
1.1877 + assert_signature_maps_to (expected_sig, gtype);
1.1878 +}
1.1879 +
1.1880 +/**
1.1881 + * @ingroup DBusGLibInternals
1.1882 + * @test_data_dir:
1.1883 + *
1.1884 + * Unit test for general glib stuff
1.1885 + * Returns: #TRUE on success.
1.1886 + */
1.1887 + #ifdef __SYMBIAN32__
1.1888 + EXPORT_C
1.1889 + #endif
1.1890 +gboolean
1.1891 +_dbus_gvalue_test (const char *test_data_dir)
1.1892 +{
1.1893 + _dbus_g_value_types_init ();
1.1894 +
1.1895 + assert_bidirectional_mapping (G_TYPE_STRING, DBUS_TYPE_STRING_AS_STRING);
1.1896 + assert_bidirectional_mapping (G_TYPE_UCHAR, DBUS_TYPE_BYTE_AS_STRING);
1.1897 + assert_bidirectional_mapping (G_TYPE_UINT, DBUS_TYPE_UINT32_AS_STRING);
1.1898 +
1.1899 + assert_bidirectional_mapping (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1.1900 + 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);
1.1901 + assert_bidirectional_mapping (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
1.1902 + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING);
1.1903 + assert_bidirectional_mapping (dbus_g_type_get_collection ("GArray", G_TYPE_INT),
1.1904 + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING);
1.1905 +
1.1906 + assert_bidirectional_mapping (dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_STRING, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID),
1.1907 + 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 );
1.1908 + return TRUE;
1.1909 +}
1.1910 +
1.1911 +#endif /* DBUS_BUILD_TESTS */