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
) {
110 * This allows us to keep multiple references to this object -
111 * we only reference this context, which is per ptr, not the
112 * talloc_ctx, which is per pytalloc_Object
114 if (talloc_steal(ret
->talloc_ctx
, mem_ctx
) == NULL
) {
117 ret
->talloc_ptr_ctx
= mem_ctx
;
118 talloc_set_name_const(ret
->talloc_ctx
, py_type
->tp_name
);
120 return (PyObject
*)ret
;
122 } else if (PyType_IsSubtype(py_type
, ObjectType
)) {
124 = (pytalloc_Object
*)py_type
->tp_alloc(py_type
, 0);
126 ret
->talloc_ctx
= talloc_new(NULL
);
127 if (ret
->talloc_ctx
== NULL
) {
131 if (talloc_steal(ret
->talloc_ctx
, mem_ctx
) == NULL
) {
134 talloc_set_name_const(ret
->talloc_ctx
, py_type
->tp_name
);
136 return (PyObject
*)ret
;
138 PyErr_SetString(PyExc_RuntimeError
,
139 "pytalloc_steal_ex() called for object type "
140 "not based on talloc");
146 * Import an existing talloc pointer into a Python object.
148 _PUBLIC_ PyObject
*pytalloc_steal(PyTypeObject
*py_type
, void *ptr
)
150 return pytalloc_steal_ex(py_type
, ptr
, ptr
);
155 * Import an existing talloc pointer into a Python object, leaving the
156 * original parent, and creating a reference to the object in the python
159 * We remember the object we hold the reference to (a
160 * possibly-non-talloc pointer), the existing parent (typically the
161 * start of the array) and the new referenced parent. That way we can
162 * cope with the fact that we will have multiple parents, one per time
163 * python sees the object.
165 _PUBLIC_ PyObject
*pytalloc_reference_ex(PyTypeObject
*py_type
,
166 TALLOC_CTX
*mem_ctx
, void *ptr
)
168 PyTypeObject
*BaseObjectType
= pytalloc_GetBaseObjectType();
169 PyTypeObject
*ObjectType
= pytalloc_GetObjectType();
171 if (mem_ctx
== NULL
) {
172 return PyErr_NoMemory();
175 if (PyType_IsSubtype(py_type
, BaseObjectType
)) {
176 pytalloc_BaseObject
*ret
177 = (pytalloc_BaseObject
*)py_type
->tp_alloc(py_type
, 0);
178 ret
->talloc_ctx
= talloc_new(NULL
);
179 if (ret
->talloc_ctx
== NULL
) {
182 if (talloc_reference(ret
->talloc_ctx
, mem_ctx
) == NULL
) {
185 talloc_set_name_const(ret
->talloc_ctx
, py_type
->tp_name
);
186 ret
->talloc_ptr_ctx
= mem_ctx
;
188 return (PyObject
*)ret
;
189 } else if (PyType_IsSubtype(py_type
, ObjectType
)) {
191 = (pytalloc_Object
*)py_type
->tp_alloc(py_type
, 0);
192 ret
->talloc_ctx
= talloc_new(NULL
);
193 if (ret
->talloc_ctx
== NULL
) {
196 if (talloc_reference(ret
->talloc_ctx
, mem_ctx
) == NULL
) {
199 talloc_set_name_const(ret
->talloc_ctx
, py_type
->tp_name
);
201 return (PyObject
*)ret
;
203 PyErr_SetString(PyExc_RuntimeError
,
204 "pytalloc_reference_ex() called for object type "
205 "not based on talloc");
210 #if PY_MAJOR_VERSION < 3
212 static void py_cobject_talloc_free(void *ptr
)
217 _PUBLIC_ PyObject
*pytalloc_CObject_FromTallocPtr(void *ptr
)
222 return PyCObject_FromVoidPtr(ptr
, py_cobject_talloc_free
);
228 * Wrap a generic talloc pointer into a talloc.GenericObject,
229 * this is a subclass of talloc.BaseObject.
231 _PUBLIC_ PyObject
*pytalloc_GenericObject_steal_ex(TALLOC_CTX
*mem_ctx
, void *ptr
)
233 PyTypeObject
*tp
= pytalloc_GetGenericObjectType();
234 return pytalloc_steal_ex(tp
, mem_ctx
, ptr
);
238 * Wrap a generic talloc pointer into a talloc.GenericObject,
239 * this is a subclass of talloc.BaseObject.
241 _PUBLIC_ PyObject
*pytalloc_GenericObject_reference_ex(TALLOC_CTX
*mem_ctx
, void *ptr
)
243 PyTypeObject
*tp
= pytalloc_GetGenericObjectType();
244 return pytalloc_reference_ex(tp
, mem_ctx
, ptr
);
247 _PUBLIC_
int pytalloc_Check(PyObject
*obj
)
249 PyTypeObject
*tp
= pytalloc_GetObjectType();
251 return PyObject_TypeCheck(obj
, tp
);
254 _PUBLIC_
int pytalloc_BaseObject_check(PyObject
*obj
)
256 PyTypeObject
*tp
= pytalloc_GetBaseObjectType();
258 return PyObject_TypeCheck(obj
, tp
);
261 _PUBLIC_
size_t pytalloc_BaseObject_size(void)
263 return sizeof(pytalloc_BaseObject
);
266 static void *_pytalloc_get_checked_type(PyObject
*py_obj
, const char *type_name
,
267 bool check_only
, const char *function
)
271 void *type_obj
= talloc_check_name(ptr
, type_name
);
273 mem_ctx
= _pytalloc_get_mem_ctx(py_obj
);
274 ptr
= _pytalloc_get_ptr(py_obj
);
276 if (mem_ctx
!= ptr
) {
281 PyErr_Format(PyExc_TypeError
, "%s: expected %s, "
282 "but the pointer is no talloc pointer, "
283 "pytalloc_get_ptr() would get the raw pointer.",
284 function
, type_name
);
288 type_obj
= talloc_check_name(ptr
, type_name
);
289 if (type_obj
== NULL
) {
290 const char *name
= NULL
;
296 name
= talloc_get_name(ptr
);
297 PyErr_Format(PyExc_TypeError
, "%s: expected %s, got %s",
298 function
, type_name
, name
);
305 _PUBLIC_
int _pytalloc_check_type(PyObject
*py_obj
, const char *type_name
)
309 ptr
= _pytalloc_get_checked_type(py_obj
, type_name
,
310 true, /* check_only */
311 "pytalloc_check_type");
319 _PUBLIC_
void *_pytalloc_get_type(PyObject
*py_obj
, const char *type_name
)
321 return _pytalloc_get_checked_type(py_obj
, type_name
,
322 false, /* not check_only */
323 "pytalloc_get_type");
326 _PUBLIC_
void *_pytalloc_get_ptr(PyObject
*py_obj
)
328 if (pytalloc_BaseObject_check(py_obj
)) {
329 return ((pytalloc_BaseObject
*)py_obj
)->ptr
;
331 if (pytalloc_Check(py_obj
)) {
332 return ((pytalloc_Object
*)py_obj
)->ptr
;
337 _PUBLIC_ TALLOC_CTX
*_pytalloc_get_mem_ctx(PyObject
*py_obj
)
339 if (pytalloc_BaseObject_check(py_obj
)) {
340 return ((pytalloc_BaseObject
*)py_obj
)->talloc_ptr_ctx
;
342 if (pytalloc_Check(py_obj
)) {
343 return ((pytalloc_Object
*)py_obj
)->talloc_ctx
;
348 _PUBLIC_
int pytalloc_BaseObject_PyType_Ready(PyTypeObject
*type
)
350 PyTypeObject
*talloc_type
= pytalloc_GetBaseObjectType();
351 if (talloc_type
== NULL
) {
352 PyErr_Format(PyExc_TypeError
, "pytalloc: unable to get talloc.BaseObject type");
356 type
->tp_base
= talloc_type
;
357 type
->tp_basicsize
= pytalloc_BaseObject_size();
359 return PyType_Ready(type
);