dbus-gtype-specialized.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-gtype-specialized.c: Non-DBus-specific functions for specialized GTypes
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 "dbus-gtype-specialized.h"
00025 #include <glib.h>
00026 #include <string.h>
00027 #include <gobject/gvaluecollector.h>
00028 
00037 typedef enum {
00038   DBUS_G_SPECTYPE_COLLECTION,
00039   DBUS_G_SPECTYPE_MAP,
00040   DBUS_G_SPECTYPE_STRUCT
00041 } DBusGTypeSpecializedType;
00042 
00043 typedef struct {
00044   DBusGTypeSpecializedType type;
00045   const DBusGTypeSpecializedVtable     *vtable;
00046 } DBusGTypeSpecializedContainer;
00047 
00048 typedef struct {
00049   guint num_types;
00050   GType *types;
00051   const DBusGTypeSpecializedContainer     *klass;
00052 } DBusGTypeSpecializedData;
00053 
00054 static GHashTable /* char * -> data* */ *specialized_containers;
00055 
00056 static GQuark
00057 specialized_type_data_quark ()
00058 {
00059   static GQuark quark;
00060   if (!quark)
00061     quark = g_quark_from_static_string ("DBusGTypeSpecializedData");
00062   
00063   return quark;
00064 }
00065 
00066 void
00067 dbus_g_type_specialized_init (void)
00068 {
00069   specialized_containers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
00070 }
00071 
00072 static gboolean
00073 specialized_types_is_initialized (void)
00074 {
00075   return specialized_containers != NULL;
00076 }
00077 
00078 static DBusGTypeSpecializedData *
00079 lookup_specialization_data (GType type)
00080 {
00081   return g_type_get_qdata (type, specialized_type_data_quark ());
00082 }
00083 
00084 
00085 /* Copied from gboxed.c */
00086 static void
00087 proxy_value_init (GValue *value)
00088 {
00089   value->data[0].v_pointer = NULL;
00090 }
00091 
00092 /* Adapted from gboxed.c */
00093 static void
00094 proxy_value_free (GValue *value)
00095 {
00096   if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
00097     {
00098       DBusGTypeSpecializedData *data;
00099       GType type;
00100 
00101       type = G_VALUE_TYPE (value);
00102       data = lookup_specialization_data (type);
00103       g_assert (data != NULL);
00104 
00105       if (data->klass->vtable->free_func)
00106         {
00107           data->klass->vtable->free_func (type, value->data[0].v_pointer);
00108         }
00109       else
00110         {
00111           g_assert (data->klass->vtable->simple_free_func != NULL);
00112           data->klass->vtable->simple_free_func (value->data[0].v_pointer);
00113         }
00114     }
00115 }
00116 
00117 /* Adapted from gboxed.c */
00118 static void
00119 proxy_value_copy (const GValue *src_value,
00120                   GValue       *dest_value)
00121 {
00122   if (src_value->data[0].v_pointer)
00123     {
00124       DBusGTypeSpecializedData *data;
00125       GType type;
00126       type = G_VALUE_TYPE (src_value);
00127       data = lookup_specialization_data (type);
00128       g_assert (data != NULL);
00129       dest_value->data[0].v_pointer = data->klass->vtable->copy_func (type, src_value->data[0].v_pointer);
00130     }
00131   else
00132     dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
00133 }
00134 
00135 /* Copied from gboxed.c */
00136 static gpointer
00137 proxy_value_peek_pointer (const GValue *value)
00138 {
00139   return value->data[0].v_pointer;
00140 }
00141 
00142 /* Adapted from gboxed.c */
00143 static gchar*
00144 proxy_collect_value (GValue      *value,
00145                      guint        n_collect_values,
00146                      GTypeCValue *collect_values,
00147                      guint        collect_flags)
00148 {
00149   DBusGTypeSpecializedData *data;
00150   GType type;
00151 
00152   type = G_VALUE_TYPE (value);
00153   data = lookup_specialization_data (type);
00154 
00155   if (!collect_values[0].v_pointer)
00156     value->data[0].v_pointer = NULL;
00157   else
00158     {
00159       if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
00160         {
00161           value->data[0].v_pointer = collect_values[0].v_pointer;
00162           value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
00163         }
00164       else
00165         {
00166           value->data[0].v_pointer = data->klass->vtable->copy_func (type, collect_values[0].v_pointer);
00167         }
00168     }
00169 
00170   return NULL;
00171 }
00172 
00173 /* Adapted from gboxed.c */
00174 static gchar*
00175 proxy_lcopy_value (const GValue *value,
00176                    guint         n_collect_values,
00177                    GTypeCValue  *collect_values,
00178                    guint         collect_flags)
00179 {
00180   gpointer *boxed_p = collect_values[0].v_pointer;
00181 
00182   if (!boxed_p)
00183     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
00184 
00185   if (!value->data[0].v_pointer)
00186     *boxed_p = NULL;
00187   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
00188     *boxed_p = value->data[0].v_pointer;
00189   else
00190     {
00191       DBusGTypeSpecializedData *data;
00192       GType type;
00193 
00194       type = G_VALUE_TYPE (value);
00195       data = lookup_specialization_data (type);
00196 
00197       *boxed_p = data->klass->vtable->copy_func (type, value->data[0].v_pointer);
00198     }
00199 
00200   return NULL;
00201 }
00202 
00203 static char *
00204 build_specialization_name (const char *prefix, guint num_types, GType *types)
00205 {
00206   GString *fullname;
00207   guint i;
00208 
00209   fullname = g_string_new (prefix);
00210 
00211   g_string_append_c (fullname, '_');
00212   for (i=0; i < num_types; i++)
00213     {
00214       if (i!=0)
00215         g_string_append_c (fullname, '+');
00216       g_string_append (fullname, g_type_name (types[i]));
00217     }
00218   g_string_append_c (fullname, '_');
00219   return g_string_free (fullname, FALSE);
00220 }
00221 
00222 static void
00223 register_container (const char                         *name,
00224                     DBusGTypeSpecializedType            type,
00225                     const DBusGTypeSpecializedVtable   *vtable)
00226 {
00227   DBusGTypeSpecializedContainer *klass;
00228   
00229   klass = g_new0 (DBusGTypeSpecializedContainer, 1);
00230   klass->type = type;
00231   klass->vtable = vtable;
00232 
00233   g_hash_table_insert (specialized_containers, g_strdup (name), klass);
00234 }
00235 
00236 void
00237 dbus_g_type_register_collection (const char                                   *name,
00238                                  const DBusGTypeSpecializedCollectionVtable   *vtable,
00239                                  guint                                         flags)
00240 {
00241   g_return_if_fail (specialized_types_is_initialized ());
00242   register_container (name, DBUS_G_SPECTYPE_COLLECTION, (const DBusGTypeSpecializedVtable*) vtable);
00243 }
00244 
00245 void
00246 dbus_g_type_register_map (const char                            *name,
00247                           const DBusGTypeSpecializedMapVtable   *vtable,
00248                           guint                                  flags)
00249 {
00250   g_return_if_fail (specialized_types_is_initialized ());
00251   register_container (name, DBUS_G_SPECTYPE_MAP, (const DBusGTypeSpecializedVtable*) vtable);
00252 }
00253 
00254 void
00255 dbus_g_type_register_struct (const char                             *name,
00256                              const DBusGTypeSpecializedStructVtable *vtable,
00257                              guint                                   flags)
00258 {
00259   g_return_if_fail (specialized_types_is_initialized ());
00260   register_container (name, DBUS_G_SPECTYPE_STRUCT, (const DBusGTypeSpecializedVtable*) vtable);
00261 }
00262 
00263 
00264 const DBusGTypeSpecializedMapVtable* dbus_g_type_map_peek_vtable (GType map_type)
00265 {
00266   DBusGTypeSpecializedData *data;
00267   g_return_val_if_fail (dbus_g_type_is_map(map_type), NULL);
00268 
00269   data = lookup_specialization_data (map_type);
00270   g_assert (data != NULL);
00271 
00272   return (DBusGTypeSpecializedMapVtable *)(data->klass->vtable);
00273 }
00274 
00275 const DBusGTypeSpecializedCollectionVtable* dbus_g_type_collection_peek_vtable (GType collection_type)
00276 {
00277   DBusGTypeSpecializedData *data;
00278   g_return_val_if_fail (dbus_g_type_is_collection(collection_type), NULL);
00279 
00280   data = lookup_specialization_data (collection_type);
00281   g_assert (data != NULL);
00282 
00283   return (DBusGTypeSpecializedCollectionVtable *)(data->klass->vtable);
00284 }
00285 
00286 const DBusGTypeSpecializedStructVtable* dbus_g_type_struct_peek_vtable (GType struct_type)
00287 {
00288   DBusGTypeSpecializedData *data;
00289   g_return_val_if_fail (dbus_g_type_is_struct (struct_type), NULL);
00290 
00291   data = lookup_specialization_data (struct_type);
00292   g_assert (data != NULL);
00293 
00294   return (DBusGTypeSpecializedStructVtable *)(data->klass->vtable);
00295 }
00296 
00297 static GType
00298 register_specialized_instance (const DBusGTypeSpecializedContainer   *klass,
00299                                char                                  *name,
00300                                guint                                  num_types,
00301                                GType                                 *types)
00302 {
00303   GType ret;
00304   
00305   static const GTypeValueTable vtable =
00306     {
00307       proxy_value_init,
00308       proxy_value_free,
00309       proxy_value_copy,
00310       proxy_value_peek_pointer,
00311       "p",
00312       proxy_collect_value,
00313       "p",
00314       proxy_lcopy_value,
00315     };
00316   static const GTypeInfo derived_info =
00317     {
00318       0,                /* class_size */
00319       NULL,             /* base_init */
00320       NULL,             /* base_finalize */
00321       NULL,             /* class_init */
00322       NULL,             /* class_finalize */
00323       NULL,             /* class_data */
00324       0,                /* instance_size */
00325       0,                /* n_preallocs */
00326       NULL,             /* instance_init */
00327       &vtable,          /* value_table */
00328     };
00329 
00330   ret = g_type_register_static (G_TYPE_BOXED, name, &derived_info, 0);
00331   /* install proxy functions upon successfull registration */
00332   if (ret != G_TYPE_INVALID)
00333     {
00334       DBusGTypeSpecializedData *data;
00335       data = g_new0 (DBusGTypeSpecializedData, 1);
00336       data->num_types = num_types;
00337       data->types = g_memdup (types, sizeof (GType) * num_types);
00338       data->klass = klass;
00339       g_type_set_qdata (ret, specialized_type_data_quark (), data);
00340     }
00341 
00342   return ret;
00343 }
00344 
00345 static GType
00346 lookup_or_register_specialized (const char  *container,
00347                                 guint        num_types,
00348                                 GType       *types)
00349 {
00350   GType ret;
00351   char *name;
00352   const DBusGTypeSpecializedContainer *klass;
00353 
00354   g_return_val_if_fail (specialized_types_is_initialized (), G_TYPE_INVALID);
00355 
00356   klass = g_hash_table_lookup (specialized_containers, container);
00357   g_return_val_if_fail (klass != NULL, G_TYPE_INVALID);
00358 
00359   name = build_specialization_name (container, num_types, types);
00360   ret = g_type_from_name (name);
00361   if (ret == G_TYPE_INVALID)
00362     {
00363       /* Take ownership of name */
00364       ret = register_specialized_instance (klass, name,
00365                                            num_types,
00366                                            types);
00367     }
00368   g_free (name);
00369   return ret;
00370 }
00371 
00372 GType
00373 dbus_g_type_get_collection (const char *container,
00374                             GType       specialization)
00375 {
00376   return lookup_or_register_specialized (container, 1, &specialization);
00377 }
00378 
00379 GType
00380 dbus_g_type_get_map (const char   *container,
00381                      GType         key_specialization,
00382                      GType         value_specialization)
00383 {
00384   GType types[2] = {key_specialization, value_specialization};
00385   return lookup_or_register_specialized (container, 2, types);
00386 }
00387 
00388 GType
00389 dbus_g_type_get_structv (const char   *container,
00390                         guint         num_items,
00391                         GType        *types)
00392 {
00393   return lookup_or_register_specialized (container, num_items, types);
00394 }
00395 
00396 GType
00397 dbus_g_type_get_struct (const char *container,
00398                         GType first_type,
00399                         ...)
00400 {
00401   GArray *types;
00402   GType curtype, ret;
00403   va_list args;
00404   va_start (args, first_type);
00405 
00406   types = g_array_new (FALSE, FALSE, sizeof (GType));
00407   curtype = first_type;
00408   while (curtype != G_TYPE_INVALID)
00409     {
00410       g_array_append_val (types, curtype);
00411       curtype = va_arg (args, GType);
00412     }
00413   va_end (args);
00414 
00415   ret = lookup_or_register_specialized (container, types->len,
00416       (GType *) types->data);
00417 
00418   g_array_free (types, TRUE);
00419 
00420   return ret;
00421 }
00422 
00423 
00424 
00425 gboolean
00426 dbus_g_type_is_collection (GType gtype)
00427 {
00428   DBusGTypeSpecializedData *data;
00429   data = lookup_specialization_data (gtype);
00430   if (data == NULL)
00431     return FALSE;
00432   return data->klass->type == DBUS_G_SPECTYPE_COLLECTION;
00433 }
00434 
00435 gboolean
00436 dbus_g_type_is_map (GType gtype)
00437 {
00438   DBusGTypeSpecializedData *data;
00439   data = lookup_specialization_data (gtype);
00440   if (data == NULL)
00441     return FALSE;
00442   return data->klass->type == DBUS_G_SPECTYPE_MAP;
00443 }
00444 
00445 gboolean
00446 dbus_g_type_is_struct (GType gtype)
00447 {
00448   DBusGTypeSpecializedData *data;
00449   data = lookup_specialization_data (gtype);
00450   if (data == NULL)
00451     return FALSE;
00452   return data->klass->type == DBUS_G_SPECTYPE_STRUCT;
00453 }
00454 
00455 
00456 static GType
00457 get_specialization_index (GType gtype, guint i)
00458 {
00459   DBusGTypeSpecializedData *data;
00460 
00461   data = lookup_specialization_data (gtype);
00462   if (i < data->num_types)
00463     return data->types[i];
00464   else
00465     return G_TYPE_INVALID;
00466 }
00467 
00468 GType
00469 dbus_g_type_get_collection_specialization (GType gtype)
00470 {
00471   g_return_val_if_fail (dbus_g_type_is_collection (gtype), G_TYPE_INVALID);
00472   return get_specialization_index (gtype, 0);
00473 }
00474 
00475 GType
00476 dbus_g_type_get_map_key_specialization (GType gtype)
00477 {
00478   g_return_val_if_fail (dbus_g_type_is_map (gtype), G_TYPE_INVALID);
00479   return get_specialization_index (gtype, 0);
00480 }
00481 
00482 GType
00483 dbus_g_type_get_map_value_specialization (GType gtype)
00484 {
00485   g_return_val_if_fail (dbus_g_type_is_map (gtype), G_TYPE_INVALID);
00486   return get_specialization_index (gtype, 1);
00487 }
00488 
00489 GType
00490 dbus_g_type_get_struct_member_type (GType gtype, guint index_)
00491 {
00492   g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID);
00493   return get_specialization_index (gtype, index_);
00494 }
00495 
00496 guint
00497 dbus_g_type_get_struct_size (GType gtype)
00498 {
00499   DBusGTypeSpecializedData *data;
00500   g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID);
00501 
00502   data = lookup_specialization_data (gtype);
00503   return data->num_types;
00504 }
00505 
00506 
00507 
00508 gpointer
00509 dbus_g_type_specialized_construct (GType type)
00510 {
00511   DBusGTypeSpecializedData *data;
00512   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00513 
00514   data = lookup_specialization_data (type);
00515   g_return_val_if_fail (data != NULL, FALSE);
00516 
00517   return data->klass->vtable->constructor (type);
00518 }
00519 
00520 gboolean
00521 dbus_g_type_collection_get_fixed (GValue   *value,
00522                                   gpointer *data_ret,
00523                                   guint    *len_ret)
00524 {
00525   DBusGTypeSpecializedData *data;
00526   GType gtype;
00527 
00528   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00529   g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
00530 
00531   gtype = G_VALUE_TYPE (value);
00532   data = lookup_specialization_data (gtype);
00533   g_return_val_if_fail (data != NULL, FALSE);
00534 
00535   return ((DBusGTypeSpecializedCollectionVtable *) (data->klass->vtable))->fixed_accessor (gtype,
00536                                                                                            g_value_get_boxed (value),
00537                                                                                            data_ret, len_ret);
00538 }
00539 
00540 void
00541 dbus_g_type_collection_value_iterate (const GValue                           *value,
00542                                       DBusGTypeSpecializedCollectionIterator  iterator,
00543                                       gpointer                                user_data)
00544 {
00545   DBusGTypeSpecializedData *data;
00546   GType gtype;
00547 
00548   g_return_if_fail (specialized_types_is_initialized ());
00549   g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
00550 
00551   gtype = G_VALUE_TYPE (value);
00552   data = lookup_specialization_data (gtype);
00553   g_return_if_fail (data != NULL);
00554 
00555   ((DBusGTypeSpecializedCollectionVtable *) data->klass->vtable)->iterator (gtype,
00556                                                                             g_value_get_boxed (value),
00557                                                                             iterator, user_data);
00558 }
00559 
00560 typedef struct {
00561   GValue *val;
00562   GType specialization_type;
00563   DBusGTypeSpecializedData *specdata;
00564 } DBusGTypeSpecializedAppendContextReal;
00565 
00566 void
00567 dbus_g_type_specialized_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx)
00568 {
00569   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00570   GType gtype;
00571   DBusGTypeSpecializedData *specdata;
00572   
00573   g_return_if_fail (specialized_types_is_initialized ());
00574   g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
00575   gtype = G_VALUE_TYPE (value);
00576   specdata = lookup_specialization_data (gtype);
00577   g_return_if_fail (specdata != NULL);
00578   g_return_if_fail (specdata->num_types != 0);
00579 
00580   realctx->val = value;
00581   realctx->specialization_type = specdata->types[0];
00582   realctx->specdata = specdata;
00583 }
00584 
00585 void
00586 dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx,
00587                                            GValue                            *elt)
00588 {
00589   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00590   ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->append_func (ctx, elt);
00591 }
00592 
00593 void
00594 dbus_g_type_specialized_collection_end_append (DBusGTypeSpecializedAppendContext *ctx)
00595 {
00596   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00597   if (((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func != NULL)
00598     ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func (ctx);
00599 }
00600 
00601 void
00602 dbus_g_type_specialized_map_append (DBusGTypeSpecializedAppendContext *ctx,
00603                                     GValue                            *key,
00604                                     GValue                            *val)
00605 {
00606   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00607   ((DBusGTypeSpecializedMapVtable *) realctx->specdata->klass->vtable)->append_func (ctx, key, val);
00608 }
00609 
00610 void
00611 dbus_g_type_map_value_iterate (const GValue                           *value,
00612                                DBusGTypeSpecializedMapIterator         iterator,
00613                                gpointer                                user_data)
00614 {
00615   DBusGTypeSpecializedData *data;
00616   GType gtype;
00617 
00618   g_return_if_fail (specialized_types_is_initialized ());
00619   g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
00620 
00621   gtype = G_VALUE_TYPE (value);
00622   data = lookup_specialization_data (gtype);
00623   g_return_if_fail (data != NULL);
00624 
00625   ((DBusGTypeSpecializedMapVtable *) data->klass->vtable)->iterator (gtype,
00626                                                                      g_value_get_boxed (value),
00627                                                                      iterator, user_data);
00628 }
00629 
00630 gboolean
00631 dbus_g_type_struct_get_member (const GValue *value,
00632                                guint         index_,
00633                                GValue       *dest)
00634 {
00635   DBusGTypeSpecializedData *data;
00636   GType gtype;
00637 
00638   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00639   g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
00640 
00641   gtype = G_VALUE_TYPE (value);
00642   data = lookup_specialization_data (gtype);
00643   g_return_val_if_fail (data != NULL, FALSE);
00644 
00645   return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->get_member(gtype,
00646                                                                                            g_value_get_boxed (value),
00647                                                                                            index_, dest);
00648 }
00649 
00650 gboolean
00651 dbus_g_type_struct_set_member (GValue       *value,
00652                                guint         index_,
00653                                const GValue *src)
00654 {
00655   DBusGTypeSpecializedData *data;
00656   GType gtype;
00657 
00658   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00659   g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
00660 
00661   gtype = G_VALUE_TYPE (value);
00662   data = lookup_specialization_data (gtype);
00663   g_return_val_if_fail (data != NULL, FALSE);
00664 
00665   return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->set_member(gtype,
00666                                                                                            g_value_get_boxed (value),
00667                                                                                            index_, src);
00668 }
00669 
00684 gboolean
00685 dbus_g_type_struct_get                   (const GValue *value,
00686                                           guint first_member,
00687                                           ...)
00688 {
00689   va_list var_args;
00690   GType type;
00691   guint size,i;
00692   gchar *error;
00693   GValue val = {0,};
00694 
00695   g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE);
00696 
00697   va_start (var_args, first_member);
00698   size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
00699   i = first_member;
00700   while (i != G_MAXUINT)
00701     {
00702       if (i >= size)
00703         goto error;
00704 
00705       type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i);
00706 
00707       g_value_init (&val, type);
00708       dbus_g_type_struct_get_member (value, i, &val);
00709 
00710       G_VALUE_LCOPY (&val, var_args, 0, &error);
00711       if (error)
00712         {
00713           g_warning ("%s, %s", G_STRFUNC, error);
00714           g_free (error);
00715           g_value_unset (&val);
00716           goto error;
00717         }
00718       g_value_unset (&val);
00719       i = va_arg (var_args, guint);
00720     }
00721   va_end (var_args);
00722   return TRUE;
00723 error:
00724   va_end (var_args);
00725   return FALSE;
00726 }
00727 
00740 gboolean
00741 dbus_g_type_struct_set                   (GValue *value,
00742                                           guint first_member,
00743                                           ...)
00744 {
00745   va_list var_args;
00746   GType type;
00747   guint size,i;
00748   gchar *error;
00749   GValue val = {0,};
00750 
00751   g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE);
00752 
00753   va_start (var_args, first_member);
00754   size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
00755   i = first_member;
00756   while (i != G_MAXUINT)
00757     {
00758       if (i >= size)
00759         goto error;
00760 
00761       type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i);
00762 
00763       g_value_init (&val, type);
00764 
00765       G_VALUE_COLLECT (&val, var_args, 0, &error);
00766       if (error)
00767         {
00768           g_warning ("%s, %s", G_STRFUNC, error);
00769           g_free (error);
00770           g_value_unset (&val);
00771           goto error;
00772         }
00773 
00774       dbus_g_type_struct_set_member (value, i, &val);
00775 
00776       g_value_unset (&val);
00777       i = va_arg (var_args, guint);
00778     }
00779   va_end (var_args);
00780   return TRUE;
00781 error:
00782   va_end (var_args);
00783   return FALSE;
00784 }
00785 

Generated on Wed Apr 4 14:26:38 2007 for D-BUSGLibBindings by  doxygen 1.4.6