KCC: Fix misnamed variable in DSA object
[Samba.git] / lib / talloc / pytalloc_util.c
blobcb71dc975ccf65e77c0c0a87e344d0b4ebca9384
1 /*
2 Unix SMB/CIFS implementation.
3 Python/Talloc glue
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/>.
20 #include <Python.h>
21 #include "replace.h"
22 #include <talloc.h>
23 #include "pytalloc.h"
24 #include <assert.h>
25 #include "pytalloc_private.h"
27 _PUBLIC_ PyTypeObject *pytalloc_GetObjectType(void)
29 static PyTypeObject *type = NULL;
30 PyObject *mod;
32 if (type != NULL) {
33 return type;
36 mod = PyImport_ImportModule("talloc");
37 if (mod == NULL) {
38 return NULL;
41 type = (PyTypeObject *)PyObject_GetAttrString(mod, "Object");
42 Py_DECREF(mod);
44 return type;
47 _PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void)
49 static PyTypeObject *type = NULL;
50 PyObject *mod;
52 if (type != NULL) {
53 return type;
56 mod = PyImport_ImportModule("talloc");
57 if (mod == NULL) {
58 return NULL;
61 type = (PyTypeObject *)PyObject_GetAttrString(mod, "BaseObject");
62 Py_DECREF(mod);
64 return type;
67 /**
68 * Import an existing talloc pointer into a Python object.
70 _PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
71 void *ptr)
73 PyTypeObject *BaseObjectType = pytalloc_GetBaseObjectType();
74 PyTypeObject *ObjectType = pytalloc_GetObjectType();
76 if (mem_ctx == NULL) {
77 return PyErr_NoMemory();
80 if (PyType_IsSubtype(py_type, BaseObjectType)) {
81 pytalloc_BaseObject *ret
82 = (pytalloc_BaseObject *)py_type->tp_alloc(py_type, 0);
84 ret->talloc_ctx = talloc_new(NULL);
85 if (ret->talloc_ctx == NULL) {
86 return NULL;
90 * This allows us to keep multiple references to this object -
91 * we only reference this context, which is per ptr, not the
92 * talloc_ctx, which is per pytalloc_Object
94 if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
95 return NULL;
97 ret->talloc_ptr_ctx = mem_ctx;
98 talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
99 ret->ptr = ptr;
100 return (PyObject *)ret;
102 } else if (PyType_IsSubtype(py_type, ObjectType)) {
103 pytalloc_Object *ret
104 = (pytalloc_Object *)py_type->tp_alloc(py_type, 0);
106 ret->talloc_ctx = talloc_new(NULL);
107 if (ret->talloc_ctx == NULL) {
108 return NULL;
111 if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
112 return NULL;
114 talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
115 ret->ptr = ptr;
116 return (PyObject *)ret;
117 } else {
118 PyErr_SetString(PyExc_RuntimeError,
119 "pytalloc_steal_ex() called for object type "
120 "not based on talloc");
121 return NULL;
126 * Import an existing talloc pointer into a Python object.
128 _PUBLIC_ PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr)
130 return pytalloc_steal_ex(py_type, ptr, ptr);
135 * Import an existing talloc pointer into a Python object, leaving the
136 * original parent, and creating a reference to the object in the python
137 * object.
139 * We remember the object we hold the reference to (a
140 * possibly-non-talloc pointer), the existing parent (typically the
141 * start of the array) and the new referenced parent. That way we can
142 * cope with the fact that we will have multiple parents, one per time
143 * python sees the object.
145 _PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type,
146 TALLOC_CTX *mem_ctx, void *ptr)
148 PyTypeObject *BaseObjectType = pytalloc_GetBaseObjectType();
149 PyTypeObject *ObjectType = pytalloc_GetObjectType();
151 if (mem_ctx == NULL) {
152 return PyErr_NoMemory();
155 if (PyType_IsSubtype(py_type, BaseObjectType)) {
156 pytalloc_BaseObject *ret
157 = (pytalloc_BaseObject *)py_type->tp_alloc(py_type, 0);
158 ret->talloc_ctx = talloc_new(NULL);
159 if (ret->talloc_ctx == NULL) {
160 return NULL;
162 if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
163 return NULL;
165 talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
166 ret->talloc_ptr_ctx = mem_ctx;
167 ret->ptr = ptr;
168 return (PyObject *)ret;
169 } else if (PyType_IsSubtype(py_type, ObjectType)) {
170 pytalloc_Object *ret
171 = (pytalloc_Object *)py_type->tp_alloc(py_type, 0);
172 ret->talloc_ctx = talloc_new(NULL);
173 if (ret->talloc_ctx == NULL) {
174 return NULL;
176 if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
177 return NULL;
179 talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
180 ret->ptr = ptr;
181 return (PyObject *)ret;
182 } else {
183 PyErr_SetString(PyExc_RuntimeError,
184 "pytalloc_reference_ex() called for object type "
185 "not based on talloc");
186 return NULL;
190 #if PY_MAJOR_VERSION < 3
192 static void py_cobject_talloc_free(void *ptr)
194 talloc_free(ptr);
197 _PUBLIC_ PyObject *pytalloc_CObject_FromTallocPtr(void *ptr)
199 if (ptr == NULL) {
200 Py_RETURN_NONE;
202 return PyCObject_FromVoidPtr(ptr, py_cobject_talloc_free);
205 #endif
207 _PUBLIC_ int pytalloc_Check(PyObject *obj)
209 PyTypeObject *tp = pytalloc_GetObjectType();
211 return PyObject_TypeCheck(obj, tp);
214 _PUBLIC_ int pytalloc_BaseObject_check(PyObject *obj)
216 PyTypeObject *tp = pytalloc_GetBaseObjectType();
218 return PyObject_TypeCheck(obj, tp);
221 _PUBLIC_ size_t pytalloc_BaseObject_size(void)
223 return sizeof(pytalloc_BaseObject);
226 _PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name)
228 void *ptr = _pytalloc_get_ptr(py_obj);
229 void *type_obj = talloc_check_name(ptr, type_name);
231 if (type_obj == NULL) {
232 const char *name = talloc_get_name(ptr);
233 PyErr_Format(PyExc_TypeError, "pytalloc: expected %s, got %s",
234 type_name, name);
235 return NULL;
238 return ptr;
241 _PUBLIC_ void *_pytalloc_get_ptr(PyObject *py_obj)
243 if (pytalloc_BaseObject_check(py_obj)) {
244 return ((pytalloc_BaseObject *)py_obj)->ptr;
246 if (pytalloc_Check(py_obj)) {
247 return ((pytalloc_Object *)py_obj)->ptr;
249 return NULL;
252 _PUBLIC_ TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj)
254 if (pytalloc_BaseObject_check(py_obj)) {
255 return ((pytalloc_BaseObject *)py_obj)->talloc_ptr_ctx;
257 if (pytalloc_Check(py_obj)) {
258 return ((pytalloc_Object *)py_obj)->talloc_ctx;
260 return NULL;
263 _PUBLIC_ int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type)
265 PyTypeObject *talloc_type = pytalloc_GetBaseObjectType();
266 if (talloc_type == NULL) {
267 PyErr_Format(PyExc_TypeError, "pytalloc: unable to get talloc.BaseObject type");
268 return -1;
271 type->tp_base = talloc_type;
272 type->tp_basicsize = pytalloc_BaseObject_size();
274 return PyType_Ready(type);