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 _PUBLIC_ PyTypeObject *pytalloc_GetObjectType(void)
29 static PyTypeObject *type = NULL;
36 mod = PyImport_ImportModule("talloc");
41 type = (PyTypeObject *)PyObject_GetAttrString(mod, "Object");
47 _PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void)
49 static PyTypeObject *type = NULL;
56 mod = PyImport_ImportModule("talloc");
61 type = (PyTypeObject *)PyObject_GetAttrString(mod, "BaseObject");
67 static PyTypeObject *pytalloc_GetGenericObjectType(void)
69 static PyTypeObject *type = NULL;
76 mod = PyImport_ImportModule("talloc");
81 type = (PyTypeObject *)PyObject_GetAttrString(mod, "GenericObject");
88 * Import an existing talloc pointer into a Python object.
90 _PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
93 PyTypeObject *BaseObjectType = pytalloc_GetBaseObjectType();
94 PyTypeObject *ObjectType = pytalloc_GetObjectType();
96 if (mem_ctx == NULL) {
97 return PyErr_NoMemory();
100 if (PyType_IsSubtype(py_type, BaseObjectType)) {
101 pytalloc_BaseObject *ret
102 = (pytalloc_BaseObject *)py_type->tp_alloc(py_type, 0);
104 ret->talloc_ctx = talloc_new(NULL);
105 if (ret->talloc_ctx == NULL) {
107 return PyErr_NoMemory();
111 * This allows us to keep multiple references to this object -
112 * we only reference this context, which is per ptr, not the
113 * talloc_ctx, which is per pytalloc_Object
115 if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
117 return PyErr_NoMemory();
119 ret->talloc_ptr_ctx = mem_ctx;
120 talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
122 return (PyObject *)ret;
124 } else if (PyType_IsSubtype(py_type, ObjectType)) {
126 = (pytalloc_Object *)py_type->tp_alloc(py_type, 0);
128 ret->talloc_ctx = talloc_new(NULL);
129 if (ret->talloc_ctx == NULL) {
131 return PyErr_NoMemory();
134 if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
136 return PyErr_NoMemory();
138 talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
140 return (PyObject *)ret;
142 PyErr_SetString(PyExc_RuntimeError,
143 "pytalloc_steal_ex() called for object type "
144 "not based on talloc");
150 * Import an existing talloc pointer into a Python object.
152 _PUBLIC_ PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr)
154 return pytalloc_steal_ex(py_type, ptr, ptr);
159 * Import an existing talloc pointer into a Python object, leaving the
160 * original parent, and creating a reference to the object in the python
163 * We remember the object we hold the reference to (a
164 * possibly-non-talloc pointer), the existing parent (typically the
165 * start of the array) and the new referenced parent. That way we can
166 * cope with the fact that we will have multiple parents, one per time
167 * python sees the object.
169 _PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type,
170 TALLOC_CTX *mem_ctx, void *ptr)
172 PyTypeObject *BaseObjectType = pytalloc_GetBaseObjectType();
173 PyTypeObject *ObjectType = pytalloc_GetObjectType();
175 if (mem_ctx == NULL) {
176 return PyErr_NoMemory();
179 if (PyType_IsSubtype(py_type, BaseObjectType)) {
180 pytalloc_BaseObject *ret
181 = (pytalloc_BaseObject *)py_type->tp_alloc(py_type, 0);
182 ret->talloc_ctx = talloc_new(NULL);
183 if (ret->talloc_ctx == NULL) {
185 return PyErr_NoMemory();
187 if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
189 return PyErr_NoMemory();
191 talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
192 ret->talloc_ptr_ctx = mem_ctx;
194 return (PyObject *)ret;
195 } else if (PyType_IsSubtype(py_type, ObjectType)) {
197 = (pytalloc_Object *)py_type->tp_alloc(py_type, 0);
198 ret->talloc_ctx = talloc_new(NULL);
199 if (ret->talloc_ctx == NULL) {
201 return PyErr_NoMemory();
203 if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
205 return PyErr_NoMemory();
207 talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
209 return (PyObject *)ret;
211 PyErr_SetString(PyExc_RuntimeError,
212 "pytalloc_reference_ex() called for object type "
213 "not based on talloc");
218 #if PY_MAJOR_VERSION < 3
220 static void py_cobject_talloc_free(void *ptr)
225 _PUBLIC_ PyObject *pytalloc_CObject_FromTallocPtr(void *ptr)
230 return PyCObject_FromVoidPtr(ptr, py_cobject_talloc_free);
236 * Wrap a generic talloc pointer into a talloc.GenericObject,
237 * this is a subclass of talloc.BaseObject.
239 _PUBLIC_ PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr)
241 PyTypeObject *tp = pytalloc_GetGenericObjectType();
242 return pytalloc_steal_ex(tp, mem_ctx, ptr);
246 * Wrap a generic talloc pointer into a talloc.GenericObject,
247 * this is a subclass of talloc.BaseObject.
249 _PUBLIC_ PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr)
251 PyTypeObject *tp = pytalloc_GetGenericObjectType();
252 return pytalloc_reference_ex(tp, mem_ctx, ptr);
255 _PUBLIC_ int pytalloc_Check(PyObject *obj)
257 PyTypeObject *tp = pytalloc_GetObjectType();
259 return PyObject_TypeCheck(obj, tp);
262 _PUBLIC_ int pytalloc_BaseObject_check(PyObject *obj)
264 PyTypeObject *tp = pytalloc_GetBaseObjectType();
266 return PyObject_TypeCheck(obj, tp);
269 _PUBLIC_ size_t pytalloc_BaseObject_size(void)
271 return sizeof(pytalloc_BaseObject);
274 static void *_pytalloc_get_checked_type(PyObject *py_obj, const char *type_name,
275 bool check_only, const char *function)
279 void *type_obj = talloc_check_name(ptr, type_name);
281 mem_ctx = _pytalloc_get_mem_ctx(py_obj);
282 ptr = _pytalloc_get_ptr(py_obj);
284 if (mem_ctx != ptr) {
289 PyErr_Format(PyExc_TypeError, "%s: expected %s, "
290 "but the pointer is no talloc pointer, "
291 "pytalloc_get_ptr() would get the raw pointer.",
292 function, type_name);
296 type_obj = talloc_check_name(ptr, type_name);
297 if (type_obj == NULL) {
298 const char *name = NULL;
304 name = talloc_get_name(ptr);
305 PyErr_Format(PyExc_TypeError, "%s: expected %s, got %s",
306 function, type_name, name);
313 _PUBLIC_ int _pytalloc_check_type(PyObject *py_obj, const char *type_name)
317 ptr = _pytalloc_get_checked_type(py_obj, type_name,
318 true, /* check_only */
319 "pytalloc_check_type");
327 _PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name)
329 return _pytalloc_get_checked_type(py_obj, type_name,
330 false, /* not check_only */
331 "pytalloc_get_type");
334 _PUBLIC_ void *_pytalloc_get_ptr(PyObject *py_obj)
336 if (pytalloc_BaseObject_check(py_obj)) {
337 return ((pytalloc_BaseObject *)py_obj)->ptr;
339 if (pytalloc_Check(py_obj)) {
340 return ((pytalloc_Object *)py_obj)->ptr;
345 _PUBLIC_ TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj)
347 if (pytalloc_BaseObject_check(py_obj)) {
348 return ((pytalloc_BaseObject *)py_obj)->talloc_ptr_ctx;
350 if (pytalloc_Check(py_obj)) {
351 return ((pytalloc_Object *)py_obj)->talloc_ctx;
356 _PUBLIC_ int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type)
358 PyTypeObject *talloc_type = pytalloc_GetBaseObjectType();
359 if (talloc_type == NULL) {
360 PyErr_Format(PyExc_TypeError, "pytalloc: unable to get talloc.BaseObject type");
364 type->tp_base = talloc_type;
365 type->tp_basicsize = pytalloc_BaseObject_size();
367 return PyType_Ready(type);