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