Merged revisions 81656 via svnmerge from
[python/dscho.git] / Objects / capsule.c
blobe25af6c2aa8f3b79c7b8910fbcc788efba7da7ef
1 /* Wrap void * pointers to be passed between C modules */
3 #include "Python.h"
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;
16 static int
17 _is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule)
19 if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) {
20 PyErr_SetString(PyExc_ValueError, invalid_capsule);
21 return 0;
23 return 1;
26 #define is_legal_capsule(capsule, name) \
27 (_is_legal_capsule(capsule, \
28 name " called with invalid PyCapsule object"))
31 static int
32 name_matches(const char *name1, const char *name2) {
33 /* if either is NULL, */
34 if (!name1 || !name2) {
35 /* they're only the same if they're both NULL. */
36 return name1 == name2;
38 return !strcmp(name1, name2);
43 PyObject *
44 PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
46 PyCapsule *capsule;
48 if (!pointer) {
49 PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
50 return NULL;
53 capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type);
54 if (capsule == NULL) {
55 return NULL;
58 capsule->pointer = pointer;
59 capsule->name = name;
60 capsule->context = NULL;
61 capsule->destructor = destructor;
63 return (PyObject *)capsule;
67 int
68 PyCapsule_IsValid(PyObject *o, const char *name)
70 PyCapsule *capsule = (PyCapsule *)o;
72 return (capsule != NULL &&
73 PyCapsule_CheckExact(capsule) &&
74 capsule->pointer != NULL &&
75 name_matches(capsule->name, name));
79 void *
80 PyCapsule_GetPointer(PyObject *o, const char *name)
82 PyCapsule *capsule = (PyCapsule *)o;
84 if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) {
85 return NULL;
88 if (!name_matches(name, capsule->name)) {
89 PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
90 return NULL;
93 return capsule->pointer;
97 const char *
98 PyCapsule_GetName(PyObject *o)
100 PyCapsule *capsule = (PyCapsule *)o;
102 if (!is_legal_capsule(capsule, "PyCapsule_GetName")) {
103 return NULL;
105 return capsule->name;
109 PyCapsule_Destructor
110 PyCapsule_GetDestructor(PyObject *o)
112 PyCapsule *capsule = (PyCapsule *)o;
114 if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) {
115 return NULL;
117 return capsule->destructor;
121 void *
122 PyCapsule_GetContext(PyObject *o)
124 PyCapsule *capsule = (PyCapsule *)o;
126 if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) {
127 return NULL;
129 return capsule->context;
134 PyCapsule_SetPointer(PyObject *o, void *pointer)
136 PyCapsule *capsule = (PyCapsule *)o;
138 if (!pointer) {
139 PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
140 return -1;
143 if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) {
144 return -1;
147 capsule->pointer = pointer;
148 return 0;
153 PyCapsule_SetName(PyObject *o, const char *name)
155 PyCapsule *capsule = (PyCapsule *)o;
157 if (!is_legal_capsule(capsule, "PyCapsule_SetName")) {
158 return -1;
161 capsule->name = name;
162 return 0;
167 PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor)
169 PyCapsule *capsule = (PyCapsule *)o;
171 if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) {
172 return -1;
175 capsule->destructor = destructor;
176 return 0;
181 PyCapsule_SetContext(PyObject *o, void *context)
183 PyCapsule *capsule = (PyCapsule *)o;
185 if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) {
186 return -1;
189 capsule->context = context;
190 return 0;
194 void *
195 PyCapsule_Import(const char *name, int no_block)
197 PyObject *object = NULL;
198 void *return_value = NULL;
199 char *trace;
200 size_t name_length = (strlen(name) + 1) * sizeof(char);
201 char *name_dup = (char *)PyMem_MALLOC(name_length);
203 if (!name_dup) {
204 return NULL;
207 memcpy(name_dup, name, name_length);
209 trace = name_dup;
210 while (trace) {
211 char *dot = strchr(trace, '.');
212 if (dot) {
213 *dot++ = '\0';
216 if (object == NULL) {
217 if (no_block) {
218 object = PyImport_ImportModuleNoBlock(trace);
219 } else {
220 object = PyImport_ImportModule(trace);
221 if (!object) {
222 PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace);
225 } else {
226 PyObject *object2 = PyObject_GetAttrString(object, trace);
227 Py_DECREF(object);
228 object = object2;
230 if (!object) {
231 goto EXIT;
234 trace = dot;
237 /* compare attribute name to module.name by hand */
238 if (PyCapsule_IsValid(object, name)) {
239 PyCapsule *capsule = (PyCapsule *)object;
240 return_value = capsule->pointer;
241 } else {
242 PyErr_Format(PyExc_AttributeError,
243 "PyCapsule_Import \"%s\" is not valid",
244 name);
247 EXIT:
248 Py_XDECREF(object);
249 if (name_dup) {
250 PyMem_FREE(name_dup);
252 return return_value;
256 static void
257 capsule_dealloc(PyObject *o)
259 PyCapsule *capsule = (PyCapsule *)o;
260 if (capsule->destructor) {
261 capsule->destructor(o);
263 PyObject_DEL(o);
267 static PyObject *
268 capsule_repr(PyObject *o)
270 PyCapsule *capsule = (PyCapsule *)o;
271 const char *name;
272 const char *quote;
274 if (capsule->name) {
275 quote = "\"";
276 name = capsule->name;
277 } else {
278 quote = "";
279 name = "NULL";
282 return PyUnicode_FromFormat("<capsule object %s%s%s at %p>",
283 quote, name, quote, capsule);
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\
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\
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*/