Home | History | Annotate | Download | only in Objects
      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 };
    323 
    324 
    325