[STRIP_SUFFIX]
[gnome.gobject-introspection] / girepository / gfield.c
1 #include <string.h>
2
3 #include "girepository.h"
4 #include "girffi.h"
5 #include "config.h"
6
7 /**
8  * g_field_info_get_field:
9  * @field_info: a #GIFieldInfo
10  * @mem: pointer to a block of memory representing a C structure or union
11  * @value: a #GArgument into which to store the value retrieved
12  *
13  * Reads a field identified by a #GFieldInfo from a C structure or
14  * union.  This only handles fields of simple C types. It will fail
15  * for a field of a composite type like a nested structure or union
16  * even if that is actually readable.
17  *
18  * Returns: %TRUE if reading the field succeeded, otherwise %FALSE
19  */
20 gboolean
21 g_field_info_get_field (GIFieldInfo *field_info,
22                         gpointer     mem,
23                         GArgument   *value)
24 {
25     int offset;
26     GITypeInfo *type_info;
27     gboolean result = FALSE;
28
29     if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) == 0)
30       return FALSE;
31
32     offset = g_field_info_get_offset (field_info);
33     type_info = g_field_info_get_type (field_info);
34
35     if (g_type_info_is_pointer (type_info))
36       {
37         value->v_pointer = G_STRUCT_MEMBER(gpointer, mem, offset);
38         result = TRUE;
39       }
40     else
41       {
42         switch (g_type_info_get_tag (type_info))
43           {
44           case GI_TYPE_TAG_VOID:
45             g_warning("Field %s: should not be have void type",
46                       g_base_info_get_name ((GIBaseInfo *)field_info));
47             break;
48           case GI_TYPE_TAG_BOOLEAN:
49             value->v_boolean = G_STRUCT_MEMBER(gboolean, mem, offset) != FALSE;
50             result = TRUE;
51             break;
52           case GI_TYPE_TAG_INT8:
53           case GI_TYPE_TAG_UINT8:
54             value->v_uint8 = G_STRUCT_MEMBER(guint8, mem, offset);
55             result = TRUE;
56             break;
57           case GI_TYPE_TAG_INT16:
58           case GI_TYPE_TAG_UINT16:
59           case GI_TYPE_TAG_SHORT:
60           case GI_TYPE_TAG_USHORT:
61             value->v_uint16 = G_STRUCT_MEMBER(guint16, mem, offset);
62             result = TRUE;
63             break;
64           case GI_TYPE_TAG_INT32:
65           case GI_TYPE_TAG_UINT32:
66           case GI_TYPE_TAG_INT:
67           case GI_TYPE_TAG_UINT:
68             value->v_uint32 = G_STRUCT_MEMBER(guint32, mem, offset);
69             result = TRUE;
70             break;
71           case GI_TYPE_TAG_INT64:
72           case GI_TYPE_TAG_UINT64:
73             value->v_uint64 = G_STRUCT_MEMBER(guint64, mem, offset);
74             result = TRUE;
75             break;
76           case GI_TYPE_TAG_LONG:
77           case GI_TYPE_TAG_ULONG:
78             value->v_ulong = G_STRUCT_MEMBER(gulong, mem, offset);
79             result = TRUE;
80             break;
81           case GI_TYPE_TAG_SSIZE:
82           case GI_TYPE_TAG_SIZE:
83           case GI_TYPE_TAG_GTYPE:
84             value->v_size = G_STRUCT_MEMBER(gsize, mem, offset);
85             result = TRUE;
86             break;
87           case GI_TYPE_TAG_FLOAT:
88             value->v_float = G_STRUCT_MEMBER(gfloat, mem, offset);
89             result = TRUE;
90             break;
91           case GI_TYPE_TAG_DOUBLE:
92             value->v_double = G_STRUCT_MEMBER(gdouble, mem, offset);
93             result = TRUE;
94             break;
95           case GI_TYPE_TAG_TIME_T:
96 #if SIZEOF_TIME_T == 4
97             value->v_int32 = G_STRUCT_MEMBER(time_t, mem, offset);
98 #elif SIZEOF_TIME_T == 8
99             value->v_int64 = G_STRUCT_MEMBER(time_t, mem, offset);
100 #else
101 #  error "Unexpected size for time_t: not 4 or 8"
102 #endif
103             result = TRUE;
104             break;
105           case GI_TYPE_TAG_UTF8:
106           case GI_TYPE_TAG_FILENAME:
107           case GI_TYPE_TAG_ARRAY:
108           case GI_TYPE_TAG_GLIST:
109           case GI_TYPE_TAG_GSLIST:
110           case GI_TYPE_TAG_GHASH:
111             g_warning("Field %s: type %s should have is_pointer set",
112                       g_base_info_get_name ((GIBaseInfo *)field_info),
113                       g_type_tag_to_string (g_type_info_get_tag (type_info)));
114             break;
115           case GI_TYPE_TAG_ERROR:
116             /* Needs to be handled by the language binding directly */
117             break;
118           case GI_TYPE_TAG_INTERFACE:
119             {
120               GIBaseInfo *interface = g_type_info_get_interface (type_info);
121               switch (g_base_info_get_type (interface))
122                 {
123                 case GI_INFO_TYPE_STRUCT:
124                 case GI_INFO_TYPE_UNION:
125                 case GI_INFO_TYPE_BOXED:
126                   /* Needs to be handled by the language binding directly */
127                   break;
128                 case GI_INFO_TYPE_OBJECT:
129                   break;
130                 case GI_INFO_TYPE_ENUM:
131                 case GI_INFO_TYPE_FLAGS:
132                   {
133                     /* FIXME: there's a mismatch here between the value->v_int we use
134                      * here and the glong result returned from g_value_info_get_value().
135                      * But to switch this to glong, we'd have to make g_function_info_invoke()
136                      * translate value->v_long to the proper ABI for an enum function
137                      * call parameter, which will usually be int, and then fix up language
138                      * bindings.
139                      */
140                     GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface);
141                     switch (storage_type)
142                       {
143                       case GI_TYPE_TAG_INT8:
144                       case GI_TYPE_TAG_UINT8:
145                         value->v_int = (gint)G_STRUCT_MEMBER(guint8, mem, offset);
146                         result = TRUE;
147                         break;
148                       case GI_TYPE_TAG_INT16:
149                       case GI_TYPE_TAG_UINT16:
150                       case GI_TYPE_TAG_SHORT:
151                       case GI_TYPE_TAG_USHORT:
152                         value->v_int = (gint)G_STRUCT_MEMBER(guint16, mem, offset);
153                         result = TRUE;
154                         break;
155                       case GI_TYPE_TAG_INT32:
156                       case GI_TYPE_TAG_UINT32:
157                       case GI_TYPE_TAG_INT:
158                       case GI_TYPE_TAG_UINT:
159                         value->v_int = (gint)G_STRUCT_MEMBER(guint32, mem, offset);
160                         result = TRUE;
161                         break;
162                       case GI_TYPE_TAG_INT64:
163                       case GI_TYPE_TAG_UINT64:
164                         value->v_int = (gint)G_STRUCT_MEMBER(guint64, mem, offset);
165                         result = TRUE;
166                         break;
167                       case GI_TYPE_TAG_LONG:
168                       case GI_TYPE_TAG_ULONG:
169                         value->v_int = (gint)G_STRUCT_MEMBER(gulong, mem, offset);
170                         result = TRUE;
171                         break;
172                       default:
173                         g_warning("Field %s: Unexpected enum storage type %s",
174                                   g_base_info_get_name ((GIBaseInfo *)field_info),
175                                   g_type_tag_to_string (storage_type));
176                         break;
177                       }
178                     break;
179                   }
180                 case GI_INFO_TYPE_VFUNC:
181                 case GI_INFO_TYPE_CALLBACK:
182                   g_warning("Field %s: Interface type %d should have is_pointer set",
183                             g_base_info_get_name ((GIBaseInfo *)field_info),
184                             g_base_info_get_type (interface));
185                   break;
186                 case GI_INFO_TYPE_INVALID:
187                 case GI_INFO_TYPE_INTERFACE:
188                 case GI_INFO_TYPE_FUNCTION:
189                 case GI_INFO_TYPE_CONSTANT:
190                 case GI_INFO_TYPE_ERROR_DOMAIN:
191                 case GI_INFO_TYPE_VALUE:
192                 case GI_INFO_TYPE_SIGNAL:
193                 case GI_INFO_TYPE_PROPERTY:
194                 case GI_INFO_TYPE_FIELD:
195                 case GI_INFO_TYPE_ARG:
196                 case GI_INFO_TYPE_TYPE:
197                 case GI_INFO_TYPE_UNRESOLVED:
198                   g_warning("Field %s: Interface type %d not expected",
199                             g_base_info_get_name ((GIBaseInfo *)field_info),
200                             g_base_info_get_type (interface));
201                   break;
202                 }
203
204               g_base_info_unref ((GIBaseInfo *)interface);
205               break;
206             }
207             break;
208           }
209       }
210
211     g_base_info_unref ((GIBaseInfo *)type_info);
212
213     return result;
214 }
215
216 /**
217  * g_field_info_set_field:
218  * @field_info: a #GIFieldInfo
219  * @mem: pointer to a block of memory representing a C structure or union
220  * @value: a #GArgument holding the value to store
221  *
222  * Writes a field identified by a #GFieldInfo to a C structure or
223  * union.  This only handles fields of simple C types. It will fail
224  * for a field of a composite type like a nested structure or union
225  * even if that is actually writable. Note also that that it will refuse
226  * to write fields where memory management would by required. A field
227  * with a type such as 'char *' must be set with a setter function.
228  *
229  * Returns: %TRUE if writing the field succeeded, otherwise %FALSE
230  */
231 gboolean
232 g_field_info_set_field (GIFieldInfo     *field_info,
233                         gpointer         mem,
234                         const GArgument *value)
235 {
236     int offset;
237     GITypeInfo *type_info;
238     gboolean result = FALSE;
239
240     if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) == 0)
241       return FALSE;
242
243     offset = g_field_info_get_offset (field_info);
244     type_info = g_field_info_get_type (field_info);
245
246     if (!g_type_info_is_pointer (type_info))
247       {
248         switch (g_type_info_get_tag (type_info))
249           {
250           case GI_TYPE_TAG_VOID:
251             g_warning("Field %s: should not be have void type",
252                       g_base_info_get_name ((GIBaseInfo *)field_info));
253             break;
254           case GI_TYPE_TAG_BOOLEAN:
255             G_STRUCT_MEMBER(gboolean, mem, offset) = value->v_boolean != FALSE;
256             result = TRUE;
257             break;
258           case GI_TYPE_TAG_INT8:
259           case GI_TYPE_TAG_UINT8:
260             G_STRUCT_MEMBER(guint8, mem, offset) = value->v_uint8;
261             result = TRUE;
262             break;
263           case GI_TYPE_TAG_INT16:
264           case GI_TYPE_TAG_UINT16:
265           case GI_TYPE_TAG_SHORT:
266           case GI_TYPE_TAG_USHORT:
267             G_STRUCT_MEMBER(guint16, mem, offset) = value->v_uint16;
268             result = TRUE;
269             break;
270           case GI_TYPE_TAG_INT32:
271           case GI_TYPE_TAG_UINT32:
272           case GI_TYPE_TAG_INT:
273           case GI_TYPE_TAG_UINT:
274             G_STRUCT_MEMBER(guint32, mem, offset) = value->v_uint32;
275             result = TRUE;
276             break;
277           case GI_TYPE_TAG_INT64:
278           case GI_TYPE_TAG_UINT64:
279             G_STRUCT_MEMBER(guint64, mem, offset) = value->v_uint64;
280             result = TRUE;
281             break;
282           case GI_TYPE_TAG_LONG:
283           case GI_TYPE_TAG_ULONG:
284             G_STRUCT_MEMBER(gulong, mem, offset)= value->v_ulong;
285             result = TRUE;
286             break;
287           case GI_TYPE_TAG_SSIZE:
288           case GI_TYPE_TAG_SIZE:
289           case GI_TYPE_TAG_GTYPE:
290             G_STRUCT_MEMBER(gsize, mem, offset) = value->v_size;
291             result = TRUE;
292             break;
293           case GI_TYPE_TAG_FLOAT:
294             G_STRUCT_MEMBER(gfloat, mem, offset) = value->v_float;
295             result = TRUE;
296             break;
297           case GI_TYPE_TAG_DOUBLE:
298             G_STRUCT_MEMBER(gdouble, mem, offset)= value->v_double;
299             result = TRUE;
300             break;
301           case GI_TYPE_TAG_TIME_T:
302 #if SIZEOF_TIME_T == 4
303             G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int32;
304 #elif SIZEOF_TIME_T == 8
305             G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int64;
306 #else
307 #  error "Unexpected size for time_t: not 4 or 8"
308 #endif
309             result = TRUE;
310             break;
311           case GI_TYPE_TAG_UTF8:
312           case GI_TYPE_TAG_FILENAME:
313           case GI_TYPE_TAG_ARRAY:
314           case GI_TYPE_TAG_GLIST:
315           case GI_TYPE_TAG_GSLIST:
316           case GI_TYPE_TAG_GHASH:
317             g_warning("Field %s: type %s should have is_pointer set",
318                       g_base_info_get_name ((GIBaseInfo *)field_info),
319                       g_type_tag_to_string (g_type_info_get_tag (type_info)));
320             break;
321           case GI_TYPE_TAG_ERROR:
322             /* Needs to be handled by the language binding directly */
323             break;
324           case GI_TYPE_TAG_INTERFACE:
325             {
326               GIBaseInfo *interface = g_type_info_get_interface (type_info);
327               switch (g_base_info_get_type (interface))
328                 {
329                 case GI_INFO_TYPE_STRUCT:
330                 case GI_INFO_TYPE_UNION:
331                 case GI_INFO_TYPE_BOXED:
332                   /* Needs to be handled by the language binding directly */
333                   break;
334                 case GI_INFO_TYPE_OBJECT:
335                   break;
336                 case GI_INFO_TYPE_ENUM:
337                 case GI_INFO_TYPE_FLAGS:
338                   {
339                     /* See FIXME above
340                      */
341                     GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface);
342                     switch (storage_type)
343                       {
344                       case GI_TYPE_TAG_INT8:
345                       case GI_TYPE_TAG_UINT8:
346                         G_STRUCT_MEMBER(guint8, mem, offset) = (guint8)value->v_int;
347                         result = TRUE;
348                         break;
349                       case GI_TYPE_TAG_INT16:
350                       case GI_TYPE_TAG_UINT16:
351                       case GI_TYPE_TAG_SHORT:
352                       case GI_TYPE_TAG_USHORT:
353                         G_STRUCT_MEMBER(guint16, mem, offset) = (guint16)value->v_int;
354                         result = TRUE;
355                         break;
356                       case GI_TYPE_TAG_INT32:
357                       case GI_TYPE_TAG_UINT32:
358                       case GI_TYPE_TAG_INT:
359                       case GI_TYPE_TAG_UINT:
360                         G_STRUCT_MEMBER(guint32, mem, offset) = (guint32)value->v_int;
361                         result = TRUE;
362                         break;
363                       case GI_TYPE_TAG_INT64:
364                       case GI_TYPE_TAG_UINT64:
365                         G_STRUCT_MEMBER(guint64, mem, offset) = (guint64)value->v_int;
366                         result = TRUE;
367                         break;
368                       case GI_TYPE_TAG_LONG:
369                       case GI_TYPE_TAG_ULONG:
370                         G_STRUCT_MEMBER(gulong, mem, offset) = (gulong)value->v_int;
371                         result = TRUE;
372                         break;
373                       default:
374                         g_warning("Field %s: Unexpected enum storage type %s",
375                                   g_base_info_get_name ((GIBaseInfo *)field_info),
376                                   g_type_tag_to_string (storage_type));
377                         break;
378                       }
379                     break;
380                   }
381                   break;
382                 case GI_INFO_TYPE_VFUNC:
383                 case GI_INFO_TYPE_CALLBACK:
384                   g_warning("Field%s: Interface type %d should have is_pointer set",
385                             g_base_info_get_name ((GIBaseInfo *)field_info),
386                             g_base_info_get_type (interface));
387                   break;
388                 case GI_INFO_TYPE_INVALID:
389                 case GI_INFO_TYPE_INTERFACE:
390                 case GI_INFO_TYPE_FUNCTION:
391                 case GI_INFO_TYPE_CONSTANT:
392                 case GI_INFO_TYPE_ERROR_DOMAIN:
393                 case GI_INFO_TYPE_VALUE:
394                 case GI_INFO_TYPE_SIGNAL:
395                 case GI_INFO_TYPE_PROPERTY:
396                 case GI_INFO_TYPE_FIELD:
397                 case GI_INFO_TYPE_ARG:
398                 case GI_INFO_TYPE_TYPE:
399                 case GI_INFO_TYPE_UNRESOLVED:
400                   g_warning("Field %s: Interface type %d not expected",
401                             g_base_info_get_name ((GIBaseInfo *)field_info),
402                             g_base_info_get_type (interface));
403                   break;
404                 }
405
406               g_base_info_unref ((GIBaseInfo *)interface);
407               break;
408             }
409             break;
410           }
411       }
412
413     g_base_info_unref ((GIBaseInfo *)type_info);
414
415     return result;
416 }