index.html
Main Page
|
modules.html
Modules
|
namespaces.html
Namespace List
|
hierarchy.html
Class Hierarchy
|
annotated.html
Data Structures
|
dirs.html
Directories
|
files.html
File List
|
namespacemembers.html
Namespace Members
|
functions.html
Data Fields
|
pages.html
Related Pages
dir_000005.html
glib
dbus-gvalue-utils.c
00001
/* -*- mode: C; c-file-style: "gnu" -*- */
00002
/* dbus-gvalue-utils.c: Non-DBus-specific functions related to GType/GValue
00003
*
00004
* Copyright (C) 2005 Red Hat, Inc.
00005
*
00006
* Licensed under the Academic Free License version 2.1
00007
*
00008
* This program is free software; you can redistribute it and/or modify
00009
* it under the terms of the GNU General Public License as published by
00010
* the Free Software Foundation; either version 2 of the License, or
00011
* (at your option) any later version.
00012
*
00013
* This program is distributed in the hope that it will be useful,
00014
* but WITHOUT ANY WARRANTY; without even the implied warranty of
00015
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016
* GNU General Public License for more details.
00017
*
00018
* You should have received a copy of the GNU General Public License
00019
* along with this program; if not, write to the Free Software
00020
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021
*
00022
*/
00023
00024
#include <config.h>
00025
#include "dbus/dbus-glib.h"
00026
#include "dbus-gvalue-utils.h"
00027
#include "dbus-gtest.h"
00028
#include <glib.h>
00029
#include <string.h>
00030
#include <gobject/gvaluecollector.h>
00031
00032
00033
static
guint
00034 fixed_type_get_size (GType type)
00035 {
00036
switch
(type)
00037     {
00038
case
G_TYPE_CHAR:
00039
case
G_TYPE_UCHAR:
00040
return
sizeof
(gchar);
00041
case
G_TYPE_BOOLEAN:
00042
return
sizeof
(gboolean);
00043
case
G_TYPE_LONG:
00044
case
G_TYPE_ULONG:
00045
return
sizeof
(glong);
00046
case
G_TYPE_INT:
00047
case
G_TYPE_UINT:
00048
return
sizeof
(gint);
00049
case
G_TYPE_INT64:
00050
case
G_TYPE_UINT64:
00051
return
sizeof
(gint64);
00052
case
G_TYPE_FLOAT:
00053
return
sizeof
(gfloat);
00054
case
G_TYPE_DOUBLE:
00055
return
sizeof
(gdouble);
00056
default
:
00057
return
0;
00058     }
00059 }
00060
00061 gboolean
00062 dbus_g_type_is_fixed (GType type)
00063 {
00064
return
fixed_type_get_size (type) > 0;
00065 }
00066
00067 guint
00068 dbus_g_type_fixed_get_size (GType type)
00069 {
00070   g_assert (dbus_g_type_is_fixed (type));
00071
return
fixed_type_get_size (type);
00072 }
00073
00074 gboolean
00075 dbus_gvalue_store (GValue          *value,
00076                    gpointer        storage)
00077 {
00078
/* FIXME - can we use the GValue lcopy_value method
00079
* to do this in a cleaner way?
00080
*/
00081
switch
(g_type_fundamental (G_VALUE_TYPE (value)))
00082     {
00083
case
G_TYPE_CHAR:
00084       *((gchar *) storage) = g_value_get_char (value);
00085
return
group__DBusMacros.html#ga2
TRUE
;
00086
case
G_TYPE_UCHAR:
00087       *((guchar *) storage) = g_value_get_uchar (value);
00088
return
group__DBusMacros.html#ga2
TRUE
;
00089
case
G_TYPE_BOOLEAN:
00090       *((gboolean *) storage) = g_value_get_boolean (value);
00091
return
group__DBusMacros.html#ga2
TRUE
;
00092
case
G_TYPE_LONG:
00093       *((glong *) storage) = g_value_get_long (value);
00094
return
group__DBusMacros.html#ga2
TRUE
;
00095
case
G_TYPE_ULONG:
00096       *((gulong *) storage) = g_value_get_ulong (value);
00097
return
group__DBusMacros.html#ga2
TRUE
;
00098
case
G_TYPE_INT:
00099       *((gint *) storage) = g_value_get_int (value);
00100
return
group__DBusMacros.html#ga2
TRUE
;
00101
case
G_TYPE_UINT:
00102       *((guint *) storage) = g_value_get_uint (value);
00103
return
group__DBusMacros.html#ga2
TRUE
;
00104
case
G_TYPE_INT64:
00105       *((gint64 *) storage) = g_value_get_int64 (value);
00106
return
group__DBusMacros.html#ga2
TRUE
;
00107
case
G_TYPE_UINT64:
00108       *((guint64 *) storage) = g_value_get_uint64 (value);
00109
return
group__DBusMacros.html#ga2
TRUE
;
00110
case
G_TYPE_DOUBLE:
00111       *((gdouble *) storage) = g_value_get_double (value);
00112
return
group__DBusMacros.html#ga2
TRUE
;
00113
case
G_TYPE_STRING:
00114       *((gchar **) storage) = (
char
*) g_value_get_string (value);
00115
return
group__DBusMacros.html#ga2
TRUE
;
00116
case
G_TYPE_POINTER:
00117       *((gpointer *) storage) = g_value_get_pointer (value);
00118
return
group__DBusMacros.html#ga2
TRUE
;
00119
case
G_TYPE_OBJECT:
00120       *((gpointer *) storage) = g_value_get_object (value);
00121
return
group__DBusMacros.html#ga2
TRUE
;
00122
case
G_TYPE_BOXED:
00123       *((gpointer *) storage) = g_value_get_boxed (value);
00124
return
group__DBusMacros.html#ga2
TRUE
;
00125
default
:
00126
return
group__DBusMacros.html#ga3
FALSE
;
00127     }
00128 }
00129
00130 gboolean
00131 dbus_gvalue_set_from_pointer (GValue          *value,
00132                               gconstpointer    storage)
00133 {
00134
/* FIXME - is there a better way to do this? */
00135
switch
(g_type_fundamental (G_VALUE_TYPE (value)))
00136     {
00137
case
G_TYPE_CHAR:
00138       g_value_set_char (value, *((gchar *) storage));
00139
return
group__DBusMacros.html#ga2
TRUE
;
00140
case
G_TYPE_UCHAR:
00141       g_value_set_uchar (value, *((guchar *) storage));
00142
return
group__DBusMacros.html#ga2
TRUE
;
00143
case
G_TYPE_BOOLEAN:
00144       g_value_set_boolean (value, *((gboolean *) storage));
00145
return
group__DBusMacros.html#ga2
TRUE
;
00146
case
G_TYPE_LONG:
00147       g_value_set_long (value, *((glong *) storage));
00148
return
group__DBusMacros.html#ga2
TRUE
;
00149
case
G_TYPE_ULONG:
00150       g_value_set_ulong (value, *((gulong *) storage));
00151
return
group__DBusMacros.html#ga2
TRUE
;
00152
case
G_TYPE_INT:
00153       g_value_set_int (value, *((gint *) storage));
00154
return
group__DBusMacros.html#ga2
TRUE
;
00155
case
G_TYPE_UINT:
00156       g_value_set_uint (value, *((guint *) storage));
00157
return
group__DBusMacros.html#ga2
TRUE
;
00158
case
G_TYPE_INT64:
00159       g_value_set_int64 (value, *((gint64 *) storage));
00160
return
group__DBusMacros.html#ga2
TRUE
;
00161
case
G_TYPE_UINT64:
00162       g_value_set_uint64 (value, *((guint64 *) storage));
00163
return
group__DBusMacros.html#ga2
TRUE
;
00164
case
G_TYPE_DOUBLE:
00165       g_value_set_double (value, *((gdouble *) storage));
00166
return
group__DBusMacros.html#ga2
TRUE
;
00167
case
G_TYPE_STRING:
00168       g_value_set_string (value, *((gchar **) storage));
00169
return
group__DBusMacros.html#ga2
TRUE
;
00170
case
G_TYPE_POINTER:
00171       g_value_set_pointer (value, *((gpointer *) storage));
00172
return
group__DBusMacros.html#ga2
TRUE
;
00173
case
G_TYPE_OBJECT:
00174       g_value_set_object (value, *((gpointer *) storage));
00175
return
group__DBusMacros.html#ga2
TRUE
;
00176
case
G_TYPE_BOXED:
00177       g_value_set_boxed (value, *((gpointer *) storage));
00178
return
group__DBusMacros.html#ga2
TRUE
;
00179
default
:
00180
return
group__DBusMacros.html#ga3
FALSE
;
00181     }
00182 }
00183
00184 gboolean
00185 dbus_gvalue_take (GValue          *value,
00186                   GTypeCValue     *cvalue)
00187 {
00188   GType g_type;
00189   GTypeValueTable *value_table;
00190
char
*error_msg;
00191
00192   g_type = G_VALUE_TYPE (value);
00193   value_table = g_type_value_table_peek (g_type);
00194
00195   error_msg = value_table->collect_value (value, 1, cvalue, G_VALUE_NOCOPY_CONTENTS);
00196
if
(error_msg)
00197     {
00198       g_warning (
"%s: %s"
, G_STRLOC, error_msg);
00199       g_free (error_msg);
00200
return
group__DBusMacros.html#ga3
FALSE
;
00201     }
00202
/* Clear the NOCOPY_CONTENTS flag; we want to take ownership
00203
* of the value.
00204
*/
00205   value->data[1].v_uint &= ~(G_VALUE_NOCOPY_CONTENTS);
00206
return
group__DBusMacros.html#ga2
TRUE
;
00207 }
00208
00209 gboolean
00210 _dbus_gtype_can_signal_error (GType gtype)
00211 {
00212
switch
(gtype)
00213     {
00214
case
G_TYPE_BOOLEAN:
00215
case
G_TYPE_INT:
00216
case
G_TYPE_UINT:
00217
case
G_TYPE_STRING:
00218
case
G_TYPE_BOXED:
00219
case
G_TYPE_OBJECT:
00220
return
group__DBusMacros.html#ga2
TRUE
;
00221
default
:
00222
return
group__DBusMacros.html#ga3
FALSE
;
00223     }
00224 }
00225
00226 gboolean
00227 _dbus_gvalue_signals_error (
const
GValue *value)
00228 {
00229
/* Hardcoded rules for return value semantics for certain
00230
* types.  Perhaps in the future we'd want an annotation
00231
* specifying which return values are errors, but in
00232
* reality people will probably just use boolean and
00233
* boxed, and there the semantics are pretty standard.
00234
*/
00235
switch
(G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)))
00236     {
00237
case
G_TYPE_BOOLEAN:
00238
return
(g_value_get_boolean (value) ==
group__DBusMacros.html#ga3
FALSE
);
00239
break
;
00240
case
G_TYPE_INT:
00241
return
(g_value_get_int (value) < 0);
00242
break
;
00243
case
G_TYPE_UINT:
00244
return
(g_value_get_uint (value) == 0);
00245
break
;
00246
case
G_TYPE_STRING:
00247
return
(g_value_get_string (value) ==
group__DBusMacros.html#ga4
NULL
);
00248
break
;
00249
case
G_TYPE_BOXED:
00250
return
(g_value_get_boxed (value) ==
group__DBusMacros.html#ga4
NULL
);
00251
break
;
00252
case
G_TYPE_OBJECT:
00253
return
(g_value_get_boxed (value) ==
group__DBusMacros.html#ga4
NULL
);
00254
break
;
00255
default
:
00256       g_assert_not_reached ();
00257
return
group__DBusMacros.html#ga3
FALSE
;
00258     }
00259 }
00260
00261
00262
static
gboolean
00263 hash_func_from_gtype (GType gtype, GHashFunc *func)
00264 {
00265
switch
(gtype)
00266     {
00267
case
G_TYPE_CHAR:
00268
case
G_TYPE_UCHAR:
00269
case
G_TYPE_BOOLEAN:
00270
case
G_TYPE_INT:
00271
case
G_TYPE_UINT:
00272       *func =
group__DBusMacros.html#ga4
NULL
;
00273
return
group__DBusMacros.html#ga2
TRUE
;
00274
case
G_TYPE_STRING:
00275       *func = g_str_hash;
00276
return
group__DBusMacros.html#ga2
TRUE
;
00277
default
:
00278
return
group__DBusMacros.html#ga3
FALSE
;
00279     }
00280 }
00281
00282
static
void
00283 unset_and_free_g_value (gpointer val)
00284 {
00285   GValue *value = val;
00286
00287   g_value_unset (value);
00288   g_free (value);
00289 }
00290
00291
static
gboolean
00292 hash_free_from_gtype (GType gtype, GDestroyNotify *func)
00293 {
00294
switch
(gtype)
00295     {
00296
case
G_TYPE_CHAR:
00297
case
G_TYPE_UCHAR:
00298
case
G_TYPE_BOOLEAN:
00299
case
G_TYPE_INT:
00300
case
G_TYPE_UINT:
00301       *func =
group__DBusMacros.html#ga4
NULL
;
00302
return
group__DBusMacros.html#ga2
TRUE
;
00303
case
G_TYPE_STRING:
00304       *func = g_free;
00305
return
group__DBusMacros.html#ga2
TRUE
;
00306
default
:
00307
if
(gtype == G_TYPE_VALUE)
00308         {
00309           *func = unset_and_free_g_value;
00310
return
group__DBusMacros.html#ga2
TRUE
;
00311         }
00312
return
group__DBusMacros.html#ga3
FALSE
;
00313     }
00314 }
00315
00316 gboolean
00317 dbus_gtype_is_valid_hash_key (GType type)
00318 {
00319   GHashFunc func;
00320
return
hash_func_from_gtype (type, &func);
00321 }
00322
00323 gboolean
00324 dbus_gtype_is_valid_hash_value (GType type)
00325 {
00326   GDestroyNotify func;
00327
return
hash_free_from_gtype (type, &func);
00328 }
00329
00330 GHashFunc
00331 dbus_g_hash_func_from_gtype (GType gtype)
00332 {
00333   GHashFunc func;
00334   gboolean ret;
00335   ret = hash_func_from_gtype (gtype, &func);
00336   g_assert (ret !=
group__DBusMacros.html#ga3
FALSE
);
00337
return
func;
00338 }
00339
00340 GEqualFunc
00341 dbus_g_hash_equal_from_gtype (GType gtype)
00342 {
00343   g_assert (dbus_gtype_is_valid_hash_key (gtype));
00344
00345
switch
(gtype)
00346     {
00347
case
G_TYPE_CHAR:
00348
case
G_TYPE_UCHAR:
00349
case
G_TYPE_BOOLEAN:
00350
case
G_TYPE_INT:
00351
case
G_TYPE_UINT:
00352
return
group__DBusMacros.html#ga4
NULL
;
00353
case
G_TYPE_STRING:
00354
return
g_str_equal;
00355
default
:
00356       g_assert_not_reached ();
00357
return
group__DBusMacros.html#ga4
NULL
;
00358     }
00359 }
00360
00361 GDestroyNotify
00362 dbus_g_hash_free_from_gtype (GType gtype)
00363 {
00364   GDestroyNotify func;
00365   gboolean ret;
00366   ret = hash_free_from_gtype (gtype, &func);
00367   g_assert (ret !=
group__DBusMacros.html#ga3
FALSE
);
00368
return
func;
00369 }
00370
00371
static
void
00372 gvalue_from_hash_value (GValue *value, gpointer instance)
00373 {
00374
switch
(g_type_fundamental (G_VALUE_TYPE (value)))
00375     {
00376
case
G_TYPE_CHAR:
00377       g_value_set_char (value, (gchar) GPOINTER_TO_INT (instance));
00378
break
;
00379
case
G_TYPE_UCHAR:
00380       g_value_set_uchar (value, (guchar) GPOINTER_TO_UINT (instance));
00381
break
;
00382
case
G_TYPE_BOOLEAN:
00383       g_value_set_boolean (value, (gboolean) GPOINTER_TO_UINT (instance));
00384
break
;
00385
case
G_TYPE_INT:
00386       g_value_set_int (value, GPOINTER_TO_INT (instance));
00387
break
;
00388
case
G_TYPE_UINT:
00389       g_value_set_uint (value, GPOINTER_TO_UINT (instance));
00390
break
;
00391
case
G_TYPE_STRING:
00392       g_value_set_static_string (value, instance);
00393
break
;
00394
case
G_TYPE_POINTER:
00395       g_value_set_pointer (value, instance);
00396
break
;
00397
case
G_TYPE_BOXED:
00398       g_value_set_static_boxed (value, instance);
00399
break
;
00400
case
G_TYPE_OBJECT:
00401       g_value_set_object (value, instance);
00402       g_object_unref (g_value_get_object (value));
00403
break
;
00404
default
:
00405       g_assert_not_reached ();
00406
break
;
00407     }
00408 }
00409
00410
static
gpointer
00411 hash_value_from_gvalue (GValue *value)
00412 {
00413
switch
(g_type_fundamental (G_VALUE_TYPE (value)))
00414     {
00415
case
G_TYPE_CHAR:
00416
return
GINT_TO_POINTER ((
int
) g_value_get_char (value));
00417
break
;
00418
case
G_TYPE_UCHAR:
00419
return
GUINT_TO_POINTER ((guint) g_value_get_uchar (value));
00420
break
;
00421
case
G_TYPE_BOOLEAN:
00422
return
GUINT_TO_POINTER ((guint) g_value_get_boolean (value));
00423
break
;
00424
case
G_TYPE_INT:
00425
return
GINT_TO_POINTER (g_value_get_int (value));
00426
break
;
00427
case
G_TYPE_UINT:
00428
return
GUINT_TO_POINTER (g_value_get_uint (value));
00429
break
;
00430
case
G_TYPE_STRING:
00431
return
(gpointer) g_value_get_string (value);
00432
break
;
00433
case
G_TYPE_POINTER:
00434
return
g_value_get_pointer (value);
00435
break
;
00436
case
G_TYPE_BOXED:
00437
return
g_value_get_boxed (value);
00438
break
;
00439
case
G_TYPE_OBJECT:
00440
return
g_value_get_object (value);
00441
break
;
00442
default
:
00443       g_assert_not_reached ();
00444
return
group__DBusMacros.html#ga4
NULL
;
00445     }
00446 }
00447
structDBusGHashTableValueForeachData.html
00448
struct
structDBusGHashTableValueForeachData.html
DBusGHashTableValueForeachData
00449 {
structDBusGHashTableValueForeachData.html#o0
00450
DBusGTypeSpecializedMapIterator func;
structDBusGHashTableValueForeachData.html#o1
00451
GType
structDBusGHashTableValueForeachData.html#o1
key_type
;
structDBusGHashTableValueForeachData.html#o2
00452
GType
structDBusGHashTableValueForeachData.html#o2
value_type
;
structDBusGHashTableValueForeachData.html#o3
00453
gpointer
structDBusGHashTableValueForeachData.html#o3
data
;
00454 };
00455
00456
static
void
00457 hashtable_foreach_with_values (gpointer key, gpointer value, gpointer user_data)
00458 {
00459   GValue key_val = {0, };
00460   GValue value_val = {0, };
00461
struct
structDBusGHashTableValueForeachData.html
DBusGHashTableValueForeachData
*
structDBusGHashTableValueForeachData.html#o3
data
= user_data;
00462
00463   g_value_init (&key_val, data->
structDBusGHashTableValueForeachData.html#o1
key_type
);
00464   g_value_init (&value_val, data->
structDBusGHashTableValueForeachData.html#o2
value_type
);
00465   gvalue_from_hash_value (&key_val, key);
00466   gvalue_from_hash_value (&value_val, value);
00467
00468   data->
structDBusGHashTableValueForeachData.html#o0
func
(&key_val, &value_val, data->
structDBusGHashTableValueForeachData.html#o3
data
);
00469 }
00470
00471
00472
static
void
00473 hashtable_iterator (GType                           hash_type,
00474                     gpointer                        instance,
00475                     DBusGTypeSpecializedMapIterator iterator,
00476                     gpointer                        user_data)
00477 {
00478
struct
structDBusGHashTableValueForeachData.html
DBusGHashTableValueForeachData
data;
00479   GType key_gtype;
00480   GType value_gtype;
00481
00482   key_gtype = dbus_g_type_get_map_key_specialization (hash_type);
00483   value_gtype = dbus_g_type_get_map_value_specialization (hash_type);
00484
00485   data.
structDBusGHashTableValueForeachData.html#o0
func
= iterator;
00486   data.
structDBusGHashTableValueForeachData.html#o1
key_type
= key_gtype;
00487   data.
structDBusGHashTableValueForeachData.html#o2
value_type
= value_gtype;
00488   data.
structDBusGHashTableValueForeachData.html#o3
data
= user_data;
00489
00490   g_hash_table_foreach (instance, hashtable_foreach_with_values, &data);
00491 }
00492
00493
void
00494 dbus_g_hash_table_insert_steal_values (GHashTable *table,
00495                                        GValue     *key_val,
00496                                        GValue     *value_val)
00497 {
00498   gpointer key, val;
00499
00500   key = hash_value_from_gvalue (key_val);
00501   val = hash_value_from_gvalue (value_val);
00502
00503   g_hash_table_insert (table, key, val);
00504 }
00505
00506
static
void
00507 hashtable_append (
structDBusGTypeSpecializedAppendContext.html
DBusGTypeSpecializedAppendContext
*ctx,
00508                   GValue                            *key,
00509                   GValue                            *val)
00510 {
00511   GHashTable *table;
00512
00513   table = g_value_get_boxed (ctx->
structDBusGTypeSpecializedAppendContext.html#o0
val
);
00514   dbus_g_hash_table_insert_steal_values (table, key, val);
00515 }
00516
00517
static
gpointer
00518 hashtable_constructor (GType type)
00519 {
00520   GHashTable *ret;
00521   GType key_gtype;
00522   GType value_gtype;
00523
00524   key_gtype = dbus_g_type_get_map_key_specialization (type);
00525   value_gtype = dbus_g_type_get_map_value_specialization (type);
00526
00527   ret = g_hash_table_new_full (dbus_g_hash_func_from_gtype (key_gtype),
00528                                dbus_g_hash_equal_from_gtype (key_gtype),
00529                                dbus_g_hash_free_from_gtype (key_gtype),
00530                                dbus_g_hash_free_from_gtype (value_gtype));
00531
return
ret;
00532 }
00533
00534
static
void
00535 hashtable_insert_values (GHashTable       *table,
00536
const
GValue     *key_val,
00537
const
GValue     *value_val)
00538 {
00539   GValue key_copy = {0, };
00540   GValue value_copy = {0, };
00541
00542   g_value_init (&key_copy, G_VALUE_TYPE (key_val));
00543   g_value_copy (key_val, &key_copy);
00544   g_value_init (&value_copy, G_VALUE_TYPE (value_val));
00545   g_value_copy (value_val, &value_copy);
00546
00547   dbus_g_hash_table_insert_steal_values (table, &key_copy, &value_copy);
00548 }
00549
00550
static
void
00551 hashtable_foreach_copy (
const
GValue *key,
const
GValue *val, gpointer data)
00552 {
00553   hashtable_insert_values ((GHashTable *) data, key, val);
00554 }
00555
00556
static
gpointer
00557 hashtable_copy (GType type, gpointer src)
00558 {
00559   GHashTable *ghash;
00560   GHashTable *ret;
00561   GValue hashval = {0,};
00562
00563   ghash = src;
00564
00565   ret = hashtable_constructor (type);
00566
00567   g_value_init (&hashval, type);
00568   g_value_set_static_boxed (&hashval, ghash);
00569   dbus_g_type_map_value_iterate (&hashval, hashtable_foreach_copy, ret);
00570
return
ret;
00571 }
00572
00573
static
void
00574 hashtable_free (GType type, gpointer val)
00575 {
00576   g_hash_table_destroy (val);
00577 }
00578
00579
static
gpointer
00580 array_constructor (GType type)
00581 {
00582   GArray *array;
00583   guint elt_size;
00584   GType elt_type;
00585   gboolean zero_terminated;
00586   gboolean clear;
00587
00588   elt_type = dbus_g_type_get_collection_specialization (type);
00589   g_assert (elt_type != G_TYPE_INVALID);
00590
00591   elt_size = dbus_g_type_fixed_get_size (elt_type);
00592
00593
/* These are "safe" defaults */
00594   zero_terminated =
group__DBusMacros.html#ga2
TRUE
;
/* ((struct _DBusGRealArray*) garray)->zero_terminated; */
00595   clear =
group__DBusMacros.html#ga2
TRUE
;
/* ((struct _DBusGRealArray*) garray)->clear; */
00596
00597   array = g_array_new (zero_terminated, clear, elt_size);
00598
return
array;
00599 }
00600
00601
static
gpointer
00602 array_copy (GType type, gpointer src)
00603 {
00604   GArray *garray;
00605   GArray *
new
;
00606
00607   garray = src;
00608
00609
new
= array_constructor (type);
00610   g_array_append_vals (
new
, garray->data, garray->len);
00611
00612
return
new
;
00613 }
00614
00615
static
void
00616 array_free (GType type, gpointer val)
00617 {
00618   GArray *array;
00619   array = val;
00620   g_array_free (array,
group__DBusMacros.html#ga2
TRUE
);
00621 }
00622
00623
static
gboolean
00624 array_fixed_accessor (GType type, gpointer instance, gpointer *values, guint *len)
00625 {
00626   GType elt_type;
00627   GArray *array = instance;
00628
00629   elt_type = dbus_g_type_get_collection_specialization (type);
00630
if
(!dbus_g_type_is_fixed (elt_type))
00631
return
group__DBusMacros.html#ga3
FALSE
;
00632
00633   *values = array->data;
00634   *len = array->len;
00635
return
group__DBusMacros.html#ga2
TRUE
;
00636 }
00637
00638
static
gpointer
00639 ptrarray_constructor (GType type)
00640 {
00641
/* Later we should determine a destructor, need g_ptr_array_destroy */
00642
return
g_ptr_array_new ();
00643 }
00644
00645
static
void
00646 gvalue_from_ptrarray_value (GValue *value, gpointer instance)
00647 {
00648
switch
(g_type_fundamental (G_VALUE_TYPE (value)))
00649     {
00650
case
G_TYPE_STRING:
00651       g_value_set_string (value, instance);
00652
break
;
00653
case
G_TYPE_POINTER:
00654       g_value_set_pointer (value, instance);
00655
break
;
00656
case
G_TYPE_BOXED:
00657       g_value_set_static_boxed (value, instance);
00658
break
;
00659
case
G_TYPE_OBJECT:
00660       g_value_set_object (value, instance);
00661       g_object_unref (g_value_get_object (value));
00662
break
;
00663
default
:
00664       g_assert_not_reached ();
00665
break
;
00666     }
00667 }
00668
00669
static
gpointer
00670 ptrarray_value_from_gvalue (
const
GValue *value)
00671 {
00672
switch
(g_type_fundamental (G_VALUE_TYPE (value)))
00673     {
00674
case
G_TYPE_STRING:
00675
return
(gpointer) g_value_get_string (value);
00676
break
;
00677
case
G_TYPE_POINTER:
00678
return
g_value_get_pointer (value);
00679
break
;
00680
case
G_TYPE_BOXED:
00681
return
g_value_get_boxed (value);
00682
break
;
00683
case
G_TYPE_OBJECT:
00684
return
g_value_get_object (value);
00685
break
;
00686
default
:
00687       g_assert_not_reached ();
00688
return
group__DBusMacros.html#ga4
NULL
;
00689     }
00690 }
00691
00692
static
void
00693 ptrarray_iterator (GType                                   hash_type,
00694                    gpointer                                instance,
00695                    DBusGTypeSpecializedCollectionIterator  iterator,
00696                    gpointer                                user_data)
00697 {
00698   GPtrArray *ptrarray;
00699   GType elt_gtype;
00700   guint i;
00701
00702   ptrarray = instance;
00703
00704   elt_gtype = dbus_g_type_get_collection_specialization (hash_type);
00705
00706
for
(i = 0; i < ptrarray->len; i++)
00707     {
00708       GValue val = {0, };
00709       g_value_init (&val, elt_gtype);
00710       gvalue_from_ptrarray_value (&val, g_ptr_array_index (ptrarray, i));
00711       iterator (&val, user_data);
00712     }
00713 }
00714
00715
static
void
00716 ptrarray_copy_elt (
const
GValue *val, gpointer user_data)
00717 {
00718   GPtrArray *dest = user_data;
00719   GValue val_copy = {0, };
00720
00721   g_value_init (&val_copy, G_VALUE_TYPE (val));
00722   g_value_copy (val, &val_copy);
00723
00724   g_ptr_array_add (dest, ptrarray_value_from_gvalue (&val_copy));
00725 }
00726
00727
static
gpointer
00728 ptrarray_copy (GType type, gpointer src)
00729 {
00730   GPtrArray *
new
;
00731   GValue array_val = {0, };
00732
00733   g_value_init (&array_val, type);
00734   g_value_set_static_boxed (&array_val, src);
00735
00736
new
= ptrarray_constructor (type);
00737   dbus_g_type_collection_value_iterate (&array_val, ptrarray_copy_elt,
new
);
00738
00739
return
new
;
00740 }
00741
00742
static
void
00743 ptrarray_append (
structDBusGTypeSpecializedAppendContext.html
DBusGTypeSpecializedAppendContext
*ctx, GValue *value)
00744 {
00745   GPtrArray *array;
00746
00747   array = g_value_get_boxed (ctx->
structDBusGTypeSpecializedAppendContext.html#o0
val
);
00748
00749   g_ptr_array_add (array, ptrarray_value_from_gvalue (value));
00750 }
00751
00752
static
void
00753 ptrarray_free (GType type, gpointer val)
00754 {
00755   GPtrArray *array;
00756   array = val;
00757   g_ptr_array_free (array,
group__DBusMacros.html#ga2
TRUE
);
00758 }
00759
00760
static
gpointer
00761 slist_constructor (GType type)
00762 {
00763
return
group__DBusMacros.html#ga4
NULL
;
00764 }
00765
00766
static
void
00767 slist_iterator (GType                                   list_type,
00768                 gpointer                                instance,
00769                 DBusGTypeSpecializedCollectionIterator  iterator,
00770                 gpointer                                user_data)
00771 {
00772   GSList *slist;
00773   GType elt_gtype;
00774
00775   slist = instance;
00776
00777   elt_gtype = dbus_g_type_get_collection_specialization (list_type);
00778
00779
while
(slist !=
group__DBusMacros.html#ga4
NULL
)
00780     {
00781       GValue val = {0, };
00782       g_value_init (&val, elt_gtype);
00783       gvalue_from_ptrarray_value (&val, slist->data);
00784       iterator (&val, user_data);
00785     }
00786 }
00787
00788
static
void
00789 slist_copy_elt (
const
GValue *val, gpointer user_data)
00790 {
00791   GSList *dest = user_data;
00792   GValue val_copy = {0, };
00793
00794   g_value_init (&val_copy, G_VALUE_TYPE (val));
00795   g_value_copy (val, &val_copy);
00796
00797   g_slist_append (dest, ptrarray_value_from_gvalue (&val_copy));
00798 }
00799
00800
static
gpointer
00801 slist_copy (GType type, gpointer src)
00802 {
00803   GSList *
new
;
00804   GValue slist_val = {0, };
00805
00806   g_value_init (&slist_val, type);
00807   g_value_set_static_boxed (&slist_val, src);
00808
00809
new
= slist_constructor (type);
00810   dbus_g_type_collection_value_iterate (&slist_val, slist_copy_elt,
new
);
00811
00812
return
new
;
00813 }
00814
00815
static
void
00816 slist_append (
structDBusGTypeSpecializedAppendContext.html
DBusGTypeSpecializedAppendContext
*ctx, GValue *value)
00817 {
00818   GSList *list;
00819
00820   list = g_value_get_boxed (ctx->
structDBusGTypeSpecializedAppendContext.html#o0
val
);
00821   list = g_slist_prepend (list, ptrarray_value_from_gvalue (value));
00822   g_value_set_static_boxed (ctx->
structDBusGTypeSpecializedAppendContext.html#o0
val
, list);
00823 }
00824
00825
static
void
00826 slist_end_append (
structDBusGTypeSpecializedAppendContext.html
DBusGTypeSpecializedAppendContext
*ctx)
00827 {
00828   GSList *list;
00829
00830   list = g_value_get_boxed (ctx->
structDBusGTypeSpecializedAppendContext.html#o0
val
);
00831   list = g_slist_reverse (list);
00832
00833   g_value_set_static_boxed (ctx->
structDBusGTypeSpecializedAppendContext.html#o0
val
, list);
00834 }
00835
00836
static
void
00837 slist_free (GType type, gpointer val)
00838 {
00839   GSList *list;
00840   list = val;
00841   g_slist_free (list);
00842 }
00843
00844
void
00845 dbus_g_type_specialized_builtins_init (
void
)
00846 {
00847
static
const
structDBusGTypeSpecializedCollectionVtable.html
DBusGTypeSpecializedCollectionVtable
array_vtable = {
00848     {
00849       array_constructor,
00850       array_free,
00851       array_copy,
00852     },
00853     array_fixed_accessor,
00854
group__DBusMacros.html#ga4
NULL
,
00855     NULL,
00856     NULL
00857   };
00858
00859   dbus_g_type_register_collection (
"GArray"
, &array_vtable, 0);
00860
00861
static
const
structDBusGTypeSpecializedCollectionVtable.html
DBusGTypeSpecializedCollectionVtable
ptrarray_vtable = {
00862     {
00863       ptrarray_constructor,
00864       ptrarray_free,
00865       ptrarray_copy,
00866     },
00867     NULL,
00868     ptrarray_iterator,
00869     ptrarray_append,
00870     NULL,
00871   };
00872
00873   dbus_g_type_register_collection (
"GPtrArray"
, &ptrarray_vtable, 0);
00874
00875
static
const
structDBusGTypeSpecializedCollectionVtable.html
DBusGTypeSpecializedCollectionVtable
slist_vtable = {
00876     {
00877       slist_constructor,
00878       slist_free,
00879       slist_copy,
00880     },
00881     NULL,
00882     slist_iterator,
00883     slist_append,
00884     slist_end_append,
00885   };
00886
00887   dbus_g_type_register_collection (
"GSList"
, &slist_vtable, 0);
00888
00889
static
const
structDBusGTypeSpecializedMapVtable.html
DBusGTypeSpecializedMapVtable
hashtable_vtable = {
00890     {
00891       hashtable_constructor,
00892       hashtable_free,
00893       hashtable_copy,
00894       NULL,
00895       NULL,
00896       NULL
00897     },
00898     hashtable_iterator,
00899     hashtable_append
00900   };
00901
00902   dbus_g_type_register_map (
"GHashTable"
, &hashtable_vtable, 0);
00903 }
00904
00905
#ifdef DBUS_BUILD_TESTS
00906
00907
typedef
struct
00908
{
00909   gboolean seen_foo;
00910   gboolean seen_baz;
00911 } TestSpecializedHashData;
00912
00913
static
void
00914 test_specialized_hash (
const
GValue *key,
const
GValue *val, gpointer user_data)
00915 {
00916   TestSpecializedHashData *data = user_data;
00917
00918   g_assert (G_VALUE_HOLDS_STRING (key));
00919   g_assert (G_VALUE_HOLDS_STRING (val));
00920
00921
if
(!strcmp (g_value_get_string (key),
"foo"
))
00922     {
00923       data->seen_foo =
group__DBusMacros.html#ga2
TRUE
;
00924       g_assert (!strcmp (g_value_get_string (val),
"bar"
));
00925     }
00926
else
if
(!strcmp (g_value_get_string (key),
"baz"
))
00927     {
00928       data->seen_baz =
group__DBusMacros.html#ga2
TRUE
;
00929       g_assert (!strcmp (g_value_get_string (val),
"moo"
));
00930     }
00931
else
00932     {
00933       g_assert_not_reached ();
00934     }
00935 }
00936
00937
static
void
00938 test_specialized_hash_2 (
const
GValue *key,
const
GValue *val, gpointer user_data)
00939 {
00940   TestSpecializedHashData *data = user_data;
00941
const
GValue *realval;
00942
00943   g_assert (G_VALUE_HOLDS_STRING (key));
00944   g_assert (G_VALUE_TYPE (val) == G_TYPE_VALUE);
00945
00946   realval = g_value_get_boxed (val);
00947
00948
if
(!strcmp (g_value_get_string (key),
"foo"
))
00949     {
00950       data->seen_foo =
group__DBusMacros.html#ga2
TRUE
;
00951       g_assert (G_VALUE_HOLDS_UINT (realval));
00952       g_assert (g_value_get_uint (realval) == 20);
00953     }
00954
else
if
(!strcmp (g_value_get_string (key),
"baz"
))
00955     {
00956       data->seen_baz =
group__DBusMacros.html#ga2
TRUE
;
00957       g_assert (G_VALUE_HOLDS_STRING (realval));
00958       g_assert (!strcmp (
"bar"
, g_value_get_string (realval)));
00959     }
00960
else
00961     {
00962       g_assert_not_reached ();
00963     }
00964 }
00965
00966 gboolean
00967 _dbus_gvalue_utils_test (
const
char
*datadir)
00968 {
00969   GType type;
00970
00971   dbus_g_type_specialized_init ();
00972   dbus_g_type_specialized_builtins_init ();
00973
00974   type = dbus_g_type_get_collection (
"GArray"
, G_TYPE_UINT);
00975   g_assert (dbus_g_type_is_collection (type));
00976   g_assert (dbus_g_type_get_collection_specialization (type) == G_TYPE_UINT);
00977   {
00978     GArray *instance;
00979
00980     instance = dbus_g_type_specialized_construct (type);
00981
00982     g_assert (instance->len == 0);
00983
00984     g_array_free (instance,
group__DBusMacros.html#ga2
TRUE
);
00985   }
00986
00987   type = dbus_g_type_get_map (
"GHashTable"
, G_TYPE_STRING, G_TYPE_STRING);
00988   g_assert (dbus_g_type_is_map (type));
00989   g_assert (dbus_g_type_get_map_key_specialization (type) == G_TYPE_STRING);
00990   g_assert (dbus_g_type_get_map_value_specialization (type) == G_TYPE_STRING);
00991   {
00992     GHashTable *instance;
00993     GValue val = { 0, };
00994     TestSpecializedHashData hashdata;
00995
00996     instance = dbus_g_type_specialized_construct (type);
00997
00998     g_assert (g_hash_table_size (instance) == 0);
00999     g_hash_table_insert (instance, g_strdup (
"foo"
), g_strdup (
"bar"
));
01000     g_hash_table_insert (instance, g_strdup (
"baz"
), g_strdup (
"moo"
));
01001     g_assert (g_hash_table_size (instance) == 2);
01002
01003     g_value_init (&val, type);
01004     g_value_set_boxed_take_ownership (&val, instance);
01005     hashdata.seen_foo =
group__DBusMacros.html#ga3
FALSE
;
01006     hashdata.seen_baz =
group__DBusMacros.html#ga3
FALSE
;
01007     dbus_g_type_map_value_iterate (&val,
01008                                    test_specialized_hash,
01009                                    &hashdata);
01010
01011     g_assert (hashdata.seen_foo);
01012     g_assert (hashdata.seen_baz);
01013
01014     g_value_unset (&val);
01015   }
01016
01017   type = dbus_g_type_get_map (
"GHashTable"
, G_TYPE_STRING, G_TYPE_VALUE);
01018   g_assert (dbus_g_type_is_map (type));
01019   g_assert (dbus_g_type_get_map_key_specialization (type) == G_TYPE_STRING);
01020   g_assert (dbus_g_type_get_map_value_specialization (type) == G_TYPE_VALUE);
01021   {
01022     GHashTable *instance;
01023     GValue val = { 0, };
01024     TestSpecializedHashData hashdata;
01025
structDBusGTypeSpecializedAppendContext.html
DBusGTypeSpecializedAppendContext
ctx;
01026     GValue *eltval;
01027
01028     instance = dbus_g_type_specialized_construct (type);
01029     g_value_init (&val, type);
01030     g_value_set_boxed_take_ownership (&val, instance);
01031
01032     dbus_g_type_specialized_init_append (&val, &ctx);
01033
01034     {
01035       GValue keyval = { 0, };
01036       GValue valval = { 0, };
01037       g_value_init (&keyval, G_TYPE_STRING);
01038       g_value_set_string (&keyval,
"foo"
);
01039
01040       g_value_init (&valval, G_TYPE_VALUE);
01041       eltval = g_new0 (GValue, 1);
01042       g_value_init (eltval, G_TYPE_UINT);
01043       g_value_set_uint (eltval, 20);
01044       g_value_set_boxed_take_ownership (&valval, eltval);
01045       dbus_g_type_specialized_map_append (&ctx, &keyval, &valval);
01046     }
01047
01048     {
01049       GValue keyval = { 0, };
01050       GValue valval = { 0, };
01051       g_value_init (&keyval, G_TYPE_STRING);
01052       g_value_set_string (&keyval,
"baz"
);
01053       g_value_init (&valval, G_TYPE_VALUE);
01054       eltval = g_new0 (GValue, 1);
01055       g_value_init (eltval, G_TYPE_STRING);
01056       g_value_set_string (eltval,
"bar"
);
01057       g_value_set_boxed_take_ownership (&valval, eltval);
01058       dbus_g_type_specialized_map_append (&ctx, &keyval, &valval);
01059     }
01060
01061     hashdata.seen_foo =
group__DBusMacros.html#ga3
FALSE
;
01062     hashdata.seen_baz =
group__DBusMacros.html#ga3
FALSE
;
01063     dbus_g_type_map_value_iterate (&val,
01064                                    test_specialized_hash_2,
01065                                    &hashdata);
01066
01067     g_assert (hashdata.seen_foo);
01068     g_assert (hashdata.seen_baz);
01069
01070     g_value_unset (&val);
01071   }
01072
01073   type = dbus_g_type_get_collection (
"GPtrArray"
, G_TYPE_STRING);
01074   g_assert (dbus_g_type_is_collection (type));
01075   g_assert (dbus_g_type_get_collection_specialization (type) == G_TYPE_STRING);
01076   {
01077     GPtrArray *instance;
01078
structDBusGTypeSpecializedAppendContext.html
DBusGTypeSpecializedAppendContext
ctx;
01079     GValue val = {0, };
01080     GValue eltval = {0, };
01081
01082     instance = dbus_g_type_specialized_construct (type);
01083
01084     g_assert (instance->len == 0);
01085
01086     g_value_init (&val, type);
01087     g_value_set_boxed_take_ownership (&val, instance);
01088
01089     dbus_g_type_specialized_init_append (&val, &ctx);
01090
01091     g_value_init (&eltval, G_TYPE_STRING);
01092     g_value_set_static_string (&eltval,
"foo"
);
01093     dbus_g_type_specialized_collection_append (&ctx, &eltval);
01094
01095     g_value_reset (&eltval);
01096     g_value_set_static_string (&eltval,
"bar"
);
01097     dbus_g_type_specialized_collection_append (&ctx, &eltval);
01098
01099     g_value_reset (&eltval);
01100     g_value_set_static_string (&eltval,
"baz"
);
01101     dbus_g_type_specialized_collection_append (&ctx, &eltval);
01102
01103     dbus_g_type_specialized_collection_end_append (&ctx);
01104
01105     g_assert (instance->len == 3);
01106
01107     g_assert (!strcmp (
"foo"
, g_ptr_array_index (instance, 0)));
01108     g_assert (!strcmp (
"bar"
, g_ptr_array_index (instance, 1)));
01109     g_assert (!strcmp (
"baz"
, g_ptr_array_index (instance, 2)));
01110
01111     g_value_unset (&val);
01112   }
01113
01114
return
group__DBusMacros.html#ga2
TRUE
;
01115 }
01116
01117
01118
01119
#endif
/* DBUS_BUILD_TESTS */
Generated on Tue Sep 13 01:28:06 2005 for D-BUS by
http://www.doxygen.org/index.html
doxygen
1.4.4
