1/* Wrap void * pointers to be passed between C modules */ 2 3#include "Python.h" 4 5/* Internal structure of PyCapsule */ 6typedef struct { 7 PyObject_HEAD 8 void *pointer; 9 const char *name; 10 void *context; 11 PyCapsule_Destructor destructor; 12} PyCapsule; 13 14 15 16static 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 31static int 32name_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 43PyObject * 44PyCapsule_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 67int 68PyCapsule_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 79void * 80PyCapsule_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 97const char * 98PyCapsule_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 109PyCapsule_Destructor 110PyCapsule_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 121void * 122PyCapsule_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 133int 134PyCapsule_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 152int 153PyCapsule_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 166int 167PyCapsule_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 180int 181PyCapsule_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 194void * 195PyCapsule_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 PyErr_NoMemory(); 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 object = PyImport_ImportModule(trace); 218 if (!object) { 219 PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace); 220 } 221 } else { 222 PyObject *object2 = PyObject_GetAttrString(object, trace); 223 Py_DECREF(object); 224 object = object2; 225 } 226 if (!object) { 227 goto EXIT; 228 } 229 230 trace = dot; 231 } 232 233 /* compare attribute name to module.name by hand */ 234 if (PyCapsule_IsValid(object, name)) { 235 PyCapsule *capsule = (PyCapsule *)object; 236 return_value = capsule->pointer; 237 } else { 238 PyErr_Format(PyExc_AttributeError, 239 "PyCapsule_Import \"%s\" is not valid", 240 name); 241 } 242 243EXIT: 244 Py_XDECREF(object); 245 if (name_dup) { 246 PyMem_Free(name_dup); 247 } 248 return return_value; 249} 250 251 252static void 253capsule_dealloc(PyObject *o) 254{ 255 PyCapsule *capsule = (PyCapsule *)o; 256 if (capsule->destructor) { 257 capsule->destructor(o); 258 } 259 PyObject_Free(o); 260} 261 262 263static PyObject * 264capsule_repr(PyObject *o) 265{ 266 PyCapsule *capsule = (PyCapsule *)o; 267 const char *name; 268 const char *quote; 269 270 if (capsule->name) { 271 quote = "\""; 272 name = capsule->name; 273 } else { 274 quote = ""; 275 name = "NULL"; 276 } 277 278 return PyUnicode_FromFormat("<capsule object %s%s%s at %p>", 279 quote, name, quote, capsule); 280} 281 282 283 284PyDoc_STRVAR(PyCapsule_Type__doc__, 285"Capsule objects let you wrap a C \"void *\" pointer in a Python\n\ 286object. They're a way of passing data through the Python interpreter\n\ 287without creating your own custom type.\n\ 288\n\ 289Capsules are used for communication between extension modules.\n\ 290They provide a way for an extension module to export a C interface\n\ 291to other extension modules, so that extension modules can use the\n\ 292Python import mechanism to link to one another.\n\ 293"); 294 295PyTypeObject PyCapsule_Type = { 296 PyVarObject_HEAD_INIT(&PyType_Type, 0) 297 "PyCapsule", /*tp_name*/ 298 sizeof(PyCapsule), /*tp_basicsize*/ 299 0, /*tp_itemsize*/ 300 /* methods */ 301 capsule_dealloc, /*tp_dealloc*/ 302 0, /*tp_vectorcall_offset*/ 303 0, /*tp_getattr*/ 304 0, /*tp_setattr*/ 305 0, /*tp_as_async*/ 306 capsule_repr, /*tp_repr*/ 307 0, /*tp_as_number*/ 308 0, /*tp_as_sequence*/ 309 0, /*tp_as_mapping*/ 310 0, /*tp_hash*/ 311 0, /*tp_call*/ 312 0, /*tp_str*/ 313 0, /*tp_getattro*/ 314 0, /*tp_setattro*/ 315 0, /*tp_as_buffer*/ 316 0, /*tp_flags*/ 317 PyCapsule_Type__doc__ /*tp_doc*/ 318}; 319 320 321