Python-2.7.3/Objects/capsule.c

No issues found

  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 _is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule)
 18 {
 19     if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) {
 20         PyErr_SetString(PyExc_ValueError, invalid_capsule);
 21         return 0;
 22     }
 23     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 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;
 37     }
 38     return !strcmp(name1, name2);
 39 }
 40 
 41 
 42 
 43 PyObject *
 44 PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
 45 {
 46     PyCapsule *capsule;
 47 
 48     if (!pointer) {
 49         PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
 50         return NULL;
 51     }
 52 
 53     capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type);
 54     if (capsule == NULL) {
 55         return NULL;
 56     }
 57 
 58     capsule->pointer = pointer;
 59     capsule->name = name;
 60     capsule->context = NULL;
 61     capsule->destructor = destructor;
 62 
 63     return (PyObject *)capsule;
 64 }
 65 
 66 
 67 int
 68 PyCapsule_IsValid(PyObject *o, const char *name)
 69 {
 70     PyCapsule *capsule = (PyCapsule *)o;
 71 
 72     return (capsule != NULL &&
 73             PyCapsule_CheckExact(capsule) &&
 74             capsule->pointer != NULL &&
 75             name_matches(capsule->name, name));
 76 }
 77 
 78 
 79 void *
 80 PyCapsule_GetPointer(PyObject *o, const char *name)
 81 {
 82     PyCapsule *capsule = (PyCapsule *)o;
 83 
 84     if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) {
 85         return NULL;
 86     }
 87 
 88     if (!name_matches(name, capsule->name)) {
 89         PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
 90         return NULL;
 91     }
 92 
 93     return capsule->pointer;
 94 }
 95 
 96 
 97 const char *
 98 PyCapsule_GetName(PyObject *o)
 99 {
100     PyCapsule *capsule = (PyCapsule *)o;
101 
102     if (!is_legal_capsule(capsule, "PyCapsule_GetName")) {
103         return NULL;
104     }
105     return capsule->name;
106 }
107 
108 
109 PyCapsule_Destructor
110 PyCapsule_GetDestructor(PyObject *o)
111 {
112     PyCapsule *capsule = (PyCapsule *)o;
113 
114     if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) {
115         return NULL;
116     }
117     return capsule->destructor;
118 }
119 
120 
121 void *
122 PyCapsule_GetContext(PyObject *o)
123 {
124     PyCapsule *capsule = (PyCapsule *)o;
125 
126     if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) {
127         return NULL;
128     }
129     return capsule->context;
130 }
131 
132 
133 int
134 PyCapsule_SetPointer(PyObject *o, void *pointer)
135 {
136     PyCapsule *capsule = (PyCapsule *)o;
137 
138     if (!pointer) {
139         PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
140         return -1;
141     }
142 
143     if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) {
144         return -1;
145     }
146 
147     capsule->pointer = pointer;
148     return 0;
149 }
150 
151 
152 int
153 PyCapsule_SetName(PyObject *o, const char *name)
154 {
155     PyCapsule *capsule = (PyCapsule *)o;
156 
157     if (!is_legal_capsule(capsule, "PyCapsule_SetName")) {
158         return -1;
159     }
160 
161     capsule->name = name;
162     return 0;
163 }
164 
165 
166 int
167 PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor)
168 {
169     PyCapsule *capsule = (PyCapsule *)o;
170 
171     if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) {
172         return -1;
173     }
174 
175     capsule->destructor = destructor;
176     return 0;
177 }
178 
179 
180 int
181 PyCapsule_SetContext(PyObject *o, void *context)
182 {
183     PyCapsule *capsule = (PyCapsule *)o;
184 
185     if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) {
186         return -1;
187     }
188 
189     capsule->context = context;
190     return 0;
191 }
192 
193 
194 void *
195 PyCapsule_Import(const char *name, int no_block)
196 {
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);
202 
203     if (!name_dup) {
204         return NULL;
205     }
206 
207     memcpy(name_dup, name, name_length);
208 
209     trace = name_dup;
210     while (trace) {
211         char *dot = strchr(trace, '.');
212         if (dot) {
213             *dot++ = '\0';
214         }
215 
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);
223                 }
224             }
225         } else {
226             PyObject *object2 = PyObject_GetAttrString(object, trace);
227             Py_DECREF(object);
228             object = object2;
229         }
230         if (!object) {
231             goto EXIT;
232         }
233 
234         trace = dot;
235     }
236 
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);
245     }
246 
247 EXIT:
248     Py_XDECREF(object);
249     if (name_dup) {
250         PyMem_FREE(name_dup);
251     }
252     return return_value;
253 }
254 
255 
256 static void
257 capsule_dealloc(PyObject *o)
258 {
259     PyCapsule *capsule = (PyCapsule *)o;
260     if (capsule->destructor) {
261         capsule->destructor(o);
262     }
263     PyObject_DEL(o);
264 }
265 
266 
267 static PyObject *
268 capsule_repr(PyObject *o)
269 {
270     PyCapsule *capsule = (PyCapsule *)o;
271     const char *name;
272     const char *quote;
273 
274     if (capsule->name) {
275         quote = "\"";
276         name = capsule->name;
277     } else {
278         quote = "";
279         name = "NULL";
280     }
281 
282     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 };