Update.
[platform/upstream/glib.git] / gobject / gvaluecollector.h
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * gvaluecollector.h: GValue varargs stubs
20  */
21 #ifndef __G_VALUE_COLLECTOR_H__
22 #define __G_VALUE_COLLECTOR_H__
23
24 G_BEGIN_DECLS
25
26 /* we may want to add aggregate types here some day, if requested
27  * by users. the basic C types are covered already, everything
28  * smaller than an int is promoted to an integer and floats are
29  * always promoted to doubles for varargs call constructions.
30  */
31 enum    /*< skip >*/
32 {
33   G_VALUE_COLLECT_INT           = 'i',
34   G_VALUE_COLLECT_LONG          = 'l',
35   G_VALUE_COLLECT_INT64         = 'q',
36   G_VALUE_COLLECT_DOUBLE        = 'd',
37   G_VALUE_COLLECT_POINTER       = 'p'
38 };
39
40
41 /* vararg union holding actuall values collected
42  */
43 union _GTypeCValue
44 {
45   gint     v_int;
46   glong    v_long;
47   gint64   v_int64;
48   gdouble  v_double;
49   gpointer v_pointer;
50 };
51
52
53 /* G_VALUE_COLLECT() collects a variable argument value
54  * from a va_list. we have to implement the varargs collection as a
55  * macro, because on some systems va_list variables cannot be passed
56  * by reference.
57  * value is supposed to be initialized according to the value
58  * type to be collected.
59  * var_args is the va_list variable and may be evaluated multiple times.
60  * __error is a gchar** variable that will be modified to hold a g_new()
61  * allocated error messages if something fails.
62  */
63 #define G_VALUE_COLLECT(value, var_args, flags, __error)                                \
64 G_STMT_START {                                                                          \
65   GValue *_value = (value);                                                             \
66   guint _flags = (flags);                                                               \
67   GType _value_type = G_VALUE_TYPE (_value);                                            \
68   GTypeValueTable *_vtable = g_type_value_table_peek (_value_type);                     \
69   gchar *_collect_format = _vtable->collect_format;                                     \
70   GTypeCValue _cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, };                \
71   guint _n_values = 0;                                                                  \
72                                                                                         \
73   if (_vtable->value_free)                                                              \
74     _vtable->value_free (_value);                                                       \
75   _value->g_type = _value_type;         /* value_meminit() from gvalue.c */             \
76   memset (_value->data, 0, sizeof (_value->data));                                      \
77   while (*_collect_format)                                                              \
78     {                                                                                   \
79       GTypeCValue *_cvalue = _cvalues + _n_values++;                                    \
80                                                                                         \
81       switch (*_collect_format++)                                                       \
82         {                                                                               \
83         case G_VALUE_COLLECT_INT:                                                       \
84           _cvalue->v_int = va_arg ((var_args), gint);                                   \
85           break;                                                                        \
86         case G_VALUE_COLLECT_LONG:                                                      \
87           _cvalue->v_long = va_arg ((var_args), glong);                                 \
88           break;                                                                        \
89         case G_VALUE_COLLECT_INT64:                                                     \
90           _cvalue->v_int64 = va_arg ((var_args), gint64);                               \
91           break;                                                                        \
92         case G_VALUE_COLLECT_DOUBLE:                                                    \
93           _cvalue->v_double = va_arg ((var_args), gdouble);                             \
94           break;                                                                        \
95         case G_VALUE_COLLECT_POINTER:                                                   \
96           _cvalue->v_pointer = va_arg ((var_args), gpointer);                           \
97           break;                                                                        \
98         default:                                                                        \
99           g_assert_not_reached ();                                                      \
100         }                                                                               \
101     }                                                                                   \
102   *(__error) = _vtable->collect_value (_value,                                          \
103                                        _n_values,                                       \
104                                        _cvalues,                                        \
105                                        _flags);                                         \
106 } G_STMT_END
107
108
109 /* G_VALUE_LCOPY() collects a value's variable argument
110  * locations from a va_list. usage is analogous to G_VALUE_COLLECT().
111  */
112 #define G_VALUE_LCOPY(value, var_args, flags, __error)                                  \
113 G_STMT_START {                                                                          \
114   const GValue *_value = (value);                                                       \
115   guint _flags = (flags);                                                               \
116   GType _value_type = G_VALUE_TYPE (_value);                                            \
117   GTypeValueTable *_vtable = g_type_value_table_peek (_value_type);                     \
118   gchar *_lcopy_format = _vtable->lcopy_format;                                         \
119   GTypeCValue _cvalues[G_VALUE_COLLECT_FORMAT_MAX_LENGTH] = { { 0, }, };                \
120   guint _n_values = 0;                                                                  \
121                                                                                         \
122   while (*_lcopy_format)                                                                \
123     {                                                                                   \
124       GTypeCValue *_cvalue = _cvalues + _n_values++;                                    \
125                                                                                         \
126       switch (*_lcopy_format++)                                                         \
127         {                                                                               \
128         case G_VALUE_COLLECT_INT:                                                       \
129           _cvalue->v_int = va_arg ((var_args), gint);                                   \
130           break;                                                                        \
131         case G_VALUE_COLLECT_LONG:                                                      \
132           _cvalue->v_long = va_arg ((var_args), glong);                                 \
133           break;                                                                        \
134         case G_VALUE_COLLECT_INT64:                                                     \
135           _cvalue->v_int64 = va_arg ((var_args), gint64);                               \
136           break;                                                                        \
137         case G_VALUE_COLLECT_DOUBLE:                                                    \
138           _cvalue->v_double = va_arg ((var_args), gdouble);                             \
139           break;                                                                        \
140         case G_VALUE_COLLECT_POINTER:                                                   \
141           _cvalue->v_pointer = va_arg ((var_args), gpointer);                           \
142           break;                                                                        \
143         default:                                                                        \
144           g_assert_not_reached ();                                                      \
145         }                                                                               \
146     }                                                                                   \
147   *(__error) = _vtable->lcopy_value (_value,                                            \
148                                      _n_values,                                         \
149                                      _cvalues,                                          \
150                                      _flags);                                           \
151 } G_STMT_END
152
153
154 #define G_VALUE_COLLECT_FORMAT_MAX_LENGTH       (8)
155
156 G_END_DECLS
157
158 #endif /* __G_VALUE_COLLECTOR_H__ */