Initial packaging for Tizen
[profile/ivi/gobject-introspection.git] / girepository / gifieldinfo.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2  * GObject introspection: Field 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 #include "config.h"
29
30 /**
31  * SECTION:gifieldinfo
32  * @Short_description: Struct representing a struct or union field
33  * @Title: GIFieldInfo
34  *
35  * A GIFieldInfo struct represents a field of a struct (see #GIStructInfo),
36  * union (see #GIUnionInfo) or an object (see #GIObjectInfo). The GIFieldInfo
37  * is fetched by calling g_struct_info_get_field(), g_union_info_get_field()
38  * or g_object_info_get_value().
39  * A field has a size, type and a struct offset asssociated and a set of flags,
40  * which is currently #GI_FIELD_IS_READABLE or #GI_FIELD_IS_WRITABLE.
41  *
42  * <refsect1 id="gi-gifieldinfo.struct-hierarchy" role="struct_hierarchy">
43  * <title role="struct_hierarchy.title">Struct hierarchy</title>
44  * <synopsis>
45  *   <link linkend="gi-GIBaseInfo">GIBaseInfo</link>
46  *    +----GIFieldInfo
47  * </synopsis>
48  * </refsect1>
49  */
50
51 /**
52  * g_field_info_get_flags:
53  * @info: a #GIFieldInfo
54  *
55  * Obtain the flags for this #GIFieldInfo. See #GIFieldInfoFlags for possible
56  * flag values.
57  *
58  * Returns: the flags
59  */
60 GIFieldInfoFlags
61 g_field_info_get_flags (GIFieldInfo *info)
62 {
63   GIFieldInfoFlags flags;
64   GIRealInfo *rinfo = (GIRealInfo *)info;
65   FieldBlob *blob;
66
67   g_return_val_if_fail (info != NULL, 0);
68   g_return_val_if_fail (GI_IS_FIELD_INFO (info), 0);
69
70   blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
71
72   flags = 0;
73
74   if (blob->readable)
75     flags = flags | GI_FIELD_IS_READABLE;
76
77   if (blob->writable)
78     flags = flags | GI_FIELD_IS_WRITABLE;
79
80   return flags;
81 }
82
83 /**
84  * g_field_info_get_size:
85  * @info: a #GIFieldInfo
86  *
87  * Obtain the size in bits of the field member, this is how
88  * much space you need to allocate to store the field.
89  *
90  * Returns: the field size
91  */
92 gint
93 g_field_info_get_size (GIFieldInfo *info)
94 {
95   GIRealInfo *rinfo = (GIRealInfo *)info;
96   FieldBlob *blob;
97
98   g_return_val_if_fail (info != NULL, 0);
99   g_return_val_if_fail (GI_IS_FIELD_INFO (info), 0);
100
101   blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
102
103   return blob->bits;
104 }
105
106 /**
107  * g_field_info_get_offset:
108  * @info: a #GIFieldInfo
109  *
110  * Obtain the offset in bits of the field member, this is relative
111  * to the beginning of the struct or union.
112  *
113  * Returns: the field offset
114  */
115 gint
116 g_field_info_get_offset (GIFieldInfo *info)
117 {
118   GIRealInfo *rinfo = (GIRealInfo *)info;
119   FieldBlob *blob;
120
121   g_return_val_if_fail (info != NULL, 0);
122   g_return_val_if_fail (GI_IS_FIELD_INFO (info), 0);
123
124   blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
125
126   return blob->struct_offset;
127 }
128
129 /**
130  * g_field_info_get_type:
131  * @info: a #GIFieldInfo
132  *
133  * Obtain the type of a field as a #GITypeInfo.
134  *
135  * Returns: (transfer full): the #GITypeInfo. Free the struct by calling
136  * g_base_info_unref() when done.
137  */
138 GITypeInfo *
139 g_field_info_get_type (GIFieldInfo *info)
140 {
141   GIRealInfo *rinfo = (GIRealInfo *)info;
142   Header *header = (Header *)rinfo->typelib->data;
143   FieldBlob *blob;
144   GIRealInfo *type_info;
145
146   g_return_val_if_fail (info != NULL, NULL);
147   g_return_val_if_fail (GI_IS_FIELD_INFO (info), NULL);
148
149   blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
150
151   if (blob->has_embedded_type)
152     {
153       type_info = (GIRealInfo *) g_info_new (GI_INFO_TYPE_TYPE,
154                                                 (GIBaseInfo*)info, rinfo->typelib,
155                                                 rinfo->offset + header->field_blob_size);
156       type_info->type_is_embedded = TRUE;
157     }
158   else
159     return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type));
160
161   return (GIBaseInfo*)type_info;
162 }
163
164 /**
165  * g_field_info_get_field: (skip)
166  * @field_info: a #GIFieldInfo
167  * @mem: pointer to a block of memory representing a C structure or union
168  * @value: a #GIArgument into which to store the value retrieved
169  *
170  * Reads a field identified by a #GFieldInfo from a C structure or
171  * union.  This only handles fields of simple C types. It will fail
172  * for a field of a composite type like a nested structure or union
173  * even if that is actually readable.
174  *
175  * Returns: %TRUE if reading the field succeeded, otherwise %FALSE
176  */
177 gboolean
178 g_field_info_get_field (GIFieldInfo *field_info,
179                         gpointer     mem,
180                         GIArgument   *value)
181 {
182   int offset;
183   GITypeInfo *type_info;
184   gboolean result = FALSE;
185
186   g_return_val_if_fail (field_info != NULL, FALSE);
187   g_return_val_if_fail (GI_IS_FIELD_INFO (field_info), FALSE);
188
189   if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) == 0)
190     return FALSE;
191
192   offset = g_field_info_get_offset (field_info);
193   type_info = g_field_info_get_type (field_info);
194
195   if (g_type_info_is_pointer (type_info))
196     {
197       value->v_pointer = G_STRUCT_MEMBER (gpointer, mem, offset);
198       result = TRUE;
199     }
200   else
201     {
202       switch (g_type_info_get_tag (type_info))
203         {
204         case GI_TYPE_TAG_VOID:
205           g_warning("Field %s: should not be have void type",
206                     g_base_info_get_name ((GIBaseInfo *)field_info));
207           break;
208         case GI_TYPE_TAG_BOOLEAN:
209           value->v_boolean = G_STRUCT_MEMBER (gboolean, mem, offset) != FALSE;
210           result = TRUE;
211           break;
212         case GI_TYPE_TAG_INT8:
213         case GI_TYPE_TAG_UINT8:
214           value->v_uint8 = G_STRUCT_MEMBER (guint8, mem, offset);
215           result = TRUE;
216           break;
217         case GI_TYPE_TAG_INT16:
218         case GI_TYPE_TAG_UINT16:
219           value->v_uint16 = G_STRUCT_MEMBER (guint16, mem, offset);
220           result = TRUE;
221           break;
222         case GI_TYPE_TAG_INT32:
223         case GI_TYPE_TAG_UINT32:
224         case GI_TYPE_TAG_UNICHAR:
225           value->v_uint32 = G_STRUCT_MEMBER (guint32, mem, offset);
226           result = TRUE;
227           break;
228         case GI_TYPE_TAG_INT64:
229         case GI_TYPE_TAG_UINT64:
230           value->v_uint64 = G_STRUCT_MEMBER (guint64, mem, offset);
231           result = TRUE;
232           break;
233         case GI_TYPE_TAG_GTYPE:
234           value->v_size = G_STRUCT_MEMBER (gsize, mem, offset);
235           result = TRUE;
236           break;
237         case GI_TYPE_TAG_FLOAT:
238           value->v_float = G_STRUCT_MEMBER (gfloat, mem, offset);
239           result = TRUE;
240           break;
241         case GI_TYPE_TAG_DOUBLE:
242           value->v_double = G_STRUCT_MEMBER (gdouble, mem, offset);
243           result = TRUE;
244           break;
245         case GI_TYPE_TAG_ARRAY:
246           /* We don't check the array type and that it is fixed-size,
247              we trust g-ir-compiler to do the right thing */
248           value->v_pointer = G_STRUCT_MEMBER_P (mem, offset);
249           result = TRUE;
250           break;
251         case GI_TYPE_TAG_UTF8:
252         case GI_TYPE_TAG_FILENAME:
253         case GI_TYPE_TAG_GLIST:
254         case GI_TYPE_TAG_GSLIST:
255         case GI_TYPE_TAG_GHASH:
256           g_warning("Field %s: type %s should have is_pointer set",
257                     g_base_info_get_name ((GIBaseInfo *)field_info),
258                     g_type_tag_to_string (g_type_info_get_tag (type_info)));
259           break;
260         case GI_TYPE_TAG_ERROR:
261           /* Needs to be handled by the language binding directly */
262           break;
263         case GI_TYPE_TAG_INTERFACE:
264           {
265             GIBaseInfo *interface = g_type_info_get_interface (type_info);
266             switch (g_base_info_get_type (interface))
267               {
268               case GI_INFO_TYPE_STRUCT:
269               case GI_INFO_TYPE_UNION:
270               case GI_INFO_TYPE_BOXED:
271                 /* Needs to be handled by the language binding directly */
272                 break;
273               case GI_INFO_TYPE_OBJECT:
274                 break;
275               case GI_INFO_TYPE_ENUM:
276               case GI_INFO_TYPE_FLAGS:
277                 {
278                   /* FIXME: there's a mismatch here between the value->v_int we use
279                    * here and the gint64 result returned from g_value_info_get_value().
280                    * But to switch this to gint64, we'd have to make g_function_info_invoke()
281                    * translate value->v_int64 to the proper ABI for an enum function
282                    * call parameter, which will usually be int, and then fix up language
283                    * bindings.
284                    */
285                   GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface);
286                   switch (storage_type)
287                     {
288                     case GI_TYPE_TAG_INT8:
289                     case GI_TYPE_TAG_UINT8:
290                       value->v_int = (gint)G_STRUCT_MEMBER (guint8, mem, offset);
291                       result = TRUE;
292                       break;
293                     case GI_TYPE_TAG_INT16:
294                     case GI_TYPE_TAG_UINT16:
295                       value->v_int = (gint)G_STRUCT_MEMBER (guint16, mem, offset);
296                       result = TRUE;
297                       break;
298                     case GI_TYPE_TAG_INT32:
299                     case GI_TYPE_TAG_UINT32:
300                       value->v_int = (gint)G_STRUCT_MEMBER (guint32, mem, offset);
301                       result = TRUE;
302                       break;
303                     case GI_TYPE_TAG_INT64:
304                     case GI_TYPE_TAG_UINT64:
305                       value->v_int = (gint)G_STRUCT_MEMBER (guint64, mem, offset);
306                       result = TRUE;
307                       break;
308                     default:
309                       g_warning("Field %s: Unexpected enum storage type %s",
310                                 g_base_info_get_name ((GIBaseInfo *)field_info),
311                                 g_type_tag_to_string (storage_type));
312                       break;
313                     }
314                   break;
315                 }
316               case GI_INFO_TYPE_VFUNC:
317               case GI_INFO_TYPE_CALLBACK:
318                 g_warning("Field %s: Interface type %d should have is_pointer set",
319                           g_base_info_get_name ((GIBaseInfo *)field_info),
320                           g_base_info_get_type (interface));
321                 break;
322               case GI_INFO_TYPE_INVALID:
323               case GI_INFO_TYPE_INTERFACE:
324               case GI_INFO_TYPE_FUNCTION:
325               case GI_INFO_TYPE_CONSTANT:
326               case GI_INFO_TYPE_INVALID_0:
327               case GI_INFO_TYPE_VALUE:
328               case GI_INFO_TYPE_SIGNAL:
329               case GI_INFO_TYPE_PROPERTY:
330               case GI_INFO_TYPE_FIELD:
331               case GI_INFO_TYPE_ARG:
332               case GI_INFO_TYPE_TYPE:
333               case GI_INFO_TYPE_UNRESOLVED:
334                 g_warning("Field %s: Interface type %d not expected",
335                           g_base_info_get_name ((GIBaseInfo *)field_info),
336                           g_base_info_get_type (interface));
337                 break;
338               }
339
340             g_base_info_unref ((GIBaseInfo *)interface);
341             break;
342           }
343           break;
344         }
345     }
346
347   g_base_info_unref ((GIBaseInfo *)type_info);
348
349   return result;
350 }
351
352 /**
353  * g_field_info_set_field: (skip)
354  * @field_info: a #GIFieldInfo
355  * @mem: pointer to a block of memory representing a C structure or union
356  * @value: a #GIArgument holding the value to store
357  *
358  * Writes a field identified by a #GFieldInfo to a C structure or
359  * union.  This only handles fields of simple C types. It will fail
360  * for a field of a composite type like a nested structure or union
361  * even if that is actually writable. Note also that that it will refuse
362  * to write fields where memory management would by required. A field
363  * with a type such as 'char *' must be set with a setter function.
364  *
365  * Returns: %TRUE if writing the field succeeded, otherwise %FALSE
366  */
367 gboolean
368 g_field_info_set_field (GIFieldInfo     *field_info,
369                         gpointer         mem,
370                         const GIArgument *value)
371 {
372   int offset;
373   GITypeInfo *type_info;
374   gboolean result = FALSE;
375
376   g_return_val_if_fail (field_info != NULL, FALSE);
377   g_return_val_if_fail (GI_IS_FIELD_INFO (field_info), FALSE);
378
379   if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) == 0)
380     return FALSE;
381
382   offset = g_field_info_get_offset (field_info);
383   type_info = g_field_info_get_type (field_info);
384
385   if (!g_type_info_is_pointer (type_info))
386     {
387       switch (g_type_info_get_tag (type_info))
388         {
389         case GI_TYPE_TAG_VOID:
390           g_warning("Field %s: should not be have void type",
391                     g_base_info_get_name ((GIBaseInfo *)field_info));
392           break;
393         case GI_TYPE_TAG_BOOLEAN:
394           G_STRUCT_MEMBER (gboolean, mem, offset) = value->v_boolean != FALSE;
395           result = TRUE;
396           break;
397         case GI_TYPE_TAG_INT8:
398         case GI_TYPE_TAG_UINT8:
399           G_STRUCT_MEMBER (guint8, mem, offset) = value->v_uint8;
400           result = TRUE;
401           break;
402         case GI_TYPE_TAG_INT16:
403         case GI_TYPE_TAG_UINT16:
404           G_STRUCT_MEMBER (guint16, mem, offset) = value->v_uint16;
405           result = TRUE;
406           break;
407         case GI_TYPE_TAG_INT32:
408         case GI_TYPE_TAG_UINT32:
409         case GI_TYPE_TAG_UNICHAR:
410           G_STRUCT_MEMBER (guint32, mem, offset) = value->v_uint32;
411           result = TRUE;
412           break;
413         case GI_TYPE_TAG_INT64:
414         case GI_TYPE_TAG_UINT64:
415           G_STRUCT_MEMBER (guint64, mem, offset) = value->v_uint64;
416           result = TRUE;
417           break;
418         case GI_TYPE_TAG_GTYPE:
419           G_STRUCT_MEMBER (gsize, mem, offset) = value->v_size;
420           result = TRUE;
421           break;
422         case GI_TYPE_TAG_FLOAT:
423           G_STRUCT_MEMBER (gfloat, mem, offset) = value->v_float;
424           result = TRUE;
425           break;
426         case GI_TYPE_TAG_DOUBLE:
427           G_STRUCT_MEMBER (gdouble, mem, offset)= value->v_double;
428           result = TRUE;
429           break;
430         case GI_TYPE_TAG_UTF8:
431         case GI_TYPE_TAG_FILENAME:
432         case GI_TYPE_TAG_ARRAY:
433         case GI_TYPE_TAG_GLIST:
434         case GI_TYPE_TAG_GSLIST:
435         case GI_TYPE_TAG_GHASH:
436           g_warning("Field %s: type %s should have is_pointer set",
437                     g_base_info_get_name ((GIBaseInfo *)field_info),
438                     g_type_tag_to_string (g_type_info_get_tag (type_info)));
439           break;
440         case GI_TYPE_TAG_ERROR:
441           /* Needs to be handled by the language binding directly */
442           break;
443         case GI_TYPE_TAG_INTERFACE:
444           {
445             GIBaseInfo *interface = g_type_info_get_interface (type_info);
446             switch (g_base_info_get_type (interface))
447               {
448               case GI_INFO_TYPE_STRUCT:
449               case GI_INFO_TYPE_UNION:
450               case GI_INFO_TYPE_BOXED:
451                 /* Needs to be handled by the language binding directly */
452                 break;
453               case GI_INFO_TYPE_OBJECT:
454                 break;
455               case GI_INFO_TYPE_ENUM:
456               case GI_INFO_TYPE_FLAGS:
457                 {
458                   /* See FIXME above
459                    */
460                   GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface);
461                   switch (storage_type)
462                     {
463                     case GI_TYPE_TAG_INT8:
464                     case GI_TYPE_TAG_UINT8:
465                       G_STRUCT_MEMBER (guint8, mem, offset) = (guint8)value->v_int;
466                       result = TRUE;
467                       break;
468                     case GI_TYPE_TAG_INT16:
469                     case GI_TYPE_TAG_UINT16:
470                       G_STRUCT_MEMBER (guint16, mem, offset) = (guint16)value->v_int;
471                       result = TRUE;
472                       break;
473                     case GI_TYPE_TAG_INT32:
474                     case GI_TYPE_TAG_UINT32:
475                       G_STRUCT_MEMBER (guint32, mem, offset) = (guint32)value->v_int;
476                       result = TRUE;
477                       break;
478                     case GI_TYPE_TAG_INT64:
479                     case GI_TYPE_TAG_UINT64:
480                       G_STRUCT_MEMBER (guint64, mem, offset) = (guint64)value->v_int;
481                       result = TRUE;
482                       break;
483                     default:
484                       g_warning("Field %s: Unexpected enum storage type %s",
485                                 g_base_info_get_name ((GIBaseInfo *)field_info),
486                                 g_type_tag_to_string (storage_type));
487                       break;
488                     }
489                   break;
490                 }
491                 break;
492               case GI_INFO_TYPE_VFUNC:
493               case GI_INFO_TYPE_CALLBACK:
494                 g_warning("Field%s: Interface type %d should have is_pointer set",
495                           g_base_info_get_name ((GIBaseInfo *)field_info),
496                           g_base_info_get_type (interface));
497                 break;
498               case GI_INFO_TYPE_INVALID:
499               case GI_INFO_TYPE_INTERFACE:
500               case GI_INFO_TYPE_FUNCTION:
501               case GI_INFO_TYPE_CONSTANT:
502               case GI_INFO_TYPE_INVALID_0:
503               case GI_INFO_TYPE_VALUE:
504               case GI_INFO_TYPE_SIGNAL:
505               case GI_INFO_TYPE_PROPERTY:
506               case GI_INFO_TYPE_FIELD:
507               case GI_INFO_TYPE_ARG:
508               case GI_INFO_TYPE_TYPE:
509               case GI_INFO_TYPE_UNRESOLVED:
510                 g_warning("Field %s: Interface type %d not expected",
511                           g_base_info_get_name ((GIBaseInfo *)field_info),
512                           g_base_info_get_type (interface));
513                 break;
514               }
515
516             g_base_info_unref ((GIBaseInfo *)interface);
517             break;
518           }
519           break;
520         }
521     } else {
522       switch (g_type_info_get_tag (type_info))
523         {
524         case GI_TYPE_TAG_INTERFACE:
525           {
526             GIBaseInfo *interface = g_type_info_get_interface (type_info);
527             switch (g_base_info_get_type (interface))
528               {
529                 case GI_INFO_TYPE_OBJECT:
530                 case GI_INFO_TYPE_INTERFACE:
531                   G_STRUCT_MEMBER (gpointer, mem, offset) = (gpointer)value->v_pointer;
532                   result = TRUE;
533                   break;
534                 default:
535                   break;
536               }
537               g_base_info_unref ((GIBaseInfo *)interface);
538           }
539         default:
540           break;
541         }
542     }
543
544   g_base_info_unref ((GIBaseInfo *)type_info);
545
546   return result;
547 }