Line data Source code
1 : /* Wrap void * pointers to be passed between C modules */
2 :
3 : #include "Python.h"
4 :
5 : /* Internal structure of PyCapsule */
6 : typedef struct {
7 : PyObject_HEAD
8 : void *pointer;
9 : const char *name;
10 : void *context;
11 : PyCapsule_Destructor destructor;
12 : } PyCapsule;
13 :
14 :
15 :
16 : static int
17 1064 : _is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule)
18 : {
19 1064 : if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) {
20 0 : PyErr_SetString(PyExc_ValueError, invalid_capsule);
21 0 : return 0;
22 : }
23 1064 : return 1;
24 : }
25 :
26 : #define is_legal_capsule(capsule, name) \
27 : (_is_legal_capsule(capsule, \
28 : name " called with invalid PyCapsule object"))
29 :
30 :
31 : static int
32 980 : name_matches(const char *name1, const char *name2) {
33 : /* if either is NULL, */
34 980 : if (!name1 || !name2) {
35 : /* they're only the same if they're both NULL. */
36 0 : return name1 == name2;
37 : }
38 980 : return !strcmp(name1, name2);
39 : }
40 :
41 :
42 :
43 : PyObject *
44 1067 : PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
45 : {
46 : PyCapsule *capsule;
47 :
48 1067 : if (!pointer) {
49 0 : PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
50 0 : return NULL;
51 : }
52 :
53 1067 : capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type);
54 1067 : if (capsule == NULL) {
55 0 : return NULL;
56 : }
57 :
58 1067 : capsule->pointer = pointer;
59 1067 : capsule->name = name;
60 1067 : capsule->context = NULL;
61 1067 : capsule->destructor = destructor;
62 :
63 1067 : return (PyObject *)capsule;
64 : }
65 :
66 :
67 : int
68 0 : PyCapsule_IsValid(PyObject *o, const char *name)
69 : {
70 0 : PyCapsule *capsule = (PyCapsule *)o;
71 :
72 0 : return (capsule != NULL &&
73 0 : PyCapsule_CheckExact(capsule) &&
74 0 : capsule->pointer != NULL &&
75 0 : name_matches(capsule->name, name));
76 : }
77 :
78 :
79 : void *
80 980 : PyCapsule_GetPointer(PyObject *o, const char *name)
81 : {
82 980 : PyCapsule *capsule = (PyCapsule *)o;
83 :
84 980 : if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) {
85 0 : return NULL;
86 : }
87 :
88 980 : if (!name_matches(name, capsule->name)) {
89 0 : PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
90 0 : return NULL;
91 : }
92 :
93 980 : return capsule->pointer;
94 : }
95 :
96 :
97 : const char *
98 0 : PyCapsule_GetName(PyObject *o)
99 : {
100 0 : PyCapsule *capsule = (PyCapsule *)o;
101 :
102 0 : if (!is_legal_capsule(capsule, "PyCapsule_GetName")) {
103 0 : return NULL;
104 : }
105 0 : return capsule->name;
106 : }
107 :
108 :
109 : PyCapsule_Destructor
110 0 : PyCapsule_GetDestructor(PyObject *o)
111 : {
112 0 : PyCapsule *capsule = (PyCapsule *)o;
113 :
114 0 : if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) {
115 0 : return NULL;
116 : }
117 0 : return capsule->destructor;
118 : }
119 :
120 :
121 : void *
122 0 : PyCapsule_GetContext(PyObject *o)
123 : {
124 0 : PyCapsule *capsule = (PyCapsule *)o;
125 :
126 0 : if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) {
127 0 : return NULL;
128 : }
129 0 : return capsule->context;
130 : }
131 :
132 :
133 : int
134 0 : PyCapsule_SetPointer(PyObject *o, void *pointer)
135 : {
136 0 : PyCapsule *capsule = (PyCapsule *)o;
137 :
138 0 : if (!pointer) {
139 0 : PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
140 0 : return -1;
141 : }
142 :
143 0 : if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) {
144 0 : return -1;
145 : }
146 :
147 0 : capsule->pointer = pointer;
148 0 : return 0;
149 : }
150 :
151 :
152 : int
153 0 : PyCapsule_SetName(PyObject *o, const char *name)
154 : {
155 0 : PyCapsule *capsule = (PyCapsule *)o;
156 :
157 0 : if (!is_legal_capsule(capsule, "PyCapsule_SetName")) {
158 0 : return -1;
159 : }
160 :
161 0 : capsule->name = name;
162 0 : return 0;
163 : }
164 :
165 :
166 : int
167 84 : PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor)
168 : {
169 84 : PyCapsule *capsule = (PyCapsule *)o;
170 :
171 84 : if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) {
172 0 : return -1;
173 : }
174 :
175 84 : capsule->destructor = destructor;
176 84 : return 0;
177 : }
178 :
179 :
180 : int
181 0 : PyCapsule_SetContext(PyObject *o, void *context)
182 : {
183 0 : PyCapsule *capsule = (PyCapsule *)o;
184 :
185 0 : if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) {
186 0 : return -1;
187 : }
188 :
189 0 : capsule->context = context;
190 0 : return 0;
191 : }
192 :
193 :
194 : void *
195 0 : PyCapsule_Import(const char *name, int no_block)
196 : {
197 0 : PyObject *object = NULL;
198 0 : void *return_value = NULL;
199 : char *trace;
200 0 : size_t name_length = (strlen(name) + 1) * sizeof(char);
201 0 : char *name_dup = (char *)PyMem_MALLOC(name_length);
202 :
203 0 : if (!name_dup) {
204 0 : return NULL;
205 : }
206 :
207 0 : memcpy(name_dup, name, name_length);
208 :
209 0 : trace = name_dup;
210 0 : while (trace) {
211 0 : char *dot = strchr(trace, '.');
212 0 : if (dot) {
213 0 : *dot++ = '\0';
214 : }
215 :
216 0 : if (object == NULL) {
217 0 : if (no_block) {
218 0 : object = PyImport_ImportModuleNoBlock(trace);
219 : } else {
220 0 : object = PyImport_ImportModule(trace);
221 0 : if (!object) {
222 0 : PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace);
223 : }
224 : }
225 : } else {
226 0 : PyObject *object2 = PyObject_GetAttrString(object, trace);
227 0 : Py_DECREF(object);
228 0 : object = object2;
229 : }
230 0 : if (!object) {
231 0 : goto EXIT;
232 : }
233 :
234 0 : trace = dot;
235 : }
236 :
237 : /* compare attribute name to module.name by hand */
238 0 : if (PyCapsule_IsValid(object, name)) {
239 0 : PyCapsule *capsule = (PyCapsule *)object;
240 0 : return_value = capsule->pointer;
241 : } else {
242 0 : PyErr_Format(PyExc_AttributeError,
243 : "PyCapsule_Import \"%s\" is not valid",
244 : name);
245 : }
246 :
247 : EXIT:
248 0 : Py_XDECREF(object);
249 0 : if (name_dup) {
250 0 : PyMem_FREE(name_dup);
251 : }
252 0 : return return_value;
253 : }
254 :
255 :
256 : static void
257 1067 : capsule_dealloc(PyObject *o)
258 : {
259 1067 : PyCapsule *capsule = (PyCapsule *)o;
260 1067 : if (capsule->destructor) {
261 0 : capsule->destructor(o);
262 : }
263 1067 : PyObject_DEL(o);
264 1067 : }
265 :
266 :
267 : static PyObject *
268 0 : capsule_repr(PyObject *o)
269 : {
270 0 : PyCapsule *capsule = (PyCapsule *)o;
271 : const char *name;
272 : const char *quote;
273 :
274 0 : if (capsule->name) {
275 0 : quote = "\"";
276 0 : name = capsule->name;
277 : } else {
278 0 : quote = "";
279 0 : name = "NULL";
280 : }
281 :
282 0 : return PyString_FromFormat("<capsule object %s%s%s at %p>",
283 : quote, name, quote, capsule);
284 : }
285 :
286 :
287 :
288 : PyDoc_STRVAR(PyCapsule_Type__doc__,
289 : "Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
290 : object. They're a way of passing data through the Python interpreter\n\
291 : without creating your own custom type.\n\
292 : \n\
293 : Capsules are used for communication between extension modules.\n\
294 : They provide a way for an extension module to export a C interface\n\
295 : to other extension modules, so that extension modules can use the\n\
296 : Python import mechanism to link to one another.\n\
297 : ");
298 :
299 : PyTypeObject PyCapsule_Type = {
300 : PyVarObject_HEAD_INIT(&PyType_Type, 0)
301 : "PyCapsule", /*tp_name*/
302 : sizeof(PyCapsule), /*tp_basicsize*/
303 : 0, /*tp_itemsize*/
304 : /* methods */
305 : capsule_dealloc, /*tp_dealloc*/
306 : 0, /*tp_print*/
307 : 0, /*tp_getattr*/
308 : 0, /*tp_setattr*/
309 : 0, /*tp_reserved*/
310 : capsule_repr, /*tp_repr*/
311 : 0, /*tp_as_number*/
312 : 0, /*tp_as_sequence*/
313 : 0, /*tp_as_mapping*/
314 : 0, /*tp_hash*/
315 : 0, /*tp_call*/
316 : 0, /*tp_str*/
317 : 0, /*tp_getattro*/
318 : 0, /*tp_setattro*/
319 : 0, /*tp_as_buffer*/
320 : 0, /*tp_flags*/
321 : PyCapsule_Type__doc__ /*tp_doc*/
322 : };
323 :
324 :
|