smbstatus: add frame files for json specific methods
[Samba.git] / lib / talloc / pytalloc_util.c
blob1b7cfdda6e7cde9964409d50e58cd9a0552e43e6
1 /*
2 Unix SMB/CIFS implementation.
3 Python/Talloc glue
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
8 ** under the LGPL
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/>.
24 #include <Python.h>
25 #include "replace.h"
26 #include <talloc.h>
27 #include "pytalloc.h"
28 #include <assert.h>
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;
37 PyObject *mod;
39 mod = PyImport_ImportModule("talloc");
40 if (mod == NULL) {
41 return NULL;
44 type = (PyTypeObject *)PyObject_GetAttrString(mod, "Object");
45 Py_DECREF(mod);
47 return type;
50 _PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void)
52 static PyTypeObject *type = NULL;
53 PyObject *mod;
55 mod = PyImport_ImportModule("talloc");
56 if (mod == NULL) {
57 return NULL;
60 type = (PyTypeObject *)PyObject_GetAttrString(mod, "BaseObject");
61 Py_DECREF(mod);
63 return type;
66 static PyTypeObject *pytalloc_GetGenericObjectType(void)
68 static PyTypeObject *type = NULL;
69 PyObject *mod;
71 mod = PyImport_ImportModule("talloc");
72 if (mod == NULL) {
73 return NULL;
76 type = (PyTypeObject *)PyObject_GetAttrString(mod, "GenericObject");
77 Py_DECREF(mod);
79 return type;
82 /**
83 * Import an existing talloc pointer into a Python object.
85 _PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
86 void *ptr)
88 return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, true);
91 /**
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
103 * object.
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)
125 bool ok = false;
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) {
133 goto err;
135 ObjectType = pytalloc_GetObjectType();
136 if (ObjectType == NULL) {
137 goto err;
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");
150 return NULL;
154 obj = py_type->tp_alloc(py_type, 0);
155 if (obj == NULL) {
156 goto err;
159 talloc_ctx = talloc_new(NULL);
160 if (talloc_ctx == NULL) {
161 PyErr_NoMemory();
162 goto err;
165 if (steal) {
166 ok = (talloc_steal(talloc_ctx, mem_ctx) != NULL);
167 } else {
168 ok = (talloc_reference(talloc_ctx, mem_ctx) != NULL);
170 if (!ok) {
171 goto err;
173 talloc_set_name_const(talloc_ctx, py_type->tp_name);
175 if (is_baseobject) {
176 pytalloc_BaseObject *ret = (pytalloc_BaseObject*)obj;
177 ret->talloc_ctx = talloc_ctx;
178 ret->talloc_ptr_ctx = mem_ctx;
179 ret->ptr = ptr;
180 } else {
181 pytalloc_Object *ret = (pytalloc_Object*)obj;
182 ret->talloc_ctx = talloc_ctx;
183 ret->ptr = ptr;
185 return obj;
187 err:
188 TALLOC_FREE(talloc_ctx);
189 Py_XDECREF(obj);
190 return NULL;
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)
235 TALLOC_CTX *mem_ctx;
236 void *ptr = NULL;
237 void *type_obj;
239 mem_ctx = _pytalloc_get_mem_ctx(py_obj);
240 ptr = _pytalloc_get_ptr(py_obj);
242 if (mem_ctx != ptr || ptr == NULL) {
243 if (check_only) {
244 return 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);
251 return NULL;
254 type_obj = talloc_check_name(ptr, type_name);
255 if (type_obj == NULL) {
256 const char *name = NULL;
258 if (check_only) {
259 return NULL;
262 name = talloc_get_name(ptr);
263 PyErr_Format(PyExc_TypeError, "%s: expected %s, got %s",
264 function, type_name, name);
265 return NULL;
268 return ptr;
271 _PUBLIC_ int _pytalloc_check_type(PyObject *py_obj, const char *type_name)
273 void *ptr = NULL;
275 ptr = _pytalloc_get_checked_type(py_obj, type_name,
276 true, /* check_only */
277 "pytalloc_check_type");
278 if (ptr == NULL) {
279 return 0;
282 return 1;
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;
300 return NULL;
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;
311 return NULL;
314 _PUBLIC_ int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type)
316 PyTypeObject *talloc_type = pytalloc_GetBaseObjectType();
317 if (talloc_type == NULL) {
318 return -1;
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);
330 if (ptr == NULL) {
331 return "non-talloc object";
333 return talloc_get_name(ptr);