2 Unix SMB/CIFS implementation.
4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "pytalloc_private.h"
27 static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type,
28 TALLOC_CTX *mem_ctx, void *ptr, bool steal);
30 _PUBLIC_ PyTypeObject *pytalloc_GetObjectType(void)
32 static PyTypeObject *type = NULL;
39 mod = PyImport_ImportModule("talloc");
44 type = (PyTypeObject *)PyObject_GetAttrString(mod, "Object");
50 _PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void)
52 static PyTypeObject *type = NULL;
59 mod = PyImport_ImportModule("talloc");
64 type = (PyTypeObject *)PyObject_GetAttrString(mod, "BaseObject");
70 static PyTypeObject *pytalloc_GetGenericObjectType(void)
72 static PyTypeObject *type = NULL;
79 mod = PyImport_ImportModule("talloc");
84 type = (PyTypeObject *)PyObject_GetAttrString(mod, "GenericObject");
91 * Import an existing talloc pointer into a Python object.
93 _PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
96 return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, true);
100 * Import an existing talloc pointer into a Python object.
102 _PUBLIC_ PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr)
104 return pytalloc_steal_or_reference(py_type, ptr, ptr, true);
109 * Import an existing talloc pointer into a Python object, leaving the
110 * original parent, and creating a reference to the object in the python
113 * We remember the object we hold the reference to (a
114 * possibly-non-talloc pointer), the existing parent (typically the
115 * start of the array) and the new referenced parent. That way we can
116 * cope with the fact that we will have multiple parents, one per time
117 * python sees the object.
119 _PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type,
120 TALLOC_CTX *mem_ctx, void *ptr)
122 return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, false);
127 * Internal function that either steals or referecences the talloc
128 * pointer into a new talloc context.
130 static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type,
131 TALLOC_CTX *mem_ctx, void *ptr, bool steal)
134 TALLOC_CTX *talloc_ctx = NULL;
135 bool is_baseobject = false;
136 PyObject *obj = NULL;
137 PyTypeObject *BaseObjectType = NULL, *ObjectType = NULL;
139 BaseObjectType = pytalloc_GetBaseObjectType();
140 if (BaseObjectType == NULL) {
143 ObjectType = pytalloc_GetObjectType();
144 if (ObjectType == NULL) {
148 /* this should have been tested by caller */
149 if (mem_ctx == NULL) {
150 return PyErr_NoMemory();
153 is_baseobject = PyType_IsSubtype(py_type, BaseObjectType);
154 if (!is_baseobject) {
155 if (!PyType_IsSubtype(py_type, ObjectType)) {
156 PyErr_SetString(PyExc_TypeError,
157 "Expected type based on talloc");
162 obj = py_type->tp_alloc(py_type, 0);
167 talloc_ctx = talloc_new(NULL);
168 if (talloc_ctx == NULL) {
174 ok = (talloc_steal(talloc_ctx, mem_ctx) != NULL);
176 ok = (talloc_reference(talloc_ctx, mem_ctx) != NULL);
181 talloc_set_name_const(talloc_ctx, py_type->tp_name);
184 pytalloc_BaseObject *ret = (pytalloc_BaseObject*)obj;
185 ret->talloc_ctx = talloc_ctx;
186 ret->talloc_ptr_ctx = mem_ctx;
189 pytalloc_Object *ret = (pytalloc_Object*)obj;
190 ret->talloc_ctx = talloc_ctx;
196 TALLOC_FREE(talloc_ctx);
202 * Wrap a generic talloc pointer into a talloc.GenericObject,
203 * this is a subclass of talloc.BaseObject.
205 _PUBLIC_ PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr)
207 PyTypeObject *tp = pytalloc_GetGenericObjectType();
208 return pytalloc_steal_ex(tp, mem_ctx, ptr);
212 * Wrap a generic talloc pointer into a talloc.GenericObject,
213 * this is a subclass of talloc.BaseObject.
215 _PUBLIC_ PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr)
217 PyTypeObject *tp = pytalloc_GetGenericObjectType();
218 return pytalloc_reference_ex(tp, mem_ctx, ptr);
221 _PUBLIC_ int pytalloc_Check(PyObject *obj)
223 PyTypeObject *tp = pytalloc_GetObjectType();
225 return PyObject_TypeCheck(obj, tp);
228 _PUBLIC_ int pytalloc_BaseObject_check(PyObject *obj)
230 PyTypeObject *tp = pytalloc_GetBaseObjectType();
232 return PyObject_TypeCheck(obj, tp);
235 _PUBLIC_ size_t pytalloc_BaseObject_size(void)
237 return sizeof(pytalloc_BaseObject);
240 static void *_pytalloc_get_checked_type(PyObject *py_obj, const char *type_name,
241 bool check_only, const char *function)
245 void *type_obj = talloc_check_name(ptr, type_name);
247 mem_ctx = _pytalloc_get_mem_ctx(py_obj);
248 ptr = _pytalloc_get_ptr(py_obj);
250 if (mem_ctx != ptr || ptr == NULL) {
255 PyErr_Format(PyExc_TypeError, "%s: expected %s, "
256 "but the pointer is no talloc pointer, "
257 "pytalloc_get_ptr() would get the raw pointer.",
258 function, type_name);
262 type_obj = talloc_check_name(ptr, type_name);
263 if (type_obj == NULL) {
264 const char *name = NULL;
270 name = talloc_get_name(ptr);
271 PyErr_Format(PyExc_TypeError, "%s: expected %s, got %s",
272 function, type_name, name);
279 _PUBLIC_ int _pytalloc_check_type(PyObject *py_obj, const char *type_name)
283 ptr = _pytalloc_get_checked_type(py_obj, type_name,
284 true, /* check_only */
285 "pytalloc_check_type");
293 _PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name)
295 return _pytalloc_get_checked_type(py_obj, type_name,
296 false, /* not check_only */
297 "pytalloc_get_type");
300 _PUBLIC_ void *_pytalloc_get_ptr(PyObject *py_obj)
302 if (pytalloc_BaseObject_check(py_obj)) {
303 return ((pytalloc_BaseObject *)py_obj)->ptr;
305 if (pytalloc_Check(py_obj)) {
306 return ((pytalloc_Object *)py_obj)->ptr;
311 _PUBLIC_ TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj)
313 if (pytalloc_BaseObject_check(py_obj)) {
314 return ((pytalloc_BaseObject *)py_obj)->talloc_ptr_ctx;
316 if (pytalloc_Check(py_obj)) {
317 return ((pytalloc_Object *)py_obj)->talloc_ctx;
322 _PUBLIC_ int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type)
324 PyTypeObject *talloc_type = pytalloc_GetBaseObjectType();
325 if (talloc_type == NULL) {
329 type->tp_base = talloc_type;
330 type->tp_basicsize = pytalloc_BaseObject_size();
332 return PyType_Ready(type);
335 _PUBLIC_ const char *_pytalloc_get_name(PyObject *obj)
337 void *ptr = pytalloc_get_ptr(obj);
339 return "non-talloc object";
341 return talloc_get_name(ptr);