2 Unix SMB/CIFS implementation.
4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
6 ** NOTE! The following LGPL license applies to the talloc
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 3 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, see <http://www.gnu.org/licenses/>.
29 #include "pytalloc_private.h"
31 static PyObject
*pytalloc_steal_or_reference(PyTypeObject
*py_type
,
32 TALLOC_CTX
*mem_ctx
, void *ptr
, bool steal
);
34 _PUBLIC_ PyTypeObject
*pytalloc_GetObjectType(void)
36 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
;
55 mod
= PyImport_ImportModule("talloc");
60 type
= (PyTypeObject
*)PyObject_GetAttrString(mod
, "BaseObject");
66 static PyTypeObject
*pytalloc_GetGenericObjectType(void)
68 static PyTypeObject
*type
= NULL
;
71 mod
= PyImport_ImportModule("talloc");
76 type
= (PyTypeObject
*)PyObject_GetAttrString(mod
, "GenericObject");
83 * Import an existing talloc pointer into a Python object.
85 _PUBLIC_ PyObject
*pytalloc_steal_ex(PyTypeObject
*py_type
, TALLOC_CTX
*mem_ctx
,
88 return pytalloc_steal_or_reference(py_type
, mem_ctx
, ptr
, true);
92 * Import an existing talloc pointer into a Python object.
94 _PUBLIC_ PyObject
*pytalloc_steal(PyTypeObject
*py_type
, void *ptr
)
96 return pytalloc_steal_or_reference(py_type
, ptr
, ptr
, true);
101 * Import an existing talloc pointer into a Python object, leaving the
102 * original parent, and creating a reference to the object in the python
105 * We remember the object we hold the reference to (a
106 * possibly-non-talloc pointer), the existing parent (typically the
107 * start of the array) and the new referenced parent. That way we can
108 * cope with the fact that we will have multiple parents, one per time
109 * python sees the object.
111 _PUBLIC_ PyObject
*pytalloc_reference_ex(PyTypeObject
*py_type
,
112 TALLOC_CTX
*mem_ctx
, void *ptr
)
114 return pytalloc_steal_or_reference(py_type
, mem_ctx
, ptr
, false);
119 * Internal function that either steals or referecences the talloc
120 * pointer into a new talloc context.
122 static PyObject
*pytalloc_steal_or_reference(PyTypeObject
*py_type
,
123 TALLOC_CTX
*mem_ctx
, void *ptr
, bool steal
)
126 TALLOC_CTX
*talloc_ctx
= NULL
;
127 bool is_baseobject
= false;
128 PyObject
*obj
= NULL
;
129 PyTypeObject
*BaseObjectType
= NULL
, *ObjectType
= NULL
;
131 BaseObjectType
= pytalloc_GetBaseObjectType();
132 if (BaseObjectType
== NULL
) {
135 ObjectType
= pytalloc_GetObjectType();
136 if (ObjectType
== NULL
) {
140 /* this should have been tested by caller */
141 if (mem_ctx
== NULL
) {
142 return PyErr_NoMemory();
145 is_baseobject
= PyType_IsSubtype(py_type
, BaseObjectType
);
146 if (!is_baseobject
) {
147 if (!PyType_IsSubtype(py_type
, ObjectType
)) {
148 PyErr_SetString(PyExc_TypeError
,
149 "Expected type based on talloc");
154 obj
= py_type
->tp_alloc(py_type
, 0);
159 talloc_ctx
= talloc_new(NULL
);
160 if (talloc_ctx
== NULL
) {
166 ok
= (talloc_steal(talloc_ctx
, mem_ctx
) != NULL
);
168 ok
= (talloc_reference(talloc_ctx
, mem_ctx
) != NULL
);
173 talloc_set_name_const(talloc_ctx
, py_type
->tp_name
);
176 pytalloc_BaseObject
*ret
= (pytalloc_BaseObject
*)obj
;
177 ret
->talloc_ctx
= talloc_ctx
;
178 ret
->talloc_ptr_ctx
= mem_ctx
;
181 pytalloc_Object
*ret
= (pytalloc_Object
*)obj
;
182 ret
->talloc_ctx
= talloc_ctx
;
188 TALLOC_FREE(talloc_ctx
);
194 * Wrap a generic talloc pointer into a talloc.GenericObject,
195 * this is a subclass of talloc.BaseObject.
197 _PUBLIC_ PyObject
*pytalloc_GenericObject_steal_ex(TALLOC_CTX
*mem_ctx
, void *ptr
)
199 PyTypeObject
*tp
= pytalloc_GetGenericObjectType();
200 return pytalloc_steal_ex(tp
, mem_ctx
, ptr
);
204 * Wrap a generic talloc pointer into a talloc.GenericObject,
205 * this is a subclass of talloc.BaseObject.
207 _PUBLIC_ PyObject
*pytalloc_GenericObject_reference_ex(TALLOC_CTX
*mem_ctx
, void *ptr
)
209 PyTypeObject
*tp
= pytalloc_GetGenericObjectType();
210 return pytalloc_reference_ex(tp
, mem_ctx
, ptr
);
213 _PUBLIC_
int pytalloc_Check(PyObject
*obj
)
215 PyTypeObject
*tp
= pytalloc_GetObjectType();
217 return PyObject_TypeCheck(obj
, tp
);
220 _PUBLIC_
int pytalloc_BaseObject_check(PyObject
*obj
)
222 PyTypeObject
*tp
= pytalloc_GetBaseObjectType();
224 return PyObject_TypeCheck(obj
, tp
);
227 _PUBLIC_
size_t pytalloc_BaseObject_size(void)
229 return sizeof(pytalloc_BaseObject
);
232 static void *_pytalloc_get_checked_type(PyObject
*py_obj
, const char *type_name
,
233 bool check_only
, const char *function
)
239 mem_ctx
= _pytalloc_get_mem_ctx(py_obj
);
240 ptr
= _pytalloc_get_ptr(py_obj
);
242 if (mem_ctx
!= ptr
|| ptr
== NULL
) {
247 PyErr_Format(PyExc_TypeError
, "%s: expected %s, "
248 "but the pointer is no talloc pointer, "
249 "pytalloc_get_ptr() would get the raw pointer.",
250 function
, type_name
);
254 type_obj
= talloc_check_name(ptr
, type_name
);
255 if (type_obj
== NULL
) {
256 const char *name
= NULL
;
262 name
= talloc_get_name(ptr
);
263 PyErr_Format(PyExc_TypeError
, "%s: expected %s, got %s",
264 function
, type_name
, name
);
271 _PUBLIC_
int _pytalloc_check_type(PyObject
*py_obj
, const char *type_name
)
275 ptr
= _pytalloc_get_checked_type(py_obj
, type_name
,
276 true, /* check_only */
277 "pytalloc_check_type");
285 _PUBLIC_
void *_pytalloc_get_type(PyObject
*py_obj
, const char *type_name
)
287 return _pytalloc_get_checked_type(py_obj
, type_name
,
288 false, /* not check_only */
289 "pytalloc_get_type");
292 _PUBLIC_
void *_pytalloc_get_ptr(PyObject
*py_obj
)
294 if (pytalloc_BaseObject_check(py_obj
)) {
295 return ((pytalloc_BaseObject
*)py_obj
)->ptr
;
297 if (pytalloc_Check(py_obj
)) {
298 return ((pytalloc_Object
*)py_obj
)->ptr
;
303 _PUBLIC_ TALLOC_CTX
*_pytalloc_get_mem_ctx(PyObject
*py_obj
)
305 if (pytalloc_BaseObject_check(py_obj
)) {
306 return ((pytalloc_BaseObject
*)py_obj
)->talloc_ptr_ctx
;
308 if (pytalloc_Check(py_obj
)) {
309 return ((pytalloc_Object
*)py_obj
)->talloc_ctx
;
314 _PUBLIC_
int pytalloc_BaseObject_PyType_Ready(PyTypeObject
*type
)
316 PyTypeObject
*talloc_type
= pytalloc_GetBaseObjectType();
317 if (talloc_type
== NULL
) {
321 type
->tp_base
= talloc_type
;
322 type
->tp_basicsize
= pytalloc_BaseObject_size();
324 return PyType_Ready(type
);
327 _PUBLIC_
const char *_pytalloc_get_name(PyObject
*obj
)
329 void *ptr
= pytalloc_get_ptr(obj
);
331 return "non-talloc object";
333 return talloc_get_name(ptr
);