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  * Copyright (C) 2007 Codethink Ltd.
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 
00025 #include "dbus-gtype-specialized.h"
00026 #include <glib.h>
00027 #include <string.h>
00028 #include <gobject/gvaluecollector.h>
00029 
00060 typedef enum {
00061   DBUS_G_SPECTYPE_COLLECTION,
00062   DBUS_G_SPECTYPE_MAP,
00063   DBUS_G_SPECTYPE_STRUCT
00064 } DBusGTypeSpecializedType;
00065 
00066 typedef struct {
00067   DBusGTypeSpecializedType type;
00068   const DBusGTypeSpecializedVtable     *vtable;
00069 } DBusGTypeSpecializedContainer;
00070 
00071 typedef struct {
00072   guint num_types;
00073   GType *types;
00074   const DBusGTypeSpecializedContainer     *klass;
00075 } DBusGTypeSpecializedData;
00076 
00077 static GHashTable /* char * -> data* */ *specialized_containers;
00078 
00079 static GQuark
00080 specialized_type_data_quark ()
00081 {
00082   static GQuark quark;
00083   if (!quark)
00084     quark = g_quark_from_static_string ("DBusGTypeSpecializedData");
00085   
00086   return quark;
00087 }
00088 
00089 void
00090 dbus_g_type_specialized_init (void)
00091 {
00092   specialized_containers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
00093 }
00094 
00095 static gboolean
00096 specialized_types_is_initialized (void)
00097 {
00098   return specialized_containers != NULL;
00099 }
00100 
00101 static DBusGTypeSpecializedData *
00102 lookup_specialization_data (GType type)
00103 {
00104   return g_type_get_qdata (type, specialized_type_data_quark ());
00105 }
00106 
00107 
00108 /* Copied from gboxed.c */
00109 static void
00110 proxy_value_init (GValue *value)
00111 {
00112   value->data[0].v_pointer = NULL;
00113 }
00114 
00115 /* Adapted from gboxed.c */
00116 static void
00117 proxy_value_free (GValue *value)
00118 {
00119   if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
00120     {
00121       DBusGTypeSpecializedData *data;
00122       GType type;
00123 
00124       type = G_VALUE_TYPE (value);
00125       data = lookup_specialization_data (type);
00126       g_assert (data != NULL);
00127 
00128       if (data->klass->vtable->free_func)
00129         {
00130           data->klass->vtable->free_func (type, value->data[0].v_pointer);
00131         }
00132       else
00133         {
00134           g_assert (data->klass->vtable->simple_free_func != NULL);
00135           data->klass->vtable->simple_free_func (value->data[0].v_pointer);
00136         }
00137     }
00138 }
00139 
00140 /* Adapted from gboxed.c */
00141 static void
00142 proxy_value_copy (const GValue *src_value,
00143                   GValue       *dest_value)
00144 {
00145   if (src_value->data[0].v_pointer)
00146     {
00147       DBusGTypeSpecializedData *data;
00148       GType type;
00149       type = G_VALUE_TYPE (src_value);
00150       data = lookup_specialization_data (type);
00151       g_assert (data != NULL);
00152       dest_value->data[0].v_pointer = data->klass->vtable->copy_func (type, src_value->data[0].v_pointer);
00153     }
00154   else
00155     dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
00156 }
00157 
00158 /* Copied from gboxed.c */
00159 static gpointer
00160 proxy_value_peek_pointer (const GValue *value)
00161 {
00162   return value->data[0].v_pointer;
00163 }
00164 
00165 /* Adapted from gboxed.c */
00166 static gchar*
00167 proxy_collect_value (GValue      *value,
00168                      guint        n_collect_values,
00169                      GTypeCValue *collect_values,
00170                      guint        collect_flags)
00171 {
00172   DBusGTypeSpecializedData *data;
00173   GType type;
00174 
00175   type = G_VALUE_TYPE (value);
00176   data = lookup_specialization_data (type);
00177 
00178   if (!collect_values[0].v_pointer)
00179     value->data[0].v_pointer = NULL;
00180   else
00181     {
00182       if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
00183         {
00184           value->data[0].v_pointer = collect_values[0].v_pointer;
00185           value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
00186         }
00187       else
00188         {
00189           value->data[0].v_pointer = data->klass->vtable->copy_func (type, collect_values[0].v_pointer);
00190         }
00191     }
00192 
00193   return NULL;
00194 }
00195 
00196 /* Adapted from gboxed.c */
00197 static gchar*
00198 proxy_lcopy_value (const GValue *value,
00199                    guint         n_collect_values,
00200                    GTypeCValue  *collect_values,
00201                    guint         collect_flags)
00202 {
00203   gpointer *boxed_p = collect_values[0].v_pointer;
00204 
00205   if (!boxed_p)
00206     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
00207 
00208   if (!value->data[0].v_pointer)
00209     *boxed_p = NULL;
00210   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
00211     *boxed_p = value->data[0].v_pointer;
00212   else
00213     {
00214       DBusGTypeSpecializedData *data;
00215       GType type;
00216 
00217       type = G_VALUE_TYPE (value);
00218       data = lookup_specialization_data (type);
00219 
00220       *boxed_p = data->klass->vtable->copy_func (type, value->data[0].v_pointer);
00221     }
00222 
00223   return NULL;
00224 }
00225 
00226 static char *
00227 build_specialization_name (const char *prefix, guint num_types, const GType *types)
00228 {
00229   GString *fullname;
00230   guint i;
00231 
00232   fullname = g_string_new (prefix);
00233 
00234   g_string_append_c (fullname, '_');
00235   for (i=0; i < num_types; i++)
00236     {
00237       if (i!=0)
00238         g_string_append_c (fullname, '+');
00239       g_string_append (fullname, g_type_name (types[i]));
00240     }
00241   g_string_append_c (fullname, '_');
00242   return g_string_free (fullname, FALSE);
00243 }
00244 
00245 static void
00246 register_container (const char                         *name,
00247                     DBusGTypeSpecializedType            type,
00248                     const DBusGTypeSpecializedVtable   *vtable)
00249 {
00250   DBusGTypeSpecializedContainer *klass;
00251   
00252   klass = g_new0 (DBusGTypeSpecializedContainer, 1);
00253   klass->type = type;
00254   klass->vtable = vtable;
00255 
00256   g_hash_table_insert (specialized_containers, g_strdup (name), klass);
00257 }
00258 
00267 void
00268 dbus_g_type_register_collection (const char                                   *name,
00269                                  const DBusGTypeSpecializedCollectionVtable   *vtable,
00270                                  guint                                         flags)
00271 {
00272   g_return_if_fail (specialized_types_is_initialized ());
00273   register_container (name, DBUS_G_SPECTYPE_COLLECTION, (const DBusGTypeSpecializedVtable*) vtable);
00274 }
00275 
00284 void
00285 dbus_g_type_register_map (const char                            *name,
00286                           const DBusGTypeSpecializedMapVtable   *vtable,
00287                           guint                                  flags)
00288 {
00289   g_return_if_fail (specialized_types_is_initialized ());
00290   register_container (name, DBUS_G_SPECTYPE_MAP, (const DBusGTypeSpecializedVtable*) vtable);
00291 }
00292 
00301 void
00302 dbus_g_type_register_struct (const char                             *name,
00303                              const DBusGTypeSpecializedStructVtable *vtable,
00304                              guint                                   flags)
00305 {
00306   g_return_if_fail (specialized_types_is_initialized ());
00307   register_container (name, DBUS_G_SPECTYPE_STRUCT, (const DBusGTypeSpecializedVtable*) vtable);
00308 }
00309 
00316 const DBusGTypeSpecializedMapVtable* dbus_g_type_map_peek_vtable (GType map_type)
00317 {
00318   DBusGTypeSpecializedData *data;
00319   g_return_val_if_fail (dbus_g_type_is_map(map_type), NULL);
00320 
00321   data = lookup_specialization_data (map_type);
00322   g_assert (data != NULL);
00323 
00324   return (DBusGTypeSpecializedMapVtable *)(data->klass->vtable);
00325 }
00326 
00333 const DBusGTypeSpecializedCollectionVtable* dbus_g_type_collection_peek_vtable (GType collection_type)
00334 {
00335   DBusGTypeSpecializedData *data;
00336   g_return_val_if_fail (dbus_g_type_is_collection(collection_type), NULL);
00337 
00338   data = lookup_specialization_data (collection_type);
00339   g_assert (data != NULL);
00340 
00341   return (DBusGTypeSpecializedCollectionVtable *)(data->klass->vtable);
00342 }
00343 
00350 const DBusGTypeSpecializedStructVtable* dbus_g_type_struct_peek_vtable (GType struct_type)
00351 {
00352   DBusGTypeSpecializedData *data;
00353   g_return_val_if_fail (dbus_g_type_is_struct (struct_type), NULL);
00354 
00355   data = lookup_specialization_data (struct_type);
00356   g_assert (data != NULL);
00357 
00358   return (DBusGTypeSpecializedStructVtable *)(data->klass->vtable);
00359 }
00360 
00361 static GType
00362 register_specialized_instance (const DBusGTypeSpecializedContainer   *klass,
00363                                const char                            *name,
00364                                guint                                  num_types,
00365                                const GType                           *types)
00366 {
00367   GType ret;
00368   
00369   static const GTypeValueTable vtable =
00370     {
00371       proxy_value_init,
00372       proxy_value_free,
00373       proxy_value_copy,
00374       proxy_value_peek_pointer,
00375       "p",
00376       proxy_collect_value,
00377       "p",
00378       proxy_lcopy_value,
00379     };
00380   static const GTypeInfo derived_info =
00381     {
00382       0,                /* class_size */
00383       NULL,             /* base_init */
00384       NULL,             /* base_finalize */
00385       NULL,             /* class_init */
00386       NULL,             /* class_finalize */
00387       NULL,             /* class_data */
00388       0,                /* instance_size */
00389       0,                /* n_preallocs */
00390       NULL,             /* instance_init */
00391       &vtable,          /* value_table */
00392     };
00393 
00394   ret = g_type_register_static (G_TYPE_BOXED, name, &derived_info, 0);
00395   /* install proxy functions upon successfull registration */
00396   if (ret != G_TYPE_INVALID)
00397     {
00398       DBusGTypeSpecializedData *data;
00399       data = g_new0 (DBusGTypeSpecializedData, 1);
00400       data->num_types = num_types;
00401       data->types = g_memdup (types, sizeof (GType) * num_types);
00402       data->klass = klass;
00403       g_type_set_qdata (ret, specialized_type_data_quark (), data);
00404     }
00405 
00406   return ret;
00407 }
00408 
00409 static GType
00410 lookup_or_register_specialized (const char  *container,
00411                                 guint        num_types,
00412                                 const GType *types)
00413 {
00414   GType ret;
00415   char *name;
00416   const DBusGTypeSpecializedContainer *klass;
00417 
00418   g_return_val_if_fail (specialized_types_is_initialized (), G_TYPE_INVALID);
00419 
00420   klass = g_hash_table_lookup (specialized_containers, container);
00421   g_return_val_if_fail (klass != NULL, G_TYPE_INVALID);
00422 
00423   name = build_specialization_name (container, num_types, types);
00424   ret = g_type_from_name (name);
00425   if (ret == G_TYPE_INVALID)
00426     {
00427       /* Take ownership of name */
00428       ret = register_specialized_instance (klass, name,
00429                                            num_types,
00430                                            types);
00431     }
00432   g_free (name);
00433   return ret;
00434 }
00435 
00436 
00447 GType
00448 dbus_g_type_get_collection (const char *container,
00449                             GType specialization)
00450 {
00451   return lookup_or_register_specialized (container, 1, &specialization);
00452 }
00453 
00465 GType
00466 dbus_g_type_get_map (const char   *container,
00467                      GType         key_specialization,
00468                      GType         value_specialization)
00469 {
00470   GType types[2] = {key_specialization, value_specialization};
00471   return lookup_or_register_specialized (container, 2, types);
00472 }
00473 
00485 GType
00486 dbus_g_type_get_structv (const char   *container,
00487                          guint         num_members,
00488                          GType        *types)
00489 {
00490   return lookup_or_register_specialized (container, num_members, types);
00491 }
00492 
00504 GType
00505 dbus_g_type_get_struct (const char *container,
00506                         GType first_type,
00507                         ...)
00508 {
00509   GArray *types;
00510   GType curtype, ret;
00511   va_list args;
00512   va_start (args, first_type);
00513 
00514   types = g_array_new (FALSE, FALSE, sizeof (GType));
00515   curtype = first_type;
00516   while (curtype != G_TYPE_INVALID)
00517     {
00518       g_array_append_val (types, curtype);
00519       curtype = va_arg (args, GType);
00520     }
00521   va_end (args);
00522 
00523   ret = lookup_or_register_specialized (container, types->len,
00524       (GType *) types->data);
00525 
00526   g_array_free (types, TRUE);
00527 
00528   return ret;
00529 }
00530 
00531 
00540 gboolean
00541 dbus_g_type_is_collection (GType gtype)
00542 {
00543   DBusGTypeSpecializedData *data;
00544   data = lookup_specialization_data (gtype);
00545   if (data == NULL)
00546     return FALSE;
00547   return data->klass->type == DBUS_G_SPECTYPE_COLLECTION;
00548 }
00549 
00559 gboolean
00560 dbus_g_type_is_map (GType gtype)
00561 {
00562   DBusGTypeSpecializedData *data;
00563   data = lookup_specialization_data (gtype);
00564   if (data == NULL)
00565     return FALSE;
00566   return data->klass->type == DBUS_G_SPECTYPE_MAP;
00567 }
00568 
00578 gboolean
00579 dbus_g_type_is_struct (GType gtype)
00580 {
00581   DBusGTypeSpecializedData *data;
00582   data = lookup_specialization_data (gtype);
00583   if (data == NULL)
00584     return FALSE;
00585   return data->klass->type == DBUS_G_SPECTYPE_STRUCT;
00586 }
00587 
00588 
00589 static GType
00590 get_specialization_index (GType gtype, guint i)
00591 {
00592   DBusGTypeSpecializedData *data;
00593 
00594   data = lookup_specialization_data (gtype);
00595   if (i < data->num_types)
00596     return data->types[i];
00597   else
00598     return G_TYPE_INVALID;
00599 }
00600 
00608 GType
00609 dbus_g_type_get_collection_specialization (GType gtype)
00610 {
00611   g_return_val_if_fail (dbus_g_type_is_collection (gtype), G_TYPE_INVALID);
00612   return get_specialization_index (gtype, 0);
00613 }
00614 
00622 GType
00623 dbus_g_type_get_map_key_specialization (GType gtype)
00624 {
00625   g_return_val_if_fail (dbus_g_type_is_map (gtype), G_TYPE_INVALID);
00626   return get_specialization_index (gtype, 0);
00627 }
00628 
00636 GType
00637 dbus_g_type_get_map_value_specialization (GType gtype)
00638 {
00639   g_return_val_if_fail (dbus_g_type_is_map (gtype), G_TYPE_INVALID);
00640   return get_specialization_index (gtype, 1);
00641 }
00642 
00651 GType
00652 dbus_g_type_get_struct_member_type (GType gtype, guint member)
00653 {
00654   g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID);
00655   return get_specialization_index (gtype, member);
00656 }
00657 
00665 guint
00666 dbus_g_type_get_struct_size (GType gtype)
00667 {
00668   DBusGTypeSpecializedData *data;
00669   g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID);
00670 
00671   data = lookup_specialization_data (gtype);
00672   return data->num_types;
00673 }
00674 
00687 gpointer
00688 dbus_g_type_specialized_construct (GType gtype)
00689 {
00690   DBusGTypeSpecializedData *data;
00691   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00692 
00693   data = lookup_specialization_data (gtype);
00694   g_return_val_if_fail (data != NULL, FALSE);
00695 
00696   return data->klass->vtable->constructor (gtype);
00697 }
00698 
00707 gboolean
00708 dbus_g_type_collection_get_fixed (GValue   *value,
00709                                   gpointer *data_ret,
00710                                   guint    *len_ret)
00711 {
00712   DBusGTypeSpecializedData *data;
00713   GType gtype;
00714 
00715   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00716   g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
00717 
00718   gtype = G_VALUE_TYPE (value);
00719   data = lookup_specialization_data (gtype);
00720   g_return_val_if_fail (data != NULL, FALSE);
00721 
00722   return ((DBusGTypeSpecializedCollectionVtable *) (data->klass->vtable))->fixed_accessor (gtype,
00723                                                                                            g_value_get_boxed (value),
00724                                                                                            data_ret, len_ret);
00725 }
00726 
00738 void
00739 dbus_g_type_collection_value_iterate (const GValue                           *value,
00740                                       DBusGTypeSpecializedCollectionIterator  iterator,
00741                                       gpointer                                user_data)
00742 {
00743   DBusGTypeSpecializedData *data;
00744   GType gtype;
00745 
00746   g_return_if_fail (specialized_types_is_initialized ());
00747   g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
00748 
00749   gtype = G_VALUE_TYPE (value);
00750   data = lookup_specialization_data (gtype);
00751   g_return_if_fail (data != NULL);
00752 
00753   ((DBusGTypeSpecializedCollectionVtable *) data->klass->vtable)->iterator (gtype,
00754                                                                             g_value_get_boxed (value),
00755                                                                             iterator, user_data);
00756 }
00757 
00758 typedef struct {
00759   GValue *val;
00760   GType specialization_type;
00761   DBusGTypeSpecializedData *specdata;
00762 } DBusGTypeSpecializedAppendContextReal;
00763 
00773 void
00774 dbus_g_type_specialized_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx)
00775 {
00776   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00777   GType gtype;
00778   DBusGTypeSpecializedData *specdata;
00779   
00780   g_return_if_fail (specialized_types_is_initialized ());
00781   g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
00782   gtype = G_VALUE_TYPE (value);
00783   specdata = lookup_specialization_data (gtype);
00784   g_return_if_fail (specdata != NULL);
00785   g_return_if_fail (specdata->num_types != 0);
00786 
00787   realctx->val = value;
00788   realctx->specialization_type = specdata->types[0];
00789   realctx->specdata = specdata;
00790 }
00791 
00800 void
00801 dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx,
00802                                            GValue                            *elt)
00803 {
00804   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00805   ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->append_func (ctx, elt);
00806 }
00807 
00815 void
00816 dbus_g_type_specialized_collection_end_append (DBusGTypeSpecializedAppendContext *ctx)
00817 {
00818   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00819   if (((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func != NULL)
00820     ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func (ctx);
00821 }
00822 
00832 void
00833 dbus_g_type_specialized_map_append (DBusGTypeSpecializedAppendContext *ctx,
00834                                     GValue                            *key,
00835                                     GValue                            *val)
00836 {
00837   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00838   ((DBusGTypeSpecializedMapVtable *) realctx->specdata->klass->vtable)->append_func (ctx, key, val);
00839 }
00840 
00841 
00853 void
00854 dbus_g_type_map_value_iterate (const GValue                           *value,
00855                                DBusGTypeSpecializedMapIterator         iterator,
00856                                gpointer                                user_data)
00857 {
00858   DBusGTypeSpecializedData *data;
00859   GType gtype;
00860 
00861   g_return_if_fail (specialized_types_is_initialized ());
00862   g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
00863 
00864   gtype = G_VALUE_TYPE (value);
00865   data = lookup_specialization_data (gtype);
00866   g_return_if_fail (data != NULL);
00867 
00868   ((DBusGTypeSpecializedMapVtable *) data->klass->vtable)->iterator (gtype,
00869                                                                      g_value_get_boxed (value),
00870                                                                      iterator, user_data);
00871 }
00872 
00885 gboolean
00886 dbus_g_type_struct_get_member (const GValue *value,
00887                                guint         member,
00888                                GValue       *dest)
00889 {
00890   DBusGTypeSpecializedData *data;
00891   GType gtype;
00892 
00893   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00894   g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
00895 
00896   gtype = G_VALUE_TYPE (value);
00897   data = lookup_specialization_data (gtype);
00898   g_return_val_if_fail (data != NULL, FALSE);
00899 
00900   return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->get_member(gtype,
00901                                                                                            g_value_get_boxed (value),
00902                                                                                            member, dest);
00903 }
00904 
00916 gboolean
00917 dbus_g_type_struct_set_member (GValue       *value,
00918                                guint         member,
00919                                const GValue *src)
00920 {
00921   DBusGTypeSpecializedData *data;
00922   GType gtype;
00923 
00924   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00925   g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
00926 
00927   gtype = G_VALUE_TYPE (value);
00928   data = lookup_specialization_data (gtype);
00929   g_return_val_if_fail (data != NULL, FALSE);
00930 
00931   return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->set_member(gtype,
00932                                                                                            g_value_get_boxed (value),
00933                                                                                            member, src);
00934 }
00935 
00950 gboolean
00951 dbus_g_type_struct_get                   (const GValue *value,
00952                                           guint first_member,
00953                                           ...)
00954 {
00955   va_list var_args;
00956   GType type;
00957   guint size,i;
00958   gchar *error;
00959   GValue val = {0,};
00960 
00961   g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE);
00962 
00963   va_start (var_args, first_member);
00964   size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
00965   i = first_member;
00966   while (i != G_MAXUINT)
00967     {
00968       if (i >= size)
00969         goto error;
00970 
00971       type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i);
00972 
00973       g_value_init (&val, type);
00974       dbus_g_type_struct_get_member (value, i, &val);
00975 
00976       G_VALUE_LCOPY (&val, var_args, 0, &error);
00977       if (error)
00978         {
00979           g_warning ("%s, %s", G_STRFUNC, error);
00980           g_free (error);
00981           g_value_unset (&val);
00982           goto error;
00983         }
00984       g_value_unset (&val);
00985       i = va_arg (var_args, guint);
00986     }
00987   va_end (var_args);
00988   return TRUE;
00989 error:
00990   va_end (var_args);
00991   return FALSE;
00992 }
00993 
01006 gboolean
01007 dbus_g_type_struct_set                   (GValue *value,
01008                                           guint first_member,
01009                                           ...)
01010 {
01011   va_list var_args;
01012   GType type;
01013   guint size,i;
01014   gchar *error;
01015   GValue val = {0,};
01016 
01017   g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE);
01018 
01019   va_start (var_args, first_member);
01020   size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
01021   i = first_member;
01022   while (i != G_MAXUINT)
01023     {
01024       if (i >= size)
01025         goto error;
01026 
01027       type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i);
01028 
01029       g_value_init (&val, type);
01030 
01031       G_VALUE_COLLECT (&val, var_args, 0, &error);
01032       if (error)
01033         {
01034           g_warning ("%s, %s", G_STRFUNC, error);
01035           g_free (error);
01036           g_value_unset (&val);
01037           goto error;
01038         }
01039 
01040       dbus_g_type_struct_set_member (value, i, &val);
01041 
01042       g_value_unset (&val);
01043       i = va_arg (var_args, guint);
01044     }
01045   va_end (var_args);
01046   return TRUE;
01047 error:
01048   va_end (var_args);
01049   return FALSE;
01050 }
01051 

Generated on Wed Oct 3 10:04:23 2007 for D-BUSGLibBindings by  doxygen 1.5.1