1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * Copyright (C) 2009 Simon van der Linden <svdlinden@src.gnome.org>
6 * pygi-boxed.c: wrapper to handle registered structures.
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.
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.
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
24 #include "pygi-private.h"
26 #include <pygobject.h>
27 #include <girepository.h>
28 #include <pyglib-python-compat.h>
31 _boxed_dealloc (PyGIBoxed *self)
35 PyObject_GC_UnTrack ( (PyObject *) self);
37 PyObject_ClearWeakRefs ( (PyObject *) self);
39 if ( ( (PyGBoxed *) self)->free_on_dealloc) {
40 if (self->slice_allocated) {
41 g_slice_free1 (self->size, ( (PyGBoxed *) self)->boxed);
43 g_type = pyg_type_from_object ( (PyObject *) self);
44 g_boxed_free (g_type, ( (PyGBoxed *) self)->boxed);
48 Py_TYPE( (PyGObject *) self)->tp_free ( (PyObject *) self);
52 _pygi_boxed_alloc (GIBaseInfo *info, gsize *size_out)
56 /* FIXME: Remove when bgo#622711 is fixed */
57 if (g_registered_type_info_get_g_type (info) == G_TYPE_VALUE) {
58 size = sizeof (GValue);
60 switch (g_base_info_get_type (info)) {
61 case GI_INFO_TYPE_UNION:
62 size = g_union_info_get_size ( (GIUnionInfo *) info);
64 case GI_INFO_TYPE_BOXED:
65 case GI_INFO_TYPE_STRUCT:
66 size = g_struct_info_get_size ( (GIStructInfo *) info);
69 PyErr_Format (PyExc_TypeError,
70 "info should be Boxed or Union, not '%d'",
71 g_base_info_get_type (info));
79 return g_slice_alloc0 (size);
83 _boxed_new (PyTypeObject *type,
87 static char *kwlist[] = { NULL };
92 PyGIBoxed *self = NULL;
94 if (!PyArg_ParseTupleAndKeywords (args, kwargs, "", kwlist)) {
98 info = _pygi_object_get_gi_info ( (PyObject *) type, &PyGIBaseInfo_Type);
100 if (PyErr_ExceptionMatches (PyExc_AttributeError)) {
101 PyErr_Format (PyExc_TypeError, "missing introspection information");
106 boxed = _pygi_boxed_alloc (info, &size);
112 self = (PyGIBoxed *) _pygi_boxed_new (type, boxed, TRUE);
114 g_slice_free1 (size, boxed);
119 self->slice_allocated = TRUE;
122 g_base_info_unref (info);
124 return (PyObject *) self;
128 _boxed_init (PyObject *self,
132 /* Don't call PyGBoxed's init, which raises an exception. */
136 PYGLIB_DEFINE_TYPE("gi.Boxed", PyGIBoxed_Type, PyGIBoxed);
139 _pygi_boxed_new (PyTypeObject *type,
141 gboolean free_on_dealloc)
149 if (!PyType_IsSubtype (type, &PyGIBoxed_Type)) {
150 PyErr_SetString (PyExc_TypeError, "must be a subtype of gi.Boxed");
154 self = (PyGIBoxed *) type->tp_alloc (type, 0);
159 ( (PyGBoxed *) self)->gtype = pyg_type_from_object ( (PyObject *) type);
160 ( (PyGBoxed *) self)->boxed = boxed;
161 ( (PyGBoxed *) self)->free_on_dealloc = free_on_dealloc;
163 self->slice_allocated = FALSE;
165 return (PyObject *) self;
169 _pygi_boxed_register_types (PyObject *m)
171 Py_TYPE(&PyGIBoxed_Type) = &PyType_Type;
172 PyGIBoxed_Type.tp_base = &PyGBoxed_Type;
173 PyGIBoxed_Type.tp_new = (newfunc) _boxed_new;
174 PyGIBoxed_Type.tp_init = (initproc) _boxed_init;
175 PyGIBoxed_Type.tp_dealloc = (destructor) _boxed_dealloc;
176 PyGIBoxed_Type.tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE);
178 if (PyType_Ready (&PyGIBoxed_Type))
180 if (PyModule_AddObject (m, "Boxed", (PyObject *) &PyGIBoxed_Type))