Branch and submit for IVI panda
[profile/ivi/gobject-introspection.git] / girepository / giunioninfo.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2  * GObject introspection: Union implementation
3  *
4  * Copyright (C) 2005 Matthias Clasen
5  * Copyright (C) 2008,2009 Red Hat, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <glib.h>
24
25 #include <girepository.h>
26 #include "girepository-private.h"
27 #include "gitypelib-internal.h"
28
29 /**
30  * SECTION:giunioninfo
31  * @Short_description: Struct representing a union.
32  * @Title: GIUnionInfo
33  *
34  * GIUnionInfo represents a union type.
35  *
36  * A union has methods and fields.  Unions can optionally have a
37  * discriminator, which is a field deciding what type of real union
38  * fields is valid for specified instance.
39  *
40  * <refsect1 id="gi-giobjectinfo.struct-hierarchy" role="struct_hierarchy">
41  * <title role="struct_hierarchy.title">Struct hierarchy</title>
42  * <synopsis>
43  *   <link linkend="gi-GIBaseInfo">GIBaseInfo</link>
44  *    +----<link linkend="gi-GIRegisteredTypeInfo">GIRegisteredTypeInfo</link>
45  *          +----GIUnionInfo
46  * </synopsis>
47  * </refsect1>
48  */
49
50 /**
51  * g_union_info_get_n_fields:
52  * @info: a #GIUnionInfo
53  *
54  * Obtain the number of fields this union has.
55  *
56  * Returns: number of fields
57  */
58 gint
59 g_union_info_get_n_fields  (GIUnionInfo *info)
60 {
61   GIRealInfo *rinfo = (GIRealInfo *)info;
62   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
63
64   return blob->n_fields;
65 }
66
67 /**
68  * g_union_info_get_field:
69  * @info: a #GIUnionInfo
70  * @n: a field index
71  *
72  * Obtain the type information for field with specified index.
73  *
74  * Returns: (transfer full): the #GIFieldInfo, free it with g_base_info_unref()
75  * when done.
76  */
77 GIFieldInfo *
78 g_union_info_get_field (GIUnionInfo *info,
79                         gint         n)
80 {
81   GIRealInfo *rinfo = (GIRealInfo *)info;
82   Header *header = (Header *)rinfo->typelib->data;
83
84   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib,
85                                      rinfo->offset + header->union_blob_size +
86                                      n * header->field_blob_size);
87 }
88
89 /**
90  * g_union_info_get_n_methods:
91  * @info: a #GIUnionInfo
92  *
93  * Obtain the number of methods this union has.
94  *
95  * Returns: number of methods
96  */
97 gint
98 g_union_info_get_n_methods (GIUnionInfo *info)
99 {
100   GIRealInfo *rinfo = (GIRealInfo *)info;
101   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
102
103   return blob->n_functions;
104 }
105
106 /**
107  * g_union_info_get_method:
108  * @info: a #GIUnionInfo
109  * @n: a method index
110  *
111  * Obtain the type information for method with specified index.
112  *
113  * Returns: (transfer full): the #GIFunctionInfo, free it with g_base_info_unref()
114  * when done.
115  */
116 GIFunctionInfo *
117 g_union_info_get_method (GIUnionInfo *info,
118                          gint         n)
119 {
120   GIRealInfo *rinfo = (GIRealInfo *)info;
121   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
122   Header *header = (Header *)rinfo->typelib->data;
123   gint offset;
124
125   offset = rinfo->offset + header->union_blob_size
126     + blob->n_fields * header->field_blob_size
127     + n * header->function_blob_size;
128   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
129                                         rinfo->typelib, offset);
130 }
131
132 /**
133  * g_union_info_is_discriminated:
134  * @info: a #GIUnionInfo
135  *
136  * Return true if this union contains discriminator field.
137  *
138  * Returns: %TRUE if this is a discriminated union, %FALSE otherwise
139  */
140 gboolean
141 g_union_info_is_discriminated (GIUnionInfo *info)
142 {
143   GIRealInfo *rinfo = (GIRealInfo *)info;
144   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
145
146   return blob->discriminated;
147 }
148
149 /**
150  * g_union_info_get_discrimintor_offset:
151  * @info: a #GIUnionInfo
152  *
153  * Returns offset of the discriminator field in the structure.
154  *
155  * Returns: (transfer full): offset in bytes of the discriminator
156  */
157 gint
158 g_union_info_get_discriminator_offset (GIUnionInfo *info)
159 {
160   GIRealInfo *rinfo = (GIRealInfo *)info;
161   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
162
163   return blob->discriminator_offset;
164 }
165
166 /**
167  * g_union_info_get_discriminator_type:
168  * @info: a #GIUnionInfo
169  *
170  * Obtain the type information of the union discriminator.
171  *
172  * Returns: (transfer full): the #GITypeInfo, free it with g_base_info_unref()
173  * when done.
174  */
175 GITypeInfo *
176 g_union_info_get_discriminator_type (GIUnionInfo *info)
177 {
178   GIRealInfo *rinfo = (GIRealInfo *)info;
179
180   return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24);
181 }
182
183 /**
184  * g_union_info_get_discriminator:
185  * @info: a #GIUnionInfo
186  * @n: a union field index
187  *
188  * Obtain discriminator value assigned for n-th union field, i.e. n-th
189  * union field is the active one if discriminator contains this
190  * constant.
191  *
192  * Returns: (transfer full): the #GIConstantInfo, free it with g_base_info_unref()
193  * when done.
194  */
195 GIConstantInfo *
196 g_union_info_get_discriminator (GIUnionInfo *info,
197                                 gint         n)
198 {
199   GIRealInfo *rinfo = (GIRealInfo *)info;
200   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
201
202   if (blob->discriminated)
203     {
204       Header *header = (Header *)rinfo->typelib->data;
205       gint offset;
206
207       offset = rinfo->offset + header->union_blob_size
208         + blob->n_fields * header->field_blob_size
209         + blob->n_functions * header->function_blob_size
210         + n * header->constant_blob_size;
211
212       return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
213                                             rinfo->typelib, offset);
214     }
215
216   return NULL;
217 }
218
219 /**
220  * g_union_info_find_method:
221  * @info: a #GIUnionInfo
222  * @name: a method name
223  *
224  * Obtain the type information for method named @name.
225  *
226  * Returns: (transfer full): the #GIFunctionInfo, free it with g_base_info_unref()
227  * when done.
228  */
229 GIFunctionInfo *
230 g_union_info_find_method (GIUnionInfo *info,
231                           const gchar *name)
232 {
233   gint offset;
234   GIRealInfo *rinfo = (GIRealInfo *)info;
235   Header *header = (Header *)rinfo->typelib->data;
236   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
237
238   offset = rinfo->offset + header->union_blob_size
239     + blob->n_fields * header->field_blob_size;
240
241   return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_functions, name);
242 }
243
244 /**
245  * g_union_info_get_size:
246  * @info: a #GIUnionInfo
247  *
248  * Obtain the total size of the union.
249  *
250  * Returns: size of the union in bytes
251  */
252 gsize
253 g_union_info_get_size (GIUnionInfo *info)
254 {
255   GIRealInfo *rinfo = (GIRealInfo *)info;
256   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
257
258   return blob->size;
259 }
260
261 /**
262  * g_union_info_get_alignment:
263  * @info: a #GIUnionInfo
264  *
265  * Obtain the required alignment of the union.
266  *
267  * Returns: required alignment in bytes
268  */
269 gsize
270 g_union_info_get_alignment (GIUnionInfo *info)
271 {
272   GIRealInfo *rinfo = (GIRealInfo *)info;
273   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
274
275   return blob->alignment;
276 }