cd3d97dc14ae03e4cc341c07613f9657fc028b97
[platform/upstream/pygobject2.git] / gi / pygi-info.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * vim: tabstop=4 shiftwidth=4 expandtab
3  *
4  * Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org>
5  *
6  *   pygi-info.c: GI.*Info wrappers.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  */
23
24 #include "pygi-private.h"
25 #include "pygi-cache.h"
26
27 #include <pygobject.h>
28 #include <pyglib-python-compat.h>
29
30 /* BaseInfo */
31
32 static void
33 _base_info_dealloc (PyGIBaseInfo *self)
34 {
35     PyObject_GC_UnTrack ( (PyObject *) self);
36
37     PyObject_ClearWeakRefs ( (PyObject *) self);
38
39     g_base_info_unref (self->info);
40
41     _pygi_callable_cache_free(self->cache);
42
43     Py_TYPE( (PyObject *) self)->tp_free ( (PyObject *) self);
44 }
45
46 static int
47 _base_info_traverse (PyGIBaseInfo *self,
48                      visitproc     visit,
49                      void         *arg)
50 {
51     return 0;
52 }
53
54 static PyObject *
55 _base_info_repr (PyGIBaseInfo *self)
56 {
57     return PYGLIB_PyUnicode_FromFormat ("<%s object (%s) at 0x%p>",
58                                         Py_TYPE( (PyObject *) self)->tp_name, 
59                                         g_base_info_get_name (self->info), 
60                                         (void *) self);
61 }
62
63 static PyObject *
64 _base_info_richcompare (PyGIBaseInfo *self, PyObject *other, int op)
65 {
66     PyObject *res;
67     GIBaseInfo *other_info;
68
69     if (!PyObject_TypeCheck(other, &PyGIBaseInfo_Type)) {
70         Py_INCREF(Py_NotImplemented);
71         return Py_NotImplemented;
72     }
73
74     other_info = ((PyGIBaseInfo *)other)->info;
75
76     switch (op) {
77         case Py_EQ:
78             res = g_base_info_equal (self->info, other_info) ? Py_True : Py_False;
79             break;
80         case Py_NE:
81             res = g_base_info_equal (self->info, other_info) ? Py_False : Py_True;
82             break;
83         default:
84             res = Py_NotImplemented;
85             break;
86     }
87     Py_INCREF(res);
88     return res;
89 }
90
91 static PyMethodDef _PyGIBaseInfo_methods[];
92
93 PYGLIB_DEFINE_TYPE("gi.BaseInfo", PyGIBaseInfo_Type, PyGIBaseInfo);
94
95 static PyObject *
96 _wrap_g_base_info_get_name (PyGIBaseInfo *self)
97 {
98     /* It may be better to use keyword.iskeyword(); keep in sync with
99      * python -c 'import keyword; print(keyword.kwlist)' */
100 #if PY_VERSION_HEX < 0x03000000
101     /* Python 2.x */
102     static const gchar* keywords[] = {"and", "as", "assert", "break", "class",
103         "continue", "def", "del", "elif", "else", "except", "exec", "finally",
104         "for", "from", "global", "if", "import", "in", "is", "lambda", "not",
105         "or", "pass", "print", "raise", "return", "try", "while", "with",
106         "yield", NULL};
107 #elif PY_VERSION_HEX < 0x04000000
108     /* Python 3.x; note that we explicitly keep "print"; it is not a keyword
109      * any more, but we do not want to break API between Python versions */
110     static const gchar* keywords[] = {"False", "None", "True", "and", "as",
111         "assert", "break", "class", "continue", "def", "del", "elif", "else",
112         "except", "finally", "for", "from", "global", "if", "import", "in",
113         "is", "lambda", "nonlocal", "not", "or", "pass", "raise", "return",
114         "try", "while", "with", "yield",
115         "print", NULL};
116 #else
117     #error Need keyword list for this major Python version
118 #endif
119
120     const gchar *name, **i;
121
122     name = g_base_info_get_name (self->info);
123
124     /* escape keywords */
125     for (i = keywords; *i != NULL; ++i) {
126         if (strcmp (name, *i) == 0) {
127             gchar *escaped = g_strconcat (name, "_", NULL);
128             PyObject *obj = PYGLIB_PyUnicode_FromString (escaped);
129             g_free (escaped);
130             return obj;
131         }
132     }
133
134     return PYGLIB_PyUnicode_FromString (name);
135 }
136
137 static PyObject *
138 _wrap_g_base_info_get_name_unescaped (PyGIBaseInfo *self)
139 {
140     return PYGLIB_PyUnicode_FromString (g_base_info_get_name (self->info));
141 }
142
143 static PyObject *
144 _wrap_g_base_info_get_namespace (PyGIBaseInfo *self)
145 {
146     return PYGLIB_PyUnicode_FromString (g_base_info_get_namespace (self->info));
147 }
148
149 static PyObject *
150 _wrap_g_base_info_get_container (PyGIBaseInfo *self)
151 {
152     GIBaseInfo *info;
153
154     info = g_base_info_get_container (self->info);
155
156     if (info == NULL) {
157         Py_RETURN_NONE;
158     }
159
160     return _pygi_info_new (info);
161 }
162
163
164 static PyMethodDef _PyGIBaseInfo_methods[] = {
165     { "get_name", (PyCFunction) _wrap_g_base_info_get_name, METH_NOARGS },
166     { "get_name_unescaped", (PyCFunction) _wrap_g_base_info_get_name_unescaped, METH_NOARGS },
167     { "get_namespace", (PyCFunction) _wrap_g_base_info_get_namespace, METH_NOARGS },
168     { "get_container", (PyCFunction) _wrap_g_base_info_get_container, METH_NOARGS },
169     { NULL, NULL, 0 }
170 };
171
172 PyObject *
173 _pygi_info_new (GIBaseInfo *info)
174 {
175     GIInfoType info_type;
176     PyTypeObject *type = NULL;
177     PyGIBaseInfo *self;
178
179     info_type = g_base_info_get_type (info);
180
181     switch (info_type)
182     {
183         case GI_INFO_TYPE_INVALID:
184             PyErr_SetString (PyExc_RuntimeError, "Invalid info type");
185             return NULL;
186         case GI_INFO_TYPE_FUNCTION:
187             type = &PyGIFunctionInfo_Type;
188             break;
189         case GI_INFO_TYPE_CALLBACK:
190             type = &PyGICallbackInfo_Type;
191             break;
192         case GI_INFO_TYPE_STRUCT:
193             type = &PyGIStructInfo_Type;
194             break;
195         case GI_INFO_TYPE_BOXED:
196             type = &PyGIBoxedInfo_Type;
197             break;
198         case GI_INFO_TYPE_ENUM:
199         case GI_INFO_TYPE_FLAGS:
200             type = &PyGIEnumInfo_Type;
201             break;
202         case GI_INFO_TYPE_OBJECT:
203             type = &PyGIObjectInfo_Type;
204             break;
205         case GI_INFO_TYPE_INTERFACE:
206             type = &PyGIInterfaceInfo_Type;
207             break;
208         case GI_INFO_TYPE_CONSTANT:
209             type = &PyGIConstantInfo_Type;
210             break;
211         case GI_INFO_TYPE_UNION:
212             type = &PyGIUnionInfo_Type;
213             break;
214         case GI_INFO_TYPE_VALUE:
215             type = &PyGIValueInfo_Type;
216             break;
217         case GI_INFO_TYPE_SIGNAL:
218             type = &PyGISignalInfo_Type;
219             break;
220         case GI_INFO_TYPE_VFUNC:
221             type = &PyGIVFuncInfo_Type;
222             break;
223         case GI_INFO_TYPE_PROPERTY:
224             type = &PyGIPropertyInfo_Type;
225             break;
226         case GI_INFO_TYPE_FIELD:
227             type = &PyGIFieldInfo_Type;
228             break;
229         case GI_INFO_TYPE_ARG:
230             type = &PyGIArgInfo_Type;
231             break;
232         case GI_INFO_TYPE_TYPE:
233             type = &PyGITypeInfo_Type;
234             break;
235         case GI_INFO_TYPE_UNRESOLVED:
236             type = &PyGIUnresolvedInfo_Type;
237             break;
238         default:
239             g_assert_not_reached();
240             break;
241     }
242
243     self = (PyGIBaseInfo *) type->tp_alloc (type, 0);
244     if (self == NULL) {
245         return NULL;
246     }
247
248     self->info = g_base_info_ref (info);
249
250     return (PyObject *) self;
251 }
252
253 GIBaseInfo *
254 _pygi_object_get_gi_info (PyObject     *object,
255                           PyTypeObject *type)
256 {
257     PyObject *py_info;
258     GIBaseInfo *info = NULL;
259
260     py_info = PyObject_GetAttrString (object, "__info__");
261     if (py_info == NULL) {
262         return NULL;
263     }
264     if (!PyObject_TypeCheck (py_info, type)) {
265         PyErr_Format (PyExc_TypeError, "attribute '__info__' must be %s, not %s",
266                       type->tp_name, Py_TYPE(&py_info)->tp_name);
267         goto out;
268     }
269
270     info = ( (PyGIBaseInfo *) py_info)->info;
271     g_base_info_ref (info);
272
273 out:
274     Py_DECREF (py_info);
275
276     return info;
277 }
278
279
280 /* CallableInfo */
281 PYGLIB_DEFINE_TYPE ("gi.CallableInfo", PyGICallableInfo_Type, PyGIBaseInfo);
282
283 static PyObject *
284 _wrap_g_callable_info_get_arguments (PyGIBaseInfo *self)
285 {
286     gssize n_infos;
287     PyObject *infos;
288     gssize i;
289
290     n_infos = g_callable_info_get_n_args ( (GICallableInfo *) self->info);
291
292     infos = PyTuple_New (n_infos);
293     if (infos == NULL) {
294         return NULL;
295     }
296
297     for (i = 0; i < n_infos; i++) {
298         GIBaseInfo *info;
299         PyObject *py_info;
300
301         info = (GIBaseInfo *) g_callable_info_get_arg ( (GICallableInfo *) self->info, i);
302         g_assert (info != NULL);
303
304         py_info = _pygi_info_new (info);
305
306         g_base_info_unref (info);
307
308         if (py_info == NULL) {
309             Py_CLEAR (infos);
310             break;
311         }
312
313         PyTuple_SET_ITEM (infos, i, py_info);
314     }
315
316     return infos;
317 }
318
319 static PyMethodDef _PyGICallableInfo_methods[] = {
320     { "invoke", (PyCFunction) _wrap_g_callable_info_invoke, METH_VARARGS | METH_KEYWORDS },
321     { "get_arguments", (PyCFunction) _wrap_g_callable_info_get_arguments, METH_NOARGS },
322     { NULL, NULL, 0 }
323 };
324
325 /* CallbackInfo */
326 PYGLIB_DEFINE_TYPE ("gi.CallbackInfo", PyGICallbackInfo_Type, PyGIBaseInfo);
327
328 static PyMethodDef _PyGICallbackInfo_methods[] = {
329     { NULL, NULL, 0 }
330 };
331
332 /* BoxedInfo */
333 PYGLIB_DEFINE_TYPE ("gi.BoxedInfo", PyGIBoxedInfo_Type, PyGIBaseInfo);
334
335 static PyMethodDef _PyGIBoxedInfo_methods[] = {
336     { NULL, NULL, 0 }
337 };
338
339 /* ErrorDomainInfo */
340 PYGLIB_DEFINE_TYPE ("gi.ErrorDomainInfo", PyGIErrorDomainInfo_Type, PyGIBaseInfo);
341
342 static PyMethodDef _PyGIErrorDomainInfo_methods[] = {
343     { NULL, NULL, 0 }
344 };
345
346 /* SignalInfo */
347 PYGLIB_DEFINE_TYPE ("gi.SignalInfo", PyGISignalInfo_Type, PyGIBaseInfo);
348
349 static PyMethodDef _PyGISignalInfo_methods[] = {
350     { NULL, NULL, 0 }
351 };
352
353 /* PropertyInfo */
354 PYGLIB_DEFINE_TYPE ("gi.PropertyInfo", PyGIPropertyInfo_Type, PyGIBaseInfo);
355
356 static PyMethodDef _PyGIPropertyInfo_methods[] = {
357     { NULL, NULL, 0 }
358 };
359
360
361 /* ArgInfo */
362 PYGLIB_DEFINE_TYPE ("gi.ArgInfo", PyGIArgInfo_Type, PyGIBaseInfo);
363
364 static PyObject *
365 _wrap_g_arg_info_get_direction (PyGIBaseInfo *self)
366 {
367     return PyLong_FromLong (
368             g_arg_info_get_direction ((GIArgInfo*)self->info) );
369 }
370
371 static PyObject *
372 _wrap_g_arg_info_is_caller_allocates (PyGIBaseInfo *self)
373 {
374     return PyBool_FromLong (
375             g_arg_info_is_caller_allocates ((GIArgInfo*)self->info) );
376 }
377
378 static PyObject *
379 _wrap_g_arg_info_is_return_value (PyGIBaseInfo *self)
380 {
381     return PyBool_FromLong (
382             g_arg_info_is_return_value ((GIArgInfo*)self->info) );
383 }
384
385 static PyObject *
386 _wrap_g_arg_info_is_optional (PyGIBaseInfo *self)
387 {
388     return PyBool_FromLong (
389             g_arg_info_is_optional ((GIArgInfo*)self->info) );
390 }
391
392 static PyObject *
393 _wrap_g_arg_info_may_be_null (PyGIBaseInfo *self)
394 {
395     return PyBool_FromLong (
396             g_arg_info_may_be_null ((GIArgInfo*)self->info) );
397 }
398
399 /* _g_arg_get_pytype_hint
400  *
401  * Returns new value reference to a string hinting at the python type
402  * which can be used for the given gi argument info.
403  */
404 static PyObject *
405 _g_arg_get_pytype_hint (PyGIBaseInfo *self)
406 {
407     GIArgInfo *arg_info = (GIArgInfo*)self->info;
408     GITypeInfo type_info;
409     g_arg_info_load_type(arg_info, &type_info);
410     GITypeTag type_tag = g_type_info_get_tag(&type_info);
411
412     /* First attempt getting a python type object. */
413     PyObject *py_type = _pygi_get_py_type_hint(type_tag);
414     if (py_type != Py_None && PyObject_HasAttrString(py_type, "__name__")) {
415         PyObject *name = PyObject_GetAttrString(py_type, "__name__");
416         Py_DecRef(py_type);
417         return name;
418     } else {
419         Py_DecRef(py_type);
420         if (type_tag == GI_TYPE_TAG_INTERFACE) {
421             GIBaseInfo *iface = g_type_info_get_interface(&type_info);
422             gchar *name = g_strdup_printf("%s.%s",
423                     g_base_info_get_namespace(iface),
424                     g_base_info_get_name (iface));
425             g_base_info_unref(iface);
426             PyObject *py_string = PYGLIB_PyUnicode_FromString(name);
427             g_free(name);
428             return py_string;
429         }
430         return PYGLIB_PyUnicode_FromString(g_type_tag_to_string(type_tag));
431     }
432 }
433
434 static PyMethodDef _PyGIArgInfo_methods[] = {
435     { "get_direction", (PyCFunction) _wrap_g_arg_info_get_direction, METH_NOARGS },
436     { "is_caller_allocates", (PyCFunction) _wrap_g_arg_info_is_caller_allocates, METH_NOARGS },
437     { "is_return_value", (PyCFunction) _wrap_g_arg_info_is_return_value, METH_NOARGS },
438     { "is_optional", (PyCFunction) _wrap_g_arg_info_is_optional, METH_NOARGS },
439     { "may_be_null", (PyCFunction) _wrap_g_arg_info_may_be_null, METH_NOARGS },
440     { "get_pytype_hint", (PyCFunction) _g_arg_get_pytype_hint, METH_NOARGS },
441     { NULL, NULL, 0 }
442 };
443
444
445 /* TypeInfo */
446 PYGLIB_DEFINE_TYPE ("gi.TypeInfo", PyGITypeInfo_Type, PyGIBaseInfo);
447
448 static PyMethodDef _PyGITypeInfo_methods[] = {
449     { NULL, NULL, 0 }
450 };
451
452
453 /* FunctionInfo */
454 PYGLIB_DEFINE_TYPE ("gi.FunctionInfo", PyGIFunctionInfo_Type, PyGIBaseInfo);
455
456 static PyObject *
457 _wrap_g_function_info_is_constructor (PyGIBaseInfo *self)
458 {
459     GIFunctionInfoFlags flags;
460     gboolean is_constructor;
461
462     flags = g_function_info_get_flags ( (GIFunctionInfo*) self->info);
463     is_constructor = flags & GI_FUNCTION_IS_CONSTRUCTOR;
464
465     return PyBool_FromLong (is_constructor);
466 }
467
468 static PyObject *
469 _wrap_g_function_info_is_method (PyGIBaseInfo *self)
470 {
471     GIFunctionInfoFlags flags;
472     gboolean is_method;
473
474     flags = g_function_info_get_flags ( (GIFunctionInfo*) self->info);
475     is_method = flags & GI_FUNCTION_IS_METHOD;
476
477     return PyBool_FromLong (is_method);
478 }
479
480 gsize
481 _pygi_g_type_tag_size (GITypeTag type_tag)
482 {
483     gsize size = 0;
484
485     switch (type_tag) {
486         case GI_TYPE_TAG_BOOLEAN:
487             size = sizeof (gboolean);
488             break;
489         case GI_TYPE_TAG_INT8:
490         case GI_TYPE_TAG_UINT8:
491             size = sizeof (gint8);
492             break;
493         case GI_TYPE_TAG_INT16:
494         case GI_TYPE_TAG_UINT16:
495             size = sizeof (gint16);
496             break;
497         case GI_TYPE_TAG_INT32:
498         case GI_TYPE_TAG_UINT32:
499             size = sizeof (gint32);
500             break;
501         case GI_TYPE_TAG_INT64:
502         case GI_TYPE_TAG_UINT64:
503             size = sizeof (gint64);
504             break;
505         case GI_TYPE_TAG_FLOAT:
506             size = sizeof (gfloat);
507             break;
508         case GI_TYPE_TAG_DOUBLE:
509             size = sizeof (gdouble);
510             break;
511         case GI_TYPE_TAG_GTYPE:
512             size = sizeof (GType);
513             break;
514         case GI_TYPE_TAG_UNICHAR:
515             size = sizeof (gunichar);
516             break;
517         case GI_TYPE_TAG_VOID:
518         case GI_TYPE_TAG_UTF8:
519         case GI_TYPE_TAG_FILENAME:
520         case GI_TYPE_TAG_ARRAY:
521         case GI_TYPE_TAG_INTERFACE:
522         case GI_TYPE_TAG_GLIST:
523         case GI_TYPE_TAG_GSLIST:
524         case GI_TYPE_TAG_GHASH:
525         case GI_TYPE_TAG_ERROR:
526             PyErr_Format (PyExc_TypeError,
527                           "Unable to know the size (assuming %s is not a pointer)",
528                           g_type_tag_to_string (type_tag));
529             break;
530     }
531
532     return size;
533 }
534
535 gsize
536 _pygi_g_type_info_size (GITypeInfo *type_info)
537 {
538     gsize size = 0;
539
540     GITypeTag type_tag;
541
542     type_tag = g_type_info_get_tag (type_info);
543     switch (type_tag) {
544         case GI_TYPE_TAG_BOOLEAN:
545         case GI_TYPE_TAG_INT8:
546         case GI_TYPE_TAG_UINT8:
547         case GI_TYPE_TAG_INT16:
548         case GI_TYPE_TAG_UINT16:
549         case GI_TYPE_TAG_INT32:
550         case GI_TYPE_TAG_UINT32:
551         case GI_TYPE_TAG_INT64:
552         case GI_TYPE_TAG_UINT64:
553         case GI_TYPE_TAG_FLOAT:
554         case GI_TYPE_TAG_DOUBLE:
555         case GI_TYPE_TAG_GTYPE:
556         case GI_TYPE_TAG_UNICHAR:
557             size = _pygi_g_type_tag_size (type_tag);
558             g_assert (size > 0);
559             break;
560         case GI_TYPE_TAG_INTERFACE:
561         {
562             GIBaseInfo *info;
563             GIInfoType info_type;
564
565             info = g_type_info_get_interface (type_info);
566             info_type = g_base_info_get_type (info);
567
568             switch (info_type) {
569                 case GI_INFO_TYPE_STRUCT:
570                     if (g_type_info_is_pointer (type_info)) {
571                         size = sizeof (gpointer);
572                     } else {
573                         size = g_struct_info_get_size ( (GIStructInfo *) info);
574                     }
575                     break;
576                 case GI_INFO_TYPE_UNION:
577                     if (g_type_info_is_pointer (type_info)) {
578                         size = sizeof (gpointer);
579                     } else {
580                         size = g_union_info_get_size ( (GIUnionInfo *) info);
581                     }
582                     break;
583                 case GI_INFO_TYPE_ENUM:
584                 case GI_INFO_TYPE_FLAGS:
585                     if (g_type_info_is_pointer (type_info)) {
586                         size = sizeof (gpointer);
587                     } else {
588                         GITypeTag type_tag;
589
590                         type_tag = g_enum_info_get_storage_type ( (GIEnumInfo *) info);
591                         size = _pygi_g_type_tag_size (type_tag);
592                     }
593                     break;
594                 case GI_INFO_TYPE_BOXED:
595                 case GI_INFO_TYPE_OBJECT:
596                 case GI_INFO_TYPE_INTERFACE:
597                 case GI_INFO_TYPE_CALLBACK:
598                     size = sizeof (gpointer);
599                     break;
600                 case GI_INFO_TYPE_VFUNC:
601                 case GI_INFO_TYPE_INVALID:
602                 case GI_INFO_TYPE_FUNCTION:
603                 case GI_INFO_TYPE_CONSTANT:
604                 case GI_INFO_TYPE_VALUE:
605                 case GI_INFO_TYPE_SIGNAL:
606                 case GI_INFO_TYPE_PROPERTY:
607                 case GI_INFO_TYPE_FIELD:
608                 case GI_INFO_TYPE_ARG:
609                 case GI_INFO_TYPE_TYPE:
610                 case GI_INFO_TYPE_UNRESOLVED:
611                 default:
612                     g_assert_not_reached();
613                     break;
614             }
615
616             g_base_info_unref (info);
617             break;
618         }
619         case GI_TYPE_TAG_ARRAY:
620         case GI_TYPE_TAG_VOID:
621         case GI_TYPE_TAG_UTF8:
622         case GI_TYPE_TAG_FILENAME:
623         case GI_TYPE_TAG_GLIST:
624         case GI_TYPE_TAG_GSLIST:
625         case GI_TYPE_TAG_GHASH:
626         case GI_TYPE_TAG_ERROR:
627             size = sizeof (gpointer);
628             break;
629     }
630
631     return size;
632 }
633
634 static PyMethodDef _PyGIFunctionInfo_methods[] = {
635     { "is_constructor", (PyCFunction) _wrap_g_function_info_is_constructor, METH_NOARGS },
636     { "is_method", (PyCFunction) _wrap_g_function_info_is_method, METH_NOARGS },
637     { NULL, NULL, 0 }
638 };
639
640
641 /* RegisteredTypeInfo */
642 PYGLIB_DEFINE_TYPE ("gi.RegisteredTypeInfo", PyGIRegisteredTypeInfo_Type, PyGIBaseInfo);
643
644 static PyObject *
645 _wrap_g_registered_type_info_get_g_type (PyGIBaseInfo *self)
646 {
647     GType type;
648
649     type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) self->info);
650
651     return pyg_type_wrapper_new (type);
652 }
653
654 static PyMethodDef _PyGIRegisteredTypeInfo_methods[] = {
655     { "get_g_type", (PyCFunction) _wrap_g_registered_type_info_get_g_type, METH_NOARGS },
656     { NULL, NULL, 0 }
657 };
658
659
660 /* GIStructInfo */
661 PYGLIB_DEFINE_TYPE ("StructInfo", PyGIStructInfo_Type, PyGIBaseInfo);
662
663 static PyObject *
664 _get_fields (PyGIBaseInfo *self, GIInfoType info_type)
665 {
666     gssize n_infos;
667     PyObject *infos;
668     gssize i;
669
670     switch (info_type) {
671         case GI_INFO_TYPE_STRUCT:
672             n_infos = g_struct_info_get_n_fields ( (GIStructInfo *) self->info);
673             break;
674         case GI_INFO_TYPE_OBJECT:
675             n_infos = g_object_info_get_n_fields ( (GIObjectInfo *) self->info);
676             break;
677         default:
678             g_assert_not_reached();
679     }
680
681     infos = PyTuple_New (n_infos);
682     if (infos == NULL) {
683         return NULL;
684     }
685
686     for (i = 0; i < n_infos; i++) {
687         GIBaseInfo *info;
688         PyObject *py_info;
689
690         switch (info_type) {
691             case GI_INFO_TYPE_STRUCT:
692                 info = (GIBaseInfo *) g_struct_info_get_field ( (GIStructInfo *) self->info, i);
693                 break;
694             case GI_INFO_TYPE_OBJECT:
695                 info = (GIBaseInfo *) g_object_info_get_field ( (GIObjectInfo *) self->info, i);
696                 break;
697             default:
698                 g_assert_not_reached();
699         }
700         g_assert (info != NULL);
701
702         py_info = _pygi_info_new (info);
703
704         g_base_info_unref (info);
705
706         if (py_info == NULL) {
707             Py_CLEAR (infos);
708             break;
709         }
710
711         PyTuple_SET_ITEM (infos, i, py_info);
712     }
713
714     return infos;
715 }
716
717 static PyObject *
718 _get_methods (PyGIBaseInfo *self, GIInfoType info_type)
719 {
720     gssize n_infos;
721     PyObject *infos;
722     gssize i;
723
724     switch (info_type) {
725         case GI_INFO_TYPE_STRUCT:
726             n_infos = g_struct_info_get_n_methods ( (GIStructInfo *) self->info);
727             break;
728         case GI_INFO_TYPE_OBJECT:
729             n_infos = g_object_info_get_n_methods ( (GIObjectInfo *) self->info);
730             break;
731         default:
732             g_assert_not_reached();
733     }
734
735     infos = PyTuple_New (n_infos);
736     if (infos == NULL) {
737         return NULL;
738     }
739
740     for (i = 0; i < n_infos; i++) {
741         GIBaseInfo *info;
742         PyObject *py_info;
743
744         switch (info_type) {
745             case GI_INFO_TYPE_STRUCT:
746                 info = (GIBaseInfo *) g_struct_info_get_method ( (GIStructInfo *) self->info, i);
747                 break;
748             case GI_INFO_TYPE_OBJECT:
749                 info = (GIBaseInfo *) g_object_info_get_method ( (GIObjectInfo *) self->info, i);
750                 break;
751             default:
752                 g_assert_not_reached();
753         }
754         g_assert (info != NULL);
755
756         py_info = _pygi_info_new (info);
757
758         g_base_info_unref (info);
759
760         if (py_info == NULL) {
761             Py_CLEAR (infos);
762             break;
763         }
764
765         PyTuple_SET_ITEM (infos, i, py_info);
766     }
767
768     return infos;
769 }
770
771 static PyObject *
772 _get_constants (PyGIBaseInfo *self, GIInfoType info_type)
773 {
774     gssize n_infos;
775     PyObject *infos;
776     gssize i;
777
778     switch (info_type) {
779         case GI_INFO_TYPE_INTERFACE:
780             n_infos = g_interface_info_get_n_constants ( (GIInterfaceInfo *) self->info);
781             break;
782         case GI_INFO_TYPE_OBJECT:
783             n_infos = g_object_info_get_n_constants ( (GIObjectInfo *) self->info);
784             break;
785         default:
786             g_assert_not_reached();
787     }
788
789     infos = PyTuple_New (n_infos);
790     if (infos == NULL) {
791         return NULL;
792     }
793
794     for (i = 0; i < n_infos; i++) {
795         GIBaseInfo *info;
796         PyObject *py_info;
797
798         switch (info_type) {
799             case GI_INFO_TYPE_INTERFACE:
800                 info = (GIBaseInfo *) g_interface_info_get_constant ( (GIInterfaceInfo *) self->info, i);
801                 break;
802             case GI_INFO_TYPE_OBJECT:
803                 info = (GIBaseInfo *) g_object_info_get_constant ( (GIObjectInfo *) self->info, i);
804                 break;
805             default:
806                 g_assert_not_reached();
807         }
808         g_assert (info != NULL);
809
810         py_info = _pygi_info_new (info);
811
812         g_base_info_unref (info);
813
814         if (py_info == NULL) {
815             Py_CLEAR (infos);
816             break;
817         }
818
819         PyTuple_SET_ITEM (infos, i, py_info);
820     }
821
822     return infos;
823 }
824
825 static PyObject *
826 _get_vfuncs (PyGIBaseInfo *self, GIInfoType info_type)
827 {
828     gssize n_infos;
829     PyObject *infos;
830     gssize i;
831
832     switch (info_type) {
833         case GI_INFO_TYPE_INTERFACE:
834             n_infos = g_interface_info_get_n_vfuncs ( (GIInterfaceInfo *) self->info);
835             break;
836         case GI_INFO_TYPE_OBJECT:
837             n_infos = g_object_info_get_n_vfuncs ( (GIObjectInfo *) self->info);
838             break;
839         default:
840             g_assert_not_reached();
841     }
842
843     infos = PyTuple_New (n_infos);
844     if (infos == NULL) {
845         return NULL;
846     }
847
848     for (i = 0; i < n_infos; i++) {
849         GIBaseInfo *info;
850         PyObject *py_info;
851
852         switch (info_type) {
853             case GI_INFO_TYPE_INTERFACE:
854                 info = (GIBaseInfo *) g_interface_info_get_vfunc ( (GIInterfaceInfo *) self->info, i);
855                 break;
856             case GI_INFO_TYPE_OBJECT:
857                 info = (GIBaseInfo *) g_object_info_get_vfunc ( (GIObjectInfo *) self->info, i);
858                 break;
859             default:
860                 g_assert_not_reached();
861         }
862         g_assert (info != NULL);
863
864         py_info = _pygi_info_new (info);
865
866         g_base_info_unref (info);
867
868         if (py_info == NULL) {
869             Py_CLEAR (infos);
870             break;
871         }
872
873         PyTuple_SET_ITEM (infos, i, py_info);
874     }
875
876     return infos;
877 }
878
879 static PyObject *
880 _wrap_g_struct_info_get_fields (PyGIBaseInfo *self)
881 {
882     return _get_fields (self, GI_INFO_TYPE_STRUCT);
883 }
884
885 static PyObject *
886 _wrap_g_struct_info_get_methods (PyGIBaseInfo *self)
887 {
888     return _get_methods (self, GI_INFO_TYPE_STRUCT);
889 }
890
891 static PyMethodDef _PyGIStructInfo_methods[] = {
892     { "get_fields", (PyCFunction) _wrap_g_struct_info_get_fields, METH_NOARGS },
893     { "get_methods", (PyCFunction) _wrap_g_struct_info_get_methods, METH_NOARGS },
894     { NULL, NULL, 0 }
895 };
896
897 gboolean
898 pygi_g_struct_info_is_simple (GIStructInfo *struct_info)
899 {
900     gboolean is_simple;
901     gsize n_field_infos;
902     gsize i;
903
904     is_simple = TRUE;
905
906     n_field_infos = g_struct_info_get_n_fields (struct_info);
907
908     for (i = 0; i < n_field_infos && is_simple; i++) {
909         GIFieldInfo *field_info;
910         GITypeInfo *field_type_info;
911
912         field_info = g_struct_info_get_field (struct_info, i);
913         field_type_info = g_field_info_get_type (field_info);
914
915         GITypeTag field_type_tag;
916
917         field_type_tag = g_type_info_get_tag (field_type_info);
918
919         switch (field_type_tag) {
920             case GI_TYPE_TAG_BOOLEAN:
921             case GI_TYPE_TAG_INT8:
922             case GI_TYPE_TAG_UINT8:
923             case GI_TYPE_TAG_INT16:
924             case GI_TYPE_TAG_UINT16:
925             case GI_TYPE_TAG_INT32:
926             case GI_TYPE_TAG_UINT32:
927             case GI_TYPE_TAG_INT64:
928             case GI_TYPE_TAG_UINT64:
929             case GI_TYPE_TAG_FLOAT:
930             case GI_TYPE_TAG_DOUBLE:
931             case GI_TYPE_TAG_UNICHAR:
932                 if (g_type_info_is_pointer (field_type_info)) {
933                     is_simple = FALSE;
934                 }
935                 break;
936             case GI_TYPE_TAG_VOID:
937             case GI_TYPE_TAG_GTYPE:
938             case GI_TYPE_TAG_ERROR:
939             case GI_TYPE_TAG_UTF8:
940             case GI_TYPE_TAG_FILENAME:
941             case GI_TYPE_TAG_ARRAY:
942             case GI_TYPE_TAG_GLIST:
943             case GI_TYPE_TAG_GSLIST:
944             case GI_TYPE_TAG_GHASH:
945                 is_simple = FALSE;
946                 break;
947             case GI_TYPE_TAG_INTERFACE:
948             {
949                 GIBaseInfo *info;
950                 GIInfoType info_type;
951
952                 info = g_type_info_get_interface (field_type_info);
953                 info_type = g_base_info_get_type (info);
954
955                 switch (info_type) {
956                     case GI_INFO_TYPE_STRUCT:
957                         if (g_type_info_is_pointer (field_type_info)) {
958                             is_simple = FALSE;
959                         } else {
960                             is_simple = pygi_g_struct_info_is_simple ( (GIStructInfo *) info);
961                         }
962                         break;
963                     case GI_INFO_TYPE_UNION:
964                         /* TODO */
965                         is_simple = FALSE;
966                         break;
967                     case GI_INFO_TYPE_ENUM:
968                     case GI_INFO_TYPE_FLAGS:
969                         if (g_type_info_is_pointer (field_type_info)) {
970                             is_simple = FALSE;
971                         }
972                         break;
973                     case GI_INFO_TYPE_BOXED:
974                     case GI_INFO_TYPE_OBJECT:
975                     case GI_INFO_TYPE_CALLBACK:
976                     case GI_INFO_TYPE_INTERFACE:
977                         is_simple = FALSE;
978                         break;
979                     case GI_INFO_TYPE_VFUNC:
980                     case GI_INFO_TYPE_INVALID:
981                     case GI_INFO_TYPE_FUNCTION:
982                     case GI_INFO_TYPE_CONSTANT:
983                     case GI_INFO_TYPE_VALUE:
984                     case GI_INFO_TYPE_SIGNAL:
985                     case GI_INFO_TYPE_PROPERTY:
986                     case GI_INFO_TYPE_FIELD:
987                     case GI_INFO_TYPE_ARG:
988                     case GI_INFO_TYPE_TYPE:
989                     case GI_INFO_TYPE_UNRESOLVED:
990                     default:
991                         g_assert_not_reached();
992                         break;
993                 }
994
995                 g_base_info_unref (info);
996                 break;
997             }
998         }
999
1000         g_base_info_unref ( (GIBaseInfo *) field_type_info);
1001         g_base_info_unref ( (GIBaseInfo *) field_info);
1002     }
1003
1004     return is_simple;
1005 }
1006
1007
1008 /* EnumInfo */
1009 PYGLIB_DEFINE_TYPE ("gi.EnumInfo", PyGIEnumInfo_Type, PyGIBaseInfo);
1010
1011 static PyObject *
1012 _wrap_g_enum_info_get_values (PyGIBaseInfo *self)
1013 {
1014     gssize n_infos;
1015     PyObject *infos;
1016     gssize i;
1017
1018     n_infos = g_enum_info_get_n_values ( (GIEnumInfo *) self->info);
1019
1020     infos = PyTuple_New (n_infos);
1021     if (infos == NULL) {
1022         return NULL;
1023     }
1024
1025     for (i = 0; i < n_infos; i++) {
1026         GIBaseInfo *info;
1027         PyObject *py_info;
1028
1029         info = (GIBaseInfo *) g_enum_info_get_value ( (GIEnumInfo *) self->info, i);
1030         g_assert (info != NULL);
1031
1032         py_info = _pygi_info_new (info);
1033
1034         g_base_info_unref (info);
1035
1036         if (py_info == NULL) {
1037             Py_CLEAR (infos);
1038             break;
1039         }
1040
1041         PyTuple_SET_ITEM (infos, i, py_info);
1042     }
1043
1044     return infos;
1045 }
1046
1047 static PyObject *
1048 _wrap_g_enum_info_is_flags (PyGIBaseInfo *self)
1049 {
1050     GIInfoType info_type = g_base_info_get_type ((GIBaseInfo *) self->info);
1051
1052     if (info_type == GI_INFO_TYPE_ENUM) {
1053         Py_RETURN_FALSE;
1054     } else if (info_type == GI_INFO_TYPE_FLAGS) {
1055         Py_RETURN_TRUE;
1056     } else {
1057         g_assert_not_reached();
1058     }
1059 }
1060
1061 static PyMethodDef _PyGIEnumInfo_methods[] = {
1062     { "get_values", (PyCFunction) _wrap_g_enum_info_get_values, METH_NOARGS },
1063     { "is_flags", (PyCFunction) _wrap_g_enum_info_is_flags, METH_NOARGS },
1064     { NULL, NULL, 0 }
1065 };
1066
1067
1068 /* ObjectInfo */
1069 PYGLIB_DEFINE_TYPE ("ObjectInfo", PyGIObjectInfo_Type, PyGIBaseInfo);
1070
1071 static PyObject *
1072 _wrap_g_object_info_get_parent (PyGIBaseInfo *self)
1073 {
1074     GIBaseInfo *info;
1075     PyObject *py_info;
1076
1077     info = (GIBaseInfo *) g_object_info_get_parent ( (GIObjectInfo*) self->info);
1078
1079     if (info == NULL) {
1080         Py_RETURN_NONE;
1081     }
1082
1083     py_info = _pygi_info_new (info);
1084
1085     g_base_info_unref (info);
1086
1087     return py_info;
1088 }
1089
1090 static PyObject *
1091 _wrap_g_object_info_get_methods (PyGIBaseInfo *self)
1092 {
1093     return _get_methods (self, GI_INFO_TYPE_OBJECT);
1094 }
1095
1096 static PyObject *
1097 _wrap_g_object_info_get_fields (PyGIBaseInfo *self)
1098 {
1099     return _get_fields (self, GI_INFO_TYPE_OBJECT);
1100 }
1101
1102 static PyObject *
1103 _wrap_g_object_info_get_interfaces (PyGIBaseInfo *self)
1104 {
1105     gssize n_infos;
1106     PyObject *infos;
1107     gssize i;
1108
1109     n_infos = g_object_info_get_n_interfaces ( (GIObjectInfo *) self->info);
1110
1111     infos = PyTuple_New (n_infos);
1112     if (infos == NULL) {
1113         return NULL;
1114     }
1115
1116     for (i = 0; i < n_infos; i++) {
1117         GIBaseInfo *info;
1118         PyObject *py_info;
1119
1120         info = (GIBaseInfo *) g_object_info_get_interface ( (GIObjectInfo *) self->info, i);
1121         g_assert (info != NULL);
1122
1123         py_info = _pygi_info_new (info);
1124
1125         g_base_info_unref (info);
1126
1127         if (py_info == NULL) {
1128             Py_CLEAR (infos);
1129             break;
1130         }
1131
1132         PyTuple_SET_ITEM (infos, i, py_info);
1133     }
1134
1135     return infos;
1136 }
1137
1138 static PyObject *
1139 _wrap_g_object_info_get_constants (PyGIBaseInfo *self)
1140 {
1141     return _get_constants (self, GI_INFO_TYPE_OBJECT);
1142 }
1143
1144 static PyObject *
1145 _wrap_g_object_info_get_vfuncs (PyGIBaseInfo *self)
1146 {
1147     return _get_vfuncs (self, GI_INFO_TYPE_OBJECT);
1148 }
1149
1150 static PyObject *
1151 _wrap_g_object_info_get_abstract (PyGIBaseInfo *self)
1152 {
1153     gboolean is_abstract  = g_object_info_get_abstract ( (GIObjectInfo*) self->info);
1154     return PyBool_FromLong (is_abstract);
1155 }
1156
1157 static PyMethodDef _PyGIObjectInfo_methods[] = {
1158     { "get_parent", (PyCFunction) _wrap_g_object_info_get_parent, METH_NOARGS },
1159     { "get_methods", (PyCFunction) _wrap_g_object_info_get_methods, METH_NOARGS },
1160     { "get_fields", (PyCFunction) _wrap_g_object_info_get_fields, METH_NOARGS },
1161     { "get_interfaces", (PyCFunction) _wrap_g_object_info_get_interfaces, METH_NOARGS },
1162     { "get_constants", (PyCFunction) _wrap_g_object_info_get_constants, METH_NOARGS },
1163     { "get_vfuncs", (PyCFunction) _wrap_g_object_info_get_vfuncs, METH_NOARGS },
1164     { "get_abstract", (PyCFunction) _wrap_g_object_info_get_abstract, METH_NOARGS },
1165     { NULL, NULL, 0 }
1166 };
1167
1168
1169 /* GIInterfaceInfo */
1170 PYGLIB_DEFINE_TYPE ("InterfaceInfo", PyGIInterfaceInfo_Type, PyGIBaseInfo);
1171
1172 static PyObject *
1173 _wrap_g_interface_info_get_methods (PyGIBaseInfo *self)
1174 {
1175     gssize n_infos;
1176     PyObject *infos;
1177     gssize i;
1178
1179     n_infos = g_interface_info_get_n_methods ( (GIInterfaceInfo *) self->info);
1180
1181     infos = PyTuple_New (n_infos);
1182     if (infos == NULL) {
1183         return NULL;
1184     }
1185
1186     for (i = 0; i < n_infos; i++) {
1187         GIBaseInfo *info;
1188         PyObject *py_info;
1189
1190         info = (GIBaseInfo *) g_interface_info_get_method ( (GIInterfaceInfo *) self->info, i);
1191         g_assert (info != NULL);
1192
1193         py_info = _pygi_info_new (info);
1194
1195         g_base_info_unref (info);
1196
1197         if (py_info == NULL) {
1198             Py_CLEAR (infos);
1199             break;
1200         }
1201
1202         PyTuple_SET_ITEM (infos, i, py_info);
1203     }
1204
1205     return infos;
1206 }
1207
1208 static PyObject *
1209 _wrap_g_interface_info_get_constants (PyGIBaseInfo *self)
1210 {
1211     return _get_constants (self, GI_INFO_TYPE_INTERFACE);
1212 }
1213
1214 static PyObject *
1215 _wrap_g_interface_info_get_vfuncs (PyGIBaseInfo *self)
1216 {
1217     return _get_vfuncs (self, GI_INFO_TYPE_INTERFACE);
1218 }
1219
1220 static PyMethodDef _PyGIInterfaceInfo_methods[] = {
1221     { "get_methods", (PyCFunction) _wrap_g_interface_info_get_methods, METH_NOARGS },
1222     { "get_constants", (PyCFunction) _wrap_g_interface_info_get_constants, METH_NOARGS },
1223     { "get_vfuncs", (PyCFunction) _wrap_g_interface_info_get_vfuncs, METH_NOARGS },
1224     { NULL, NULL, 0 }
1225 };
1226
1227 /* GIConstantInfo */
1228 PYGLIB_DEFINE_TYPE ("gi.ConstantInfo", PyGIConstantInfo_Type, PyGIBaseInfo);
1229
1230 static PyObject *
1231 _wrap_g_constant_info_get_value (PyGIBaseInfo *self)
1232 {
1233     GITypeInfo *type_info;
1234     GIArgument value;
1235     PyObject *py_value;
1236     gboolean free_array = FALSE;
1237
1238     if (g_constant_info_get_value ( (GIConstantInfo *) self->info, &value) < 0) {
1239         PyErr_SetString (PyExc_RuntimeError, "unable to get value");
1240         return NULL;
1241     }
1242
1243     type_info = g_constant_info_get_type ( (GIConstantInfo *) self->info);
1244
1245     if (g_type_info_get_tag (type_info) == GI_TYPE_TAG_ARRAY) {
1246         value.v_pointer = _pygi_argument_to_array (&value, NULL, NULL,
1247                                                    type_info, &free_array);
1248     }
1249
1250     py_value = _pygi_argument_to_object (&value, type_info, GI_TRANSFER_NOTHING);
1251     
1252     if (free_array) {
1253         g_array_free (value.v_pointer, FALSE);
1254     }
1255
1256     g_constant_info_free_value (self->info, &value);
1257     g_base_info_unref ( (GIBaseInfo *) type_info);
1258
1259     return py_value;
1260 }
1261
1262 static PyMethodDef _PyGIConstantInfo_methods[] = {
1263     { "get_value", (PyCFunction) _wrap_g_constant_info_get_value, METH_NOARGS },
1264     { NULL, NULL, 0 }
1265 };
1266
1267 /* GIValueInfo */
1268 PYGLIB_DEFINE_TYPE ("gi.ValueInfo", PyGIValueInfo_Type, PyGIBaseInfo);
1269
1270 static PyObject *
1271 _wrap_g_value_info_get_value (PyGIBaseInfo *self)
1272 {
1273     glong value;
1274
1275     value = g_value_info_get_value ( (GIValueInfo *) self->info);
1276
1277     return PYGLIB_PyLong_FromLong (value);
1278 }
1279
1280
1281 static PyMethodDef _PyGIValueInfo_methods[] = {
1282     { "get_value", (PyCFunction) _wrap_g_value_info_get_value, METH_NOARGS },
1283     { NULL, NULL, 0 }
1284 };
1285
1286
1287 /* GIFieldInfo */
1288 PYGLIB_DEFINE_TYPE ("gi.FieldInfo", PyGIFieldInfo_Type, PyGIBaseInfo);
1289
1290 static PyObject *
1291 _wrap_g_field_info_get_value (PyGIBaseInfo *self,
1292                               PyObject     *args)
1293 {
1294     PyObject *instance;
1295     GIBaseInfo *container_info;
1296     GIInfoType container_info_type;
1297     gpointer pointer;
1298     GITypeInfo *field_type_info;
1299     GIArgument value;
1300     PyObject *py_value = NULL;
1301     gboolean free_array = FALSE;
1302
1303     memset(&value, 0, sizeof(GIArgument));
1304
1305     if (!PyArg_ParseTuple (args, "O:FieldInfo.get_value", &instance)) {
1306         return NULL;
1307     }
1308
1309     container_info = g_base_info_get_container (self->info);
1310     g_assert (container_info != NULL);
1311
1312     /* Check the instance. */
1313     if (!_pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) container_info, TRUE, instance)) {
1314         _PyGI_ERROR_PREFIX ("argument 1: ");
1315         return NULL;
1316     }
1317
1318     /* Get the pointer to the container. */
1319     container_info_type = g_base_info_get_type (container_info);
1320     switch (container_info_type) {
1321         case GI_INFO_TYPE_UNION:
1322         case GI_INFO_TYPE_STRUCT:
1323             pointer = pyg_boxed_get (instance, void);
1324             break;
1325         case GI_INFO_TYPE_OBJECT:
1326             pointer = pygobject_get (instance);
1327             break;
1328         default:
1329             /* Other types don't have fields. */
1330             g_assert_not_reached();
1331     }
1332
1333     /* Get the field's value. */
1334     field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info);
1335
1336     /* A few types are not handled by g_field_info_get_field, so do it here. */
1337     if (!g_type_info_is_pointer (field_type_info)
1338             && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) {
1339         GIBaseInfo *info;
1340         GIInfoType info_type;
1341
1342         if (! (g_field_info_get_flags ( (GIFieldInfo *) self->info) & GI_FIELD_IS_READABLE)) {
1343             PyErr_SetString (PyExc_RuntimeError, "field is not readable");
1344             goto out;
1345         }
1346
1347         info = g_type_info_get_interface (field_type_info);
1348
1349         info_type = g_base_info_get_type (info);
1350
1351         g_base_info_unref (info);
1352
1353         switch (info_type) {
1354             case GI_INFO_TYPE_UNION:
1355                 PyErr_SetString (PyExc_NotImplementedError, "getting an union is not supported yet");
1356                 goto out;
1357             case GI_INFO_TYPE_STRUCT:
1358             {
1359                 gsize offset;
1360
1361                 offset = g_field_info_get_offset ( (GIFieldInfo *) self->info);
1362
1363                 value.v_pointer = (char*) pointer + offset;
1364
1365                 goto argument_to_object;
1366             }
1367             default:
1368                 /* Fallback. */
1369                 break;
1370         }
1371     }
1372
1373     if (!g_field_info_get_field ( (GIFieldInfo *) self->info, pointer, &value)) {
1374         PyErr_SetString (PyExc_RuntimeError, "unable to get the value");
1375         goto out;
1376     }
1377
1378     if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_ARRAY) {
1379         value.v_pointer = _pygi_argument_to_array (&value, NULL, NULL,
1380                                                    field_type_info, &free_array);
1381     }
1382
1383 argument_to_object:
1384     py_value = _pygi_argument_to_object (&value, field_type_info, GI_TRANSFER_NOTHING);
1385
1386     if (free_array) {
1387         g_array_free (value.v_pointer, FALSE);
1388     }
1389
1390 out:
1391     g_base_info_unref ( (GIBaseInfo *) field_type_info);
1392
1393     return py_value;
1394 }
1395
1396 static PyObject *
1397 _wrap_g_field_info_set_value (PyGIBaseInfo *self,
1398                               PyObject     *args)
1399 {
1400     PyObject *instance;
1401     PyObject *py_value;
1402     GIBaseInfo *container_info;
1403     GIInfoType container_info_type;
1404     gpointer pointer;
1405     GITypeInfo *field_type_info;
1406     GIArgument value;
1407     PyObject *retval = NULL;
1408
1409     if (!PyArg_ParseTuple (args, "OO:FieldInfo.set_value", &instance, &py_value)) {
1410         return NULL;
1411     }
1412
1413     container_info = g_base_info_get_container (self->info);
1414     g_assert (container_info != NULL);
1415
1416     /* Check the instance. */
1417     if (!_pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) container_info, TRUE, instance)) {
1418         _PyGI_ERROR_PREFIX ("argument 1: ");
1419         return NULL;
1420     }
1421
1422     /* Get the pointer to the container. */
1423     container_info_type = g_base_info_get_type (container_info);
1424     switch (container_info_type) {
1425         case GI_INFO_TYPE_UNION:
1426         case GI_INFO_TYPE_STRUCT:
1427             pointer = pyg_boxed_get (instance, void);
1428             break;
1429         case GI_INFO_TYPE_OBJECT:
1430             pointer = pygobject_get (instance);
1431             break;
1432         default:
1433             /* Other types don't have fields. */
1434             g_assert_not_reached();
1435     }
1436
1437     field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info);
1438
1439     /* Check the value. */
1440     {
1441         gboolean retval;
1442
1443         retval = _pygi_g_type_info_check_object (field_type_info, py_value, TRUE);
1444         if (retval < 0) {
1445             goto out;
1446         }
1447
1448         if (!retval) {
1449             _PyGI_ERROR_PREFIX ("argument 2: ");
1450             goto out;
1451         }
1452     }
1453
1454     /* Set the field's value. */
1455     /* A few types are not handled by g_field_info_set_field, so do it here. */
1456     if (!g_type_info_is_pointer (field_type_info)
1457             && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) {
1458         GIBaseInfo *info;
1459         GIInfoType info_type;
1460
1461         if (! (g_field_info_get_flags ( (GIFieldInfo *) self->info) & GI_FIELD_IS_WRITABLE)) {
1462             PyErr_SetString (PyExc_RuntimeError, "field is not writable");
1463             goto out;
1464         }
1465
1466         info = g_type_info_get_interface (field_type_info);
1467
1468         info_type = g_base_info_get_type (info);
1469
1470         switch (info_type) {
1471             case GI_INFO_TYPE_UNION:
1472                 PyErr_SetString (PyExc_NotImplementedError, "setting an union is not supported yet");
1473                 goto out;
1474             case GI_INFO_TYPE_STRUCT:
1475             {
1476                 gboolean is_simple;
1477                 gsize offset;
1478                 gssize size;
1479
1480                 is_simple = pygi_g_struct_info_is_simple ( (GIStructInfo *) info);
1481
1482                 if (!is_simple) {
1483                     PyErr_SetString (PyExc_TypeError,
1484                                      "cannot set a structure which has no well-defined ownership transfer rules");
1485                     g_base_info_unref (info);
1486                     goto out;
1487                 }
1488
1489                 value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING);
1490                 if (PyErr_Occurred()) {
1491                     g_base_info_unref (info);
1492                     goto out;
1493                 }
1494
1495                 offset = g_field_info_get_offset ( (GIFieldInfo *) self->info);
1496                 size = g_struct_info_get_size ( (GIStructInfo *) info);
1497                 g_assert (size > 0);
1498
1499                 g_memmove ((char*) pointer + offset, value.v_pointer, size);
1500
1501                 g_base_info_unref (info);
1502
1503                 retval = Py_None;
1504                 goto out;
1505             }
1506             default:
1507                 /* Fallback. */
1508                 break;
1509         }
1510
1511         g_base_info_unref (info);
1512     } else if (g_type_info_is_pointer (field_type_info)
1513             && (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_VOID
1514                 || g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_UTF8)) {
1515
1516         value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING);
1517         if (PyErr_Occurred()) {
1518             goto out;
1519         }
1520
1521         int offset = g_field_info_get_offset ((GIFieldInfo *) self->info);
1522         G_STRUCT_MEMBER (gpointer, pointer, offset) = (gpointer)value.v_pointer;
1523
1524         retval = Py_None;
1525         goto out;
1526     }
1527
1528     value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_EVERYTHING);
1529     if (PyErr_Occurred()) {
1530         goto out;
1531     }
1532
1533     if (!g_field_info_set_field ( (GIFieldInfo *) self->info, pointer, &value)) {
1534         _pygi_argument_release (&value, field_type_info, GI_TRANSFER_NOTHING, GI_DIRECTION_IN);
1535         PyErr_SetString (PyExc_RuntimeError, "unable to set value for field");
1536         goto out;
1537     }
1538
1539     retval = Py_None;
1540
1541 out:
1542     g_base_info_unref ( (GIBaseInfo *) field_type_info);
1543
1544     Py_XINCREF (retval);
1545     return retval;
1546 }
1547
1548 static PyMethodDef _PyGIFieldInfo_methods[] = {
1549     { "get_value", (PyCFunction) _wrap_g_field_info_get_value, METH_VARARGS },
1550     { "set_value", (PyCFunction) _wrap_g_field_info_set_value, METH_VARARGS },
1551     { NULL, NULL, 0 }
1552 };
1553
1554
1555 /* GIUnresolvedInfo */
1556 PYGLIB_DEFINE_TYPE ("gi.UnresolvedInfo", PyGIUnresolvedInfo_Type, PyGIBaseInfo);
1557
1558 static PyMethodDef _PyGIUnresolvedInfo_methods[] = {
1559     { NULL, NULL, 0 }
1560 };
1561
1562 /* GIVFuncInfo */
1563 PYGLIB_DEFINE_TYPE ("gi.VFuncInfo", PyGIVFuncInfo_Type, PyGIBaseInfo);
1564
1565 static PyObject *
1566 _wrap_g_vfunc_info_get_invoker (PyGIBaseInfo *self)
1567 {
1568     PyObject *result = Py_None;
1569     GIBaseInfo *info;
1570
1571     info = (GIBaseInfo *) g_vfunc_info_get_invoker ( (GIVFuncInfo *) self->info );
1572     if (info)
1573         result = _pygi_info_new(info);
1574     else
1575         Py_INCREF(Py_None);
1576
1577     return result;
1578 }
1579
1580 static PyMethodDef _PyGIVFuncInfo_methods[] = {
1581     { "get_invoker", (PyCFunction) _wrap_g_vfunc_info_get_invoker, METH_NOARGS },
1582     { NULL, NULL, 0 }
1583 };
1584
1585
1586 /* GIUnionInfo */
1587 PYGLIB_DEFINE_TYPE ("gi.UnionInfo", PyGIUnionInfo_Type, PyGIBaseInfo);
1588
1589 static PyObject *
1590 _wrap_g_union_info_get_fields (PyGIBaseInfo *self)
1591 {
1592     gssize n_infos;
1593     PyObject *infos;
1594     gssize i;
1595
1596     n_infos = g_union_info_get_n_fields ( (GIUnionInfo *) self->info);
1597
1598     infos = PyTuple_New (n_infos);
1599     if (infos == NULL) {
1600         return NULL;
1601     }
1602
1603     for (i = 0; i < n_infos; i++) {
1604         GIBaseInfo *info;
1605         PyObject *py_info;
1606
1607         info = (GIBaseInfo *) g_union_info_get_field ( (GIUnionInfo *) self->info, i);
1608         g_assert (info != NULL);
1609
1610         py_info = _pygi_info_new (info);
1611
1612         g_base_info_unref (info);
1613
1614         if (py_info == NULL) {
1615             Py_CLEAR (infos);
1616             break;
1617         }
1618
1619         PyTuple_SET_ITEM (infos, i, py_info);
1620     }
1621
1622     return infos;
1623 }
1624
1625 static PyObject *
1626 _wrap_g_union_info_get_methods (PyGIBaseInfo *self)
1627 {
1628     gssize n_infos;
1629     PyObject *infos;
1630     gssize i;
1631
1632     n_infos = g_union_info_get_n_methods ( (GIUnionInfo *) self->info);
1633
1634     infos = PyTuple_New (n_infos);
1635     if (infos == NULL) {
1636         return NULL;
1637     }
1638
1639     for (i = 0; i < n_infos; i++) {
1640         GIBaseInfo *info;
1641         PyObject *py_info;
1642
1643         info = (GIBaseInfo *) g_union_info_get_method ( (GIUnionInfo *) self->info, i);
1644         g_assert (info != NULL);
1645
1646         py_info = _pygi_info_new (info);
1647
1648         g_base_info_unref (info);
1649
1650         if (py_info == NULL) {
1651             Py_CLEAR (infos);
1652             break;
1653         }
1654
1655         PyTuple_SET_ITEM (infos, i, py_info);
1656     }
1657
1658     return infos;
1659 }
1660
1661 static PyMethodDef _PyGIUnionInfo_methods[] = {
1662     { "get_fields", (PyCFunction) _wrap_g_union_info_get_fields, METH_NOARGS },
1663     { "get_methods", (PyCFunction) _wrap_g_union_info_get_methods, METH_NOARGS },
1664     { NULL, NULL, 0 }
1665 };
1666
1667 /* Private */
1668
1669 gchar *
1670 _pygi_g_base_info_get_fullname (GIBaseInfo *info)
1671 {
1672     GIBaseInfo *container_info;
1673     gchar *fullname;
1674
1675     container_info = g_base_info_get_container (info);
1676     if (container_info != NULL) {
1677         fullname = g_strdup_printf ("%s.%s.%s",
1678                                     g_base_info_get_namespace (container_info),
1679                                     g_base_info_get_name (container_info),
1680                                     g_base_info_get_name (info));
1681     } else {
1682         fullname = g_strdup_printf ("%s.%s",
1683                                     g_base_info_get_namespace (info),
1684                                     g_base_info_get_name (info));
1685     }
1686
1687     if (fullname == NULL) {
1688         PyErr_NoMemory();
1689     }
1690
1691     return fullname;
1692 }
1693
1694 void
1695 _pygi_info_register_types (PyObject *m)
1696 {
1697 #define _PyGI_REGISTER_TYPE(m, type, cname, base) \
1698     Py_TYPE(&type) = &PyType_Type; \
1699     type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE); \
1700     type.tp_weaklistoffset = offsetof(PyGIBaseInfo, inst_weakreflist); \
1701     type.tp_methods = _PyGI##cname##_methods; \
1702     type.tp_base = &base; \
1703     if (PyType_Ready(&type)) \
1704         return; \
1705     if (PyModule_AddObject(m, #cname, (PyObject *)&type)) \
1706         return
1707
1708     Py_TYPE(&PyGIBaseInfo_Type) = &PyType_Type;
1709
1710     PyGIBaseInfo_Type.tp_dealloc = (destructor) _base_info_dealloc;
1711     PyGIBaseInfo_Type.tp_repr = (reprfunc) _base_info_repr;
1712     PyGIBaseInfo_Type.tp_flags = (Py_TPFLAGS_DEFAULT | 
1713                                    Py_TPFLAGS_BASETYPE  | 
1714                                    Py_TPFLAGS_HAVE_GC);
1715     PyGIBaseInfo_Type.tp_traverse = (traverseproc) _base_info_traverse;
1716     PyGIBaseInfo_Type.tp_weaklistoffset = offsetof(PyGIBaseInfo, inst_weakreflist);
1717     PyGIBaseInfo_Type.tp_methods = _PyGIBaseInfo_methods; 
1718     PyGIBaseInfo_Type.tp_richcompare = (richcmpfunc)_base_info_richcompare;
1719
1720     if (PyType_Ready(&PyGIBaseInfo_Type))
1721         return;   
1722  
1723     if (PyModule_AddObject(m, "BaseInfo", (PyObject *)&PyGIBaseInfo_Type))
1724         return;
1725
1726     if (PyModule_AddObject(m, "DIRECTION_IN", PyLong_FromLong(GI_DIRECTION_IN)))
1727         return;
1728     if (PyModule_AddObject(m, "DIRECTION_OUT", PyLong_FromLong(GI_DIRECTION_OUT)))
1729         return;
1730     if (PyModule_AddObject(m, "DIRECTION_INOUT", PyLong_FromLong(GI_DIRECTION_INOUT)))
1731         return;
1732
1733     _PyGI_REGISTER_TYPE (m, PyGIUnresolvedInfo_Type, UnresolvedInfo,
1734                          PyGIBaseInfo_Type);
1735     _PyGI_REGISTER_TYPE (m, PyGICallableInfo_Type, CallableInfo,
1736                          PyGIBaseInfo_Type);
1737     _PyGI_REGISTER_TYPE (m, PyGICallbackInfo_Type, CallbackInfo,
1738                          PyGIBaseInfo_Type);
1739     _PyGI_REGISTER_TYPE (m, PyGIFunctionInfo_Type, FunctionInfo,
1740                          PyGICallableInfo_Type);
1741     _PyGI_REGISTER_TYPE (m, PyGIRegisteredTypeInfo_Type, RegisteredTypeInfo,
1742                          PyGIBaseInfo_Type);
1743     _PyGI_REGISTER_TYPE (m, PyGIStructInfo_Type, StructInfo,
1744                          PyGIRegisteredTypeInfo_Type);
1745     _PyGI_REGISTER_TYPE (m, PyGIEnumInfo_Type, EnumInfo,
1746                          PyGIRegisteredTypeInfo_Type);
1747     _PyGI_REGISTER_TYPE (m, PyGIObjectInfo_Type, ObjectInfo,
1748                          PyGIRegisteredTypeInfo_Type);
1749     _PyGI_REGISTER_TYPE (m, PyGIInterfaceInfo_Type, InterfaceInfo,
1750                          PyGIRegisteredTypeInfo_Type);
1751     _PyGI_REGISTER_TYPE (m, PyGIConstantInfo_Type, ConstantInfo,
1752                          PyGIBaseInfo_Type);
1753     _PyGI_REGISTER_TYPE (m, PyGIValueInfo_Type, ValueInfo,
1754                          PyGIBaseInfo_Type);
1755     _PyGI_REGISTER_TYPE (m, PyGIFieldInfo_Type, FieldInfo,
1756                          PyGIBaseInfo_Type);
1757     _PyGI_REGISTER_TYPE (m, PyGIVFuncInfo_Type, VFuncInfo,
1758                          PyGICallableInfo_Type);
1759     _PyGI_REGISTER_TYPE (m, PyGIUnionInfo_Type, UnionInfo,
1760                          PyGIRegisteredTypeInfo_Type);
1761     _PyGI_REGISTER_TYPE (m, PyGIBoxedInfo_Type, BoxedInfo,
1762                          PyGIBaseInfo_Type);
1763     _PyGI_REGISTER_TYPE (m, PyGIErrorDomainInfo_Type, ErrorDomainInfo,
1764                          PyGIBaseInfo_Type);
1765     _PyGI_REGISTER_TYPE (m, PyGISignalInfo_Type, SignalInfo,
1766                          PyGIBaseInfo_Type);
1767     _PyGI_REGISTER_TYPE (m, PyGIPropertyInfo_Type, PropertyInfo,
1768                          PyGIBaseInfo_Type);
1769     _PyGI_REGISTER_TYPE (m, PyGIArgInfo_Type, ArgInfo,
1770                          PyGIBaseInfo_Type);
1771     _PyGI_REGISTER_TYPE (m, PyGITypeInfo_Type, TypeInfo,
1772                          PyGIBaseInfo_Type);
1773
1774
1775 #undef _PyGI_REGISTER_TYPE
1776 }