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];
00471   types[0] = key_specialization;
00472   types[1] = value_specialization;
00473   return lookup_or_register_specialized (container, 2, types);
00474 }
00475 
00487 GType
00488 dbus_g_type_get_structv (const char   *container,
00489                          guint         num_members,
00490                          GType        *types)
00491 {
00492   return lookup_or_register_specialized (container, num_members, types);
00493 }
00494 
00506 GType
00507 dbus_g_type_get_struct (const char *container,
00508                         GType first_type,
00509                         ...)
00510 {
00511   GArray *types;
00512   GType curtype, ret;
00513   va_list args;
00514   va_start (args, first_type);
00515 
00516   types = g_array_new (FALSE, FALSE, sizeof (GType));
00517   curtype = first_type;
00518   while (curtype != G_TYPE_INVALID)
00519     {
00520       g_array_append_val (types, curtype);
00521       curtype = va_arg (args, GType);
00522     }
00523   va_end (args);
00524 
00525   ret = lookup_or_register_specialized (container, types->len,
00526       (GType *) types->data);
00527 
00528   g_array_free (types, TRUE);
00529 
00530   return ret;
00531 }
00532 
00533 
00542 gboolean
00543 dbus_g_type_is_collection (GType gtype)
00544 {
00545   DBusGTypeSpecializedData *data;
00546   data = lookup_specialization_data (gtype);
00547   if (data == NULL)
00548     return FALSE;
00549   return data->klass->type == DBUS_G_SPECTYPE_COLLECTION;
00550 }
00551 
00561 gboolean
00562 dbus_g_type_is_map (GType gtype)
00563 {
00564   DBusGTypeSpecializedData *data;
00565   data = lookup_specialization_data (gtype);
00566   if (data == NULL)
00567     return FALSE;
00568   return data->klass->type == DBUS_G_SPECTYPE_MAP;
00569 }
00570 
00580 gboolean
00581 dbus_g_type_is_struct (GType gtype)
00582 {
00583   DBusGTypeSpecializedData *data;
00584   data = lookup_specialization_data (gtype);
00585   if (data == NULL)
00586     return FALSE;
00587   return data->klass->type == DBUS_G_SPECTYPE_STRUCT;
00588 }
00589 
00590 
00591 static GType
00592 get_specialization_index (GType gtype, guint i)
00593 {
00594   DBusGTypeSpecializedData *data;
00595 
00596   data = lookup_specialization_data (gtype);
00597   if (i < data->num_types)
00598     return data->types[i];
00599   else
00600     return G_TYPE_INVALID;
00601 }
00602 
00610 GType
00611 dbus_g_type_get_collection_specialization (GType gtype)
00612 {
00613   g_return_val_if_fail (dbus_g_type_is_collection (gtype), G_TYPE_INVALID);
00614   return get_specialization_index (gtype, 0);
00615 }
00616 
00624 GType
00625 dbus_g_type_get_map_key_specialization (GType gtype)
00626 {
00627   g_return_val_if_fail (dbus_g_type_is_map (gtype), G_TYPE_INVALID);
00628   return get_specialization_index (gtype, 0);
00629 }
00630 
00638 GType
00639 dbus_g_type_get_map_value_specialization (GType gtype)
00640 {
00641   g_return_val_if_fail (dbus_g_type_is_map (gtype), G_TYPE_INVALID);
00642   return get_specialization_index (gtype, 1);
00643 }
00644 
00653 GType
00654 dbus_g_type_get_struct_member_type (GType gtype, guint member)
00655 {
00656   g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID);
00657   return get_specialization_index (gtype, member);
00658 }
00659 
00667 guint
00668 dbus_g_type_get_struct_size (GType gtype)
00669 {
00670   DBusGTypeSpecializedData *data;
00671   g_return_val_if_fail (dbus_g_type_is_struct (gtype), G_TYPE_INVALID);
00672 
00673   data = lookup_specialization_data (gtype);
00674   return data->num_types;
00675 }
00676 
00689 gpointer
00690 dbus_g_type_specialized_construct (GType gtype)
00691 {
00692   DBusGTypeSpecializedData *data;
00693   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00694 
00695   data = lookup_specialization_data (gtype);
00696   g_return_val_if_fail (data != NULL, FALSE);
00697 
00698   return data->klass->vtable->constructor (gtype);
00699 }
00700 
00709 gboolean
00710 dbus_g_type_collection_get_fixed (GValue   *value,
00711                                   gpointer *data_ret,
00712                                   guint    *len_ret)
00713 {
00714   DBusGTypeSpecializedData *data;
00715   GType gtype;
00716 
00717   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00718   g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
00719 
00720   gtype = G_VALUE_TYPE (value);
00721   data = lookup_specialization_data (gtype);
00722   g_return_val_if_fail (data != NULL, FALSE);
00723 
00724   return ((DBusGTypeSpecializedCollectionVtable *) (data->klass->vtable))->fixed_accessor (gtype,
00725                                                                                            g_value_get_boxed (value),
00726                                                                                            data_ret, len_ret);
00727 }
00728 
00740 void
00741 dbus_g_type_collection_value_iterate (const GValue                           *value,
00742                                       DBusGTypeSpecializedCollectionIterator  iterator,
00743                                       gpointer                                user_data)
00744 {
00745   DBusGTypeSpecializedData *data;
00746   GType gtype;
00747 
00748   g_return_if_fail (specialized_types_is_initialized ());
00749   g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
00750 
00751   gtype = G_VALUE_TYPE (value);
00752   data = lookup_specialization_data (gtype);
00753   g_return_if_fail (data != NULL);
00754 
00755   ((DBusGTypeSpecializedCollectionVtable *) data->klass->vtable)->iterator (gtype,
00756                                                                             g_value_get_boxed (value),
00757                                                                             iterator, user_data);
00758 }
00759 
00760 typedef struct {
00761   GValue *val;
00762   GType specialization_type;
00763   DBusGTypeSpecializedData *specdata;
00764 } DBusGTypeSpecializedAppendContextReal;
00765 
00775 void
00776 dbus_g_type_specialized_init_append (GValue *value, DBusGTypeSpecializedAppendContext *ctx)
00777 {
00778   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00779   GType gtype;
00780   DBusGTypeSpecializedData *specdata;
00781   
00782   g_return_if_fail (specialized_types_is_initialized ());
00783   g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
00784   gtype = G_VALUE_TYPE (value);
00785   specdata = lookup_specialization_data (gtype);
00786   g_return_if_fail (specdata != NULL);
00787   g_return_if_fail (specdata->num_types != 0);
00788 
00789   realctx->val = value;
00790   realctx->specialization_type = specdata->types[0];
00791   realctx->specdata = specdata;
00792 }
00793 
00802 void
00803 dbus_g_type_specialized_collection_append (DBusGTypeSpecializedAppendContext *ctx,
00804                                            GValue                            *elt)
00805 {
00806   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00807   ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->append_func (ctx, elt);
00808 }
00809 
00817 void
00818 dbus_g_type_specialized_collection_end_append (DBusGTypeSpecializedAppendContext *ctx)
00819 {
00820   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00821   if (((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func != NULL)
00822     ((DBusGTypeSpecializedCollectionVtable *) realctx->specdata->klass->vtable)->end_append_func (ctx);
00823 }
00824 
00834 void
00835 dbus_g_type_specialized_map_append (DBusGTypeSpecializedAppendContext *ctx,
00836                                     GValue                            *key,
00837                                     GValue                            *val)
00838 {
00839   DBusGTypeSpecializedAppendContextReal *realctx = (DBusGTypeSpecializedAppendContextReal *) ctx;
00840   ((DBusGTypeSpecializedMapVtable *) realctx->specdata->klass->vtable)->append_func (ctx, key, val);
00841 }
00842 
00843 
00855 void
00856 dbus_g_type_map_value_iterate (const GValue                           *value,
00857                                DBusGTypeSpecializedMapIterator         iterator,
00858                                gpointer                                user_data)
00859 {
00860   DBusGTypeSpecializedData *data;
00861   GType gtype;
00862 
00863   g_return_if_fail (specialized_types_is_initialized ());
00864   g_return_if_fail (G_VALUE_HOLDS_BOXED (value));
00865 
00866   gtype = G_VALUE_TYPE (value);
00867   data = lookup_specialization_data (gtype);
00868   g_return_if_fail (data != NULL);
00869 
00870   ((DBusGTypeSpecializedMapVtable *) data->klass->vtable)->iterator (gtype,
00871                                                                      g_value_get_boxed (value),
00872                                                                      iterator, user_data);
00873 }
00874 
00887 gboolean
00888 dbus_g_type_struct_get_member (const GValue *value,
00889                                guint         member,
00890                                GValue       *dest)
00891 {
00892   DBusGTypeSpecializedData *data;
00893   GType gtype;
00894 
00895   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00896   g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
00897 
00898   gtype = G_VALUE_TYPE (value);
00899   data = lookup_specialization_data (gtype);
00900   g_return_val_if_fail (data != NULL, FALSE);
00901 
00902   return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->get_member(gtype,
00903                                                                                            g_value_get_boxed (value),
00904                                                                                            member, dest);
00905 }
00906 
00918 gboolean
00919 dbus_g_type_struct_set_member (GValue       *value,
00920                                guint         member,
00921                                const GValue *src)
00922 {
00923   DBusGTypeSpecializedData *data;
00924   GType gtype;
00925 
00926   g_return_val_if_fail (specialized_types_is_initialized (), FALSE);
00927   g_return_val_if_fail (G_VALUE_HOLDS_BOXED (value), FALSE);
00928 
00929   gtype = G_VALUE_TYPE (value);
00930   data = lookup_specialization_data (gtype);
00931   g_return_val_if_fail (data != NULL, FALSE);
00932 
00933   return ((DBusGTypeSpecializedStructVtable *) (data->klass->vtable))->set_member(gtype,
00934                                                                                            g_value_get_boxed (value),
00935                                                                                            member, src);
00936 }
00937 
00952 gboolean
00953 dbus_g_type_struct_get                   (const GValue *value,
00954                                           guint first_member,
00955                                           ...)
00956 {
00957   va_list var_args;
00958   GType type;
00959   guint size,i;
00960   gchar *error;
00961   GValue val = {0,};
00962 
00963   g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE);
00964 
00965   va_start (var_args, first_member);
00966   size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
00967   i = first_member;
00968   while (i != G_MAXUINT)
00969     {
00970       if (i >= size)
00971         goto error;
00972 
00973       type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i);
00974 
00975       g_value_init (&val, type);
00976       dbus_g_type_struct_get_member (value, i, &val);
00977 
00978       G_VALUE_LCOPY (&val, var_args, 0, &error);
00979       if (error)
00980         {
00981           g_warning ("%s, %s", G_STRFUNC, error);
00982           g_free (error);
00983           g_value_unset (&val);
00984           goto error;
00985         }
00986       g_value_unset (&val);
00987       i = va_arg (var_args, guint);
00988     }
00989   va_end (var_args);
00990   return TRUE;
00991 error:
00992   va_end (var_args);
00993   return FALSE;
00994 }
00995 
01008 gboolean
01009 dbus_g_type_struct_set                   (GValue *value,
01010                                           guint first_member,
01011                                           ...)
01012 {
01013   va_list var_args;
01014   GType type;
01015   guint size,i;
01016   gchar *error;
01017   GValue val = {0,};
01018 
01019   g_return_val_if_fail (dbus_g_type_is_struct (G_VALUE_TYPE (value)), FALSE);
01020 
01021   va_start (var_args, first_member);
01022   size = dbus_g_type_get_struct_size (G_VALUE_TYPE (value));
01023   i = first_member;
01024   while (i != G_MAXUINT)
01025     {
01026       if (i >= size)
01027         goto error;
01028 
01029       type = dbus_g_type_get_struct_member_type (G_VALUE_TYPE (value),i);
01030 
01031       g_value_init (&val, type);
01032 
01033       G_VALUE_COLLECT (&val, var_args, 0, &error);
01034       if (error)
01035         {
01036           g_warning ("%s, %s", G_STRFUNC, error);
01037           g_free (error);
01038           g_value_unset (&val);
01039           goto error;
01040         }
01041 
01042       dbus_g_type_struct_set_member (value, i, &val);
01043 
01044       g_value_unset (&val);
01045       i = va_arg (var_args, guint);
01046     }
01047   va_end (var_args);
01048   return TRUE;
01049 error:
01050   va_end (var_args);
01051   return FALSE;
01052 }
01053 

Generated on Tue Feb 24 16:47:59 2009 for D-BUSGLibBindings by  doxygen 1.5.1