• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   ToDo:
3 
4   Get rid of the checker (and also the converters) field in PyCFuncPtrObject and
5   StgDictObject, and replace them by slot functions in StgDictObject.
6 
7   think about a buffer-like object (memory? bytes?)
8 
9   Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
10   What about c_char and c_wchar arrays then?
11 
12   Add from_mmap, from_file, from_string metaclass methods.
13 
14   Maybe we can get away with from_file (calls read) and with a from_buffer
15   method?
16 
17   And what about the to_mmap, to_file, to_str(?) methods?  They would clobber
18   the namespace, probably. So, functions instead? And we already have memmove...
19 */
20 
21 /*
22 
23 Name                    methods, members, getsets
24 ==============================================================================
25 
26 PyCStructType_Type              __new__(), from_address(), __mul__(), from_param()
27 UnionType_Type          __new__(), from_address(), __mul__(), from_param()
28 PyCPointerType_Type     __new__(), from_address(), __mul__(), from_param(), set_type()
29 PyCArrayType_Type               __new__(), from_address(), __mul__(), from_param()
30 PyCSimpleType_Type              __new__(), from_address(), __mul__(), from_param()
31 
32 PyCData_Type
33   Struct_Type           __new__(), __init__()
34   PyCPointer_Type               __new__(), __init__(), _as_parameter_, contents
35   PyCArray_Type         __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
36   Simple_Type           __new__(), __init__(), _as_parameter_
37 
38 PyCField_Type
39 PyCStgDict_Type
40 
41 ==============================================================================
42 
43 class methods
44 -------------
45 
46 It has some similarity to the byref() construct compared to pointer()
47 from_address(addr)
48     - construct an instance from a given memory block (sharing this memory block)
49 
50 from_param(obj)
51     - typecheck and convert a Python object into a C function call parameter
52       The result may be an instance of the type, or an integer or tuple
53       (typecode, value[, obj])
54 
55 instance methods/properties
56 ---------------------------
57 
58 _as_parameter_
59     - convert self into a C function call parameter
60       This is either an integer, or a 3-tuple (typecode, value, obj)
61 
62 functions
63 ---------
64 
65 sizeof(cdata)
66     - return the number of bytes the buffer contains
67 
68 sizeof(ctype)
69     - return the number of bytes the buffer of an instance would contain
70 
71 byref(cdata)
72 
73 addressof(cdata)
74 
75 pointer(cdata)
76 
77 POINTER(ctype)
78 
79 bytes(cdata)
80     - return the buffer contents as a sequence of bytes (which is currently a string)
81 
82 */
83 
84 /*
85  * PyCStgDict_Type
86  * PyCStructType_Type
87  * UnionType_Type
88  * PyCPointerType_Type
89  * PyCArrayType_Type
90  * PyCSimpleType_Type
91  *
92  * PyCData_Type
93  * Struct_Type
94  * Union_Type
95  * PyCArray_Type
96  * Simple_Type
97  * PyCPointer_Type
98  * PyCField_Type
99  *
100  */
101 
102 #define PY_SSIZE_T_CLEAN
103 
104 #include "Python.h"
105 #include "structmember.h"
106 
107 #include <ffi.h>
108 #ifdef MS_WIN32
109 #include <windows.h>
110 #include <malloc.h>
111 #ifndef IS_INTRESOURCE
112 #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
113 #endif
114 #else
115 #include "ctypes_dlfcn.h"
116 #endif
117 #include "ctypes.h"
118 
119 PyObject *PyExc_ArgError = NULL;
120 
121 /* This dict maps ctypes types to POINTER types */
122 PyObject *_ctypes_ptrtype_cache = NULL;
123 
124 static PyTypeObject Simple_Type;
125 
126 /* a callable object used for unpickling */
127 static PyObject *_unpickle;
128 
129 
130 
131 /****************************************************************/
132 
133 typedef struct {
134     PyObject_HEAD
135     PyObject *key;
136     PyObject *dict;
137 } DictRemoverObject;
138 
139 static void
_DictRemover_dealloc(PyObject * myself)140 _DictRemover_dealloc(PyObject *myself)
141 {
142     DictRemoverObject *self = (DictRemoverObject *)myself;
143     Py_XDECREF(self->key);
144     Py_XDECREF(self->dict);
145     Py_TYPE(self)->tp_free(myself);
146 }
147 
148 static PyObject *
_DictRemover_call(PyObject * myself,PyObject * args,PyObject * kw)149 _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw)
150 {
151     DictRemoverObject *self = (DictRemoverObject *)myself;
152     if (self->key && self->dict) {
153         if (-1 == PyDict_DelItem(self->dict, self->key)) {
154             _PyErr_WriteUnraisableMsg("on calling _ctypes.DictRemover", NULL);
155         }
156         Py_CLEAR(self->key);
157         Py_CLEAR(self->dict);
158     }
159     Py_RETURN_NONE;
160 }
161 
162 static PyTypeObject DictRemover_Type = {
163     PyVarObject_HEAD_INIT(NULL, 0)
164     "_ctypes.DictRemover",                      /* tp_name */
165     sizeof(DictRemoverObject),                  /* tp_basicsize */
166     0,                                          /* tp_itemsize */
167     _DictRemover_dealloc,                       /* tp_dealloc */
168     0,                                          /* tp_vectorcall_offset */
169     0,                                          /* tp_getattr */
170     0,                                          /* tp_setattr */
171     0,                                          /* tp_as_async */
172     0,                                          /* tp_repr */
173     0,                                          /* tp_as_number */
174     0,                                          /* tp_as_sequence */
175     0,                                          /* tp_as_mapping */
176     0,                                          /* tp_hash */
177     _DictRemover_call,                          /* tp_call */
178     0,                                          /* tp_str */
179     0,                                          /* tp_getattro */
180     0,                                          /* tp_setattro */
181     0,                                          /* tp_as_buffer */
182 /* XXX should participate in GC? */
183     Py_TPFLAGS_DEFAULT,                         /* tp_flags */
184     "deletes a key from a dictionary",          /* tp_doc */
185     0,                                          /* tp_traverse */
186     0,                                          /* tp_clear */
187     0,                                          /* tp_richcompare */
188     0,                                          /* tp_weaklistoffset */
189     0,                                          /* tp_iter */
190     0,                                          /* tp_iternext */
191     0,                                          /* tp_methods */
192     0,                                          /* tp_members */
193     0,                                          /* tp_getset */
194     0,                                          /* tp_base */
195     0,                                          /* tp_dict */
196     0,                                          /* tp_descr_get */
197     0,                                          /* tp_descr_set */
198     0,                                          /* tp_dictoffset */
199     0,                                          /* tp_init */
200     0,                                          /* tp_alloc */
201     0,                                          /* tp_new */
202     0,                                          /* tp_free */
203 };
204 
205 int
PyDict_SetItemProxy(PyObject * dict,PyObject * key,PyObject * item)206 PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item)
207 {
208     PyObject *obj;
209     DictRemoverObject *remover;
210     PyObject *proxy;
211     int result;
212 
213     obj = _PyObject_CallNoArg((PyObject *)&DictRemover_Type);
214     if (obj == NULL)
215         return -1;
216 
217     remover = (DictRemoverObject *)obj;
218     assert(remover->key == NULL);
219     assert(remover->dict == NULL);
220     Py_INCREF(key);
221     remover->key = key;
222     Py_INCREF(dict);
223     remover->dict = dict;
224 
225     proxy = PyWeakref_NewProxy(item, obj);
226     Py_DECREF(obj);
227     if (proxy == NULL)
228         return -1;
229 
230     result = PyDict_SetItem(dict, key, proxy);
231     Py_DECREF(proxy);
232     return result;
233 }
234 
235 PyObject *
PyDict_GetItemProxy(PyObject * dict,PyObject * key)236 PyDict_GetItemProxy(PyObject *dict, PyObject *key)
237 {
238     PyObject *result;
239     PyObject *item = PyDict_GetItemWithError(dict, key);
240 
241     if (item == NULL)
242         return NULL;
243     if (!PyWeakref_CheckProxy(item))
244         return item;
245     result = PyWeakref_GET_OBJECT(item);
246     if (result == Py_None)
247         return NULL;
248     return result;
249 }
250 
251 /******************************************************************/
252 
253 /*
254   Allocate a memory block for a pep3118 format string, filled with
255   a suitable PEP 3118 type code corresponding to the given ctypes
256   type. Returns NULL on failure, with the error indicator set.
257 
258   This produces type codes in the standard size mode (cf. struct module),
259   since the endianness may need to be swapped to a non-native one
260   later on.
261  */
262 static char *
_ctypes_alloc_format_string_for_type(char code,int big_endian)263 _ctypes_alloc_format_string_for_type(char code, int big_endian)
264 {
265     char *result;
266     char pep_code = '\0';
267 
268     switch (code) {
269 #if SIZEOF_INT == 2
270     case 'i': pep_code = 'h'; break;
271     case 'I': pep_code = 'H'; break;
272 #elif SIZEOF_INT == 4
273     case 'i': pep_code = 'i'; break;
274     case 'I': pep_code = 'I'; break;
275 #elif SIZEOF_INT == 8
276     case 'i': pep_code = 'q'; break;
277     case 'I': pep_code = 'Q'; break;
278 #else
279 # error SIZEOF_INT has an unexpected value
280 #endif /* SIZEOF_INT */
281 #if SIZEOF_LONG == 4
282     case 'l': pep_code = 'l'; break;
283     case 'L': pep_code = 'L'; break;
284 #elif SIZEOF_LONG == 8
285     case 'l': pep_code = 'q'; break;
286     case 'L': pep_code = 'Q'; break;
287 #else
288 # error SIZEOF_LONG has an unexpected value
289 #endif /* SIZEOF_LONG */
290 #if SIZEOF__BOOL == 1
291     case '?': pep_code = '?'; break;
292 #elif SIZEOF__BOOL == 2
293     case '?': pep_code = 'H'; break;
294 #elif SIZEOF__BOOL == 4
295     case '?': pep_code = 'L'; break;
296 #elif SIZEOF__BOOL == 8
297     case '?': pep_code = 'Q'; break;
298 #else
299 # error SIZEOF__BOOL has an unexpected value
300 #endif /* SIZEOF__BOOL */
301     default:
302         /* The standard-size code is the same as the ctypes one */
303         pep_code = code;
304         break;
305     }
306 
307     result = PyMem_Malloc(3);
308     if (result == NULL) {
309         PyErr_NoMemory();
310         return NULL;
311     }
312 
313     result[0] = big_endian ? '>' : '<';
314     result[1] = pep_code;
315     result[2] = '\0';
316     return result;
317 }
318 
319 /*
320   Allocate a memory block for a pep3118 format string, copy prefix (if
321   non-null) and suffix into it.  Returns NULL on failure, with the error
322   indicator set.  If called with a suffix of NULL the error indicator must
323   already be set.
324  */
325 char *
_ctypes_alloc_format_string(const char * prefix,const char * suffix)326 _ctypes_alloc_format_string(const char *prefix, const char *suffix)
327 {
328     size_t len;
329     char *result;
330 
331     if (suffix == NULL) {
332         assert(PyErr_Occurred());
333         return NULL;
334     }
335     len = strlen(suffix);
336     if (prefix)
337         len += strlen(prefix);
338     result = PyMem_Malloc(len + 1);
339     if (result == NULL) {
340         PyErr_NoMemory();
341         return NULL;
342     }
343     if (prefix)
344         strcpy(result, prefix);
345     else
346         result[0] = '\0';
347     strcat(result, suffix);
348     return result;
349 }
350 
351 /*
352   Allocate a memory block for a pep3118 format string, adding
353   the given prefix (if non-null), an additional shape prefix, and a suffix.
354   Returns NULL on failure, with the error indicator set.  If called with
355   a suffix of NULL the error indicator must already be set.
356  */
357 char *
_ctypes_alloc_format_string_with_shape(int ndim,const Py_ssize_t * shape,const char * prefix,const char * suffix)358 _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
359                                        const char *prefix, const char *suffix)
360 {
361     char *new_prefix;
362     char *result;
363     char buf[32];
364     Py_ssize_t prefix_len;
365     int k;
366 
367     prefix_len = 32 * ndim + 3;
368     if (prefix)
369         prefix_len += strlen(prefix);
370     new_prefix = PyMem_Malloc(prefix_len);
371     if (new_prefix == NULL) {
372         PyErr_NoMemory();
373         return NULL;
374     }
375     new_prefix[0] = '\0';
376     if (prefix)
377         strcpy(new_prefix, prefix);
378     if (ndim > 0) {
379         /* Add the prefix "(shape[0],shape[1],...,shape[ndim-1])" */
380         strcat(new_prefix, "(");
381         for (k = 0; k < ndim; ++k) {
382             if (k < ndim-1) {
383                 sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]);
384             } else {
385                 sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]);
386             }
387             strcat(new_prefix, buf);
388         }
389     }
390     result = _ctypes_alloc_format_string(new_prefix, suffix);
391     PyMem_Free(new_prefix);
392     return result;
393 }
394 
395 /* StructParamObject and StructParam_Type are used in _ctypes_callproc()
396    for argument.keep to call PyMem_Free(ptr) on Py_DECREF(argument).
397 
398    StructUnionType_paramfunc() creates such object when a ctypes Structure is
399    passed by copy to a C function. */
400 typedef struct {
401     PyObject_HEAD
402     void *ptr;
403 } StructParamObject;
404 
405 
406 static void
StructParam_dealloc(PyObject * myself)407 StructParam_dealloc(PyObject *myself)
408 {
409     StructParamObject *self = (StructParamObject *)myself;
410     PyMem_Free(self->ptr);
411     Py_TYPE(self)->tp_free(myself);
412 }
413 
414 
415 static PyTypeObject StructParam_Type = {
416     PyVarObject_HEAD_INIT(NULL, 0)
417     .tp_name = "_ctypes.StructParam_Type",
418     .tp_basicsize = sizeof(StructParamObject),
419     .tp_dealloc = StructParam_dealloc,
420     .tp_flags = Py_TPFLAGS_DEFAULT,
421 };
422 
423 
424 /*
425   PyCStructType_Type - a meta type/class.  Creating a new class using this one as
426   __metaclass__ will call the constructor StructUnionType_new.  It replaces the
427   tp_dict member with a new instance of StgDict, and initializes the C
428   accessible fields somehow.
429 */
430 
431 static PyCArgObject *
StructUnionType_paramfunc(CDataObject * self)432 StructUnionType_paramfunc(CDataObject *self)
433 {
434     PyCArgObject *parg;
435     PyObject *obj;
436     StgDictObject *stgdict;
437     void *ptr;
438 
439     if ((size_t)self->b_size > sizeof(void*)) {
440         ptr = PyMem_Malloc(self->b_size);
441         if (ptr == NULL) {
442             return NULL;
443         }
444         memcpy(ptr, self->b_ptr, self->b_size);
445 
446         /* Create a Python object which calls PyMem_Free(ptr) in
447            its deallocator. The object will be destroyed
448            at _ctypes_callproc() cleanup. */
449         obj = (&StructParam_Type)->tp_alloc(&StructParam_Type, 0);
450         if (obj == NULL) {
451             PyMem_Free(ptr);
452             return NULL;
453         }
454 
455         StructParamObject *struct_param = (StructParamObject *)obj;
456         struct_param->ptr = ptr;
457     } else {
458         ptr = self->b_ptr;
459         obj = (PyObject *)self;
460         Py_INCREF(obj);
461     }
462 
463     parg = PyCArgObject_new();
464     if (parg == NULL) {
465         Py_DECREF(obj);
466         return NULL;
467     }
468 
469     parg->tag = 'V';
470     stgdict = PyObject_stgdict((PyObject *)self);
471     assert(stgdict); /* Cannot be NULL for structure/union instances */
472     parg->pffi_type = &stgdict->ffi_type_pointer;
473     parg->value.p = ptr;
474     parg->size = self->b_size;
475     parg->obj = obj;
476     return parg;
477 }
478 
479 static PyObject *
StructUnionType_new(PyTypeObject * type,PyObject * args,PyObject * kwds,int isStruct)480 StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
481 {
482     PyTypeObject *result;
483     PyObject *fields;
484     StgDictObject *dict;
485     _Py_IDENTIFIER(_abstract_);
486     _Py_IDENTIFIER(_fields_);
487 
488     /* create the new instance (which is a class,
489        since we are a metatype!) */
490     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
491     if (!result)
492         return NULL;
493 
494     /* keep this for bw compatibility */
495     if (_PyDict_GetItemIdWithError(result->tp_dict, &PyId__abstract_))
496         return (PyObject *)result;
497     if (PyErr_Occurred()) {
498         Py_DECREF(result);
499         return NULL;
500     }
501 
502     dict = (StgDictObject *)_PyObject_CallNoArg((PyObject *)&PyCStgDict_Type);
503     if (!dict) {
504         Py_DECREF(result);
505         return NULL;
506     }
507     if (!isStruct) {
508         dict->flags |= TYPEFLAG_HASUNION;
509     }
510     /* replace the class dict by our updated stgdict, which holds info
511        about storage requirements of the instances */
512     if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
513         Py_DECREF(result);
514         Py_DECREF((PyObject *)dict);
515         return NULL;
516     }
517     Py_SETREF(result->tp_dict, (PyObject *)dict);
518     dict->format = _ctypes_alloc_format_string(NULL, "B");
519     if (dict->format == NULL) {
520         Py_DECREF(result);
521         return NULL;
522     }
523 
524     dict->paramfunc = StructUnionType_paramfunc;
525 
526     fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_);
527     if (fields) {
528         if (_PyObject_SetAttrId((PyObject *)result, &PyId__fields_, fields) < 0) {
529             Py_DECREF(result);
530             return NULL;
531         }
532         return (PyObject *)result;
533     }
534     else if (PyErr_Occurred()) {
535         Py_DECREF(result);
536         return NULL;
537     }
538     else {
539         StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
540 
541         if (basedict == NULL)
542             return (PyObject *)result;
543         /* copy base dict */
544         if (-1 == PyCStgDict_clone(dict, basedict)) {
545             Py_DECREF(result);
546             return NULL;
547         }
548         dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
549         basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
550         return (PyObject *)result;
551     }
552 }
553 
554 static PyObject *
PyCStructType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)555 PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
556 {
557     return StructUnionType_new(type, args, kwds, 1);
558 }
559 
560 static PyObject *
UnionType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)561 UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
562 {
563     return StructUnionType_new(type, args, kwds, 0);
564 }
565 
566 static const char from_address_doc[] =
567 "C.from_address(integer) -> C instance\naccess a C instance at the specified address";
568 
569 static PyObject *
CDataType_from_address(PyObject * type,PyObject * value)570 CDataType_from_address(PyObject *type, PyObject *value)
571 {
572     void *buf;
573     if (!PyLong_Check(value)) {
574         PyErr_SetString(PyExc_TypeError,
575                         "integer expected");
576         return NULL;
577     }
578     buf = (void *)PyLong_AsVoidPtr(value);
579     if (PyErr_Occurred())
580         return NULL;
581     return PyCData_AtAddress(type, buf);
582 }
583 
584 static const char from_buffer_doc[] =
585 "C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer";
586 
587 static int
588 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);
589 
590 static PyObject *
CDataType_from_buffer(PyObject * type,PyObject * args)591 CDataType_from_buffer(PyObject *type, PyObject *args)
592 {
593     PyObject *obj;
594     PyObject *mv;
595     PyObject *result;
596     Py_buffer *buffer;
597     Py_ssize_t offset = 0;
598 
599     StgDictObject *dict = PyType_stgdict(type);
600     if (!dict) {
601         PyErr_SetString(PyExc_TypeError, "abstract class");
602         return NULL;
603     }
604 
605     if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset))
606         return NULL;
607 
608     mv = PyMemoryView_FromObject(obj);
609     if (mv == NULL)
610         return NULL;
611 
612     buffer = PyMemoryView_GET_BUFFER(mv);
613 
614     if (buffer->readonly) {
615         PyErr_SetString(PyExc_TypeError,
616             "underlying buffer is not writable");
617         Py_DECREF(mv);
618         return NULL;
619     }
620 
621     if (!PyBuffer_IsContiguous(buffer, 'C')) {
622         PyErr_SetString(PyExc_TypeError,
623             "underlying buffer is not C contiguous");
624         Py_DECREF(mv);
625         return NULL;
626     }
627 
628     if (offset < 0) {
629         PyErr_SetString(PyExc_ValueError,
630                         "offset cannot be negative");
631         Py_DECREF(mv);
632         return NULL;
633     }
634 
635     if (dict->size > buffer->len - offset) {
636         PyErr_Format(PyExc_ValueError,
637                      "Buffer size too small "
638                      "(%zd instead of at least %zd bytes)",
639                      buffer->len, dict->size + offset);
640         Py_DECREF(mv);
641         return NULL;
642     }
643 
644     if (PySys_Audit("ctypes.cdata/buffer", "nnn",
645                     (Py_ssize_t)buffer->buf, buffer->len, offset) < 0) {
646         Py_DECREF(mv);
647         return NULL;
648     }
649 
650     result = PyCData_AtAddress(type, (char *)buffer->buf + offset);
651     if (result == NULL) {
652         Py_DECREF(mv);
653         return NULL;
654     }
655 
656     if (-1 == KeepRef((CDataObject *)result, -1, mv)) {
657         Py_DECREF(result);
658         return NULL;
659     }
660 
661     return result;
662 }
663 
664 static const char from_buffer_copy_doc[] =
665 "C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer";
666 
667 static PyObject *
668 GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
669 
670 static PyObject *
CDataType_from_buffer_copy(PyObject * type,PyObject * args)671 CDataType_from_buffer_copy(PyObject *type, PyObject *args)
672 {
673     Py_buffer buffer;
674     Py_ssize_t offset = 0;
675     PyObject *result;
676     StgDictObject *dict = PyType_stgdict(type);
677     if (!dict) {
678         PyErr_SetString(PyExc_TypeError, "abstract class");
679         return NULL;
680     }
681 
682     if (!PyArg_ParseTuple(args, "y*|n:from_buffer_copy", &buffer, &offset))
683         return NULL;
684 
685     if (offset < 0) {
686         PyErr_SetString(PyExc_ValueError,
687                         "offset cannot be negative");
688         PyBuffer_Release(&buffer);
689         return NULL;
690     }
691 
692     if (dict->size > buffer.len - offset) {
693         PyErr_Format(PyExc_ValueError,
694                      "Buffer size too small (%zd instead of at least %zd bytes)",
695                      buffer.len, dict->size + offset);
696         PyBuffer_Release(&buffer);
697         return NULL;
698     }
699 
700     if (PySys_Audit("ctypes.cdata/buffer", "nnn",
701                     (Py_ssize_t)buffer.buf, buffer.len, offset) < 0) {
702         PyBuffer_Release(&buffer);
703         return NULL;
704     }
705 
706     result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL);
707     if (result != NULL) {
708         memcpy(((CDataObject *)result)->b_ptr,
709                (char *)buffer.buf + offset, dict->size);
710     }
711     PyBuffer_Release(&buffer);
712     return result;
713 }
714 
715 static const char in_dll_doc[] =
716 "C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
717 
718 static PyObject *
CDataType_in_dll(PyObject * type,PyObject * args)719 CDataType_in_dll(PyObject *type, PyObject *args)
720 {
721     PyObject *dll;
722     char *name;
723     PyObject *obj;
724     void *handle;
725     void *address;
726 
727     if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
728         return NULL;
729     if (PySys_Audit("ctypes.dlsym", "O", args) < 0) {
730         return NULL;
731     }
732 
733     obj = PyObject_GetAttrString(dll, "_handle");
734     if (!obj)
735         return NULL;
736     if (!PyLong_Check(obj)) {
737         PyErr_SetString(PyExc_TypeError,
738                         "the _handle attribute of the second argument must be an integer");
739         Py_DECREF(obj);
740         return NULL;
741     }
742     handle = (void *)PyLong_AsVoidPtr(obj);
743     Py_DECREF(obj);
744     if (PyErr_Occurred()) {
745         PyErr_SetString(PyExc_ValueError,
746                         "could not convert the _handle attribute to a pointer");
747         return NULL;
748     }
749 
750 #ifdef MS_WIN32
751     Py_BEGIN_ALLOW_THREADS
752     address = (void *)GetProcAddress(handle, name);
753     Py_END_ALLOW_THREADS
754     if (!address) {
755         PyErr_Format(PyExc_ValueError,
756                      "symbol '%s' not found",
757                      name);
758         return NULL;
759     }
760 #else
761     address = (void *)ctypes_dlsym(handle, name);
762     if (!address) {
763 #ifdef __CYGWIN__
764 /* dlerror() isn't very helpful on cygwin */
765         PyErr_Format(PyExc_ValueError,
766                      "symbol '%s' not found",
767                      name);
768 #else
769         PyErr_SetString(PyExc_ValueError, ctypes_dlerror());
770 #endif
771         return NULL;
772     }
773 #endif
774     return PyCData_AtAddress(type, address);
775 }
776 
777 static const char from_param_doc[] =
778 "Convert a Python object into a function call parameter.";
779 
780 static PyObject *
CDataType_from_param(PyObject * type,PyObject * value)781 CDataType_from_param(PyObject *type, PyObject *value)
782 {
783     _Py_IDENTIFIER(_as_parameter_);
784     PyObject *as_parameter;
785     int res = PyObject_IsInstance(value, type);
786     if (res == -1)
787         return NULL;
788     if (res) {
789         Py_INCREF(value);
790         return value;
791     }
792     if (PyCArg_CheckExact(value)) {
793         PyCArgObject *p = (PyCArgObject *)value;
794         PyObject *ob = p->obj;
795         const char *ob_name;
796         StgDictObject *dict;
797         dict = PyType_stgdict(type);
798 
799         /* If we got a PyCArgObject, we must check if the object packed in it
800            is an instance of the type's dict->proto */
801         if(dict && ob) {
802             res = PyObject_IsInstance(ob, dict->proto);
803             if (res == -1)
804                 return NULL;
805             if (res) {
806                 Py_INCREF(value);
807                 return value;
808             }
809         }
810         ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
811         PyErr_Format(PyExc_TypeError,
812                      "expected %s instance instead of pointer to %s",
813                      ((PyTypeObject *)type)->tp_name, ob_name);
814         return NULL;
815     }
816 
817     if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
818         return NULL;
819     }
820     if (as_parameter) {
821         value = CDataType_from_param(type, as_parameter);
822         Py_DECREF(as_parameter);
823         return value;
824     }
825     PyErr_Format(PyExc_TypeError,
826                  "expected %s instance instead of %s",
827                  ((PyTypeObject *)type)->tp_name,
828                  Py_TYPE(value)->tp_name);
829     return NULL;
830 }
831 
832 static PyMethodDef CDataType_methods[] = {
833     { "from_param", CDataType_from_param, METH_O, from_param_doc },
834     { "from_address", CDataType_from_address, METH_O, from_address_doc },
835     { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
836     { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
837     { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
838     { NULL, NULL },
839 };
840 
841 static PyObject *
CDataType_repeat(PyObject * self,Py_ssize_t length)842 CDataType_repeat(PyObject *self, Py_ssize_t length)
843 {
844     if (length < 0)
845         return PyErr_Format(PyExc_ValueError,
846                             "Array length must be >= 0, not %zd",
847                             length);
848     return PyCArrayType_from_ctype(self, length);
849 }
850 
851 static PySequenceMethods CDataType_as_sequence = {
852     0,                          /* inquiry sq_length; */
853     0,                          /* binaryfunc sq_concat; */
854     CDataType_repeat,           /* intargfunc sq_repeat; */
855     0,                          /* intargfunc sq_item; */
856     0,                          /* intintargfunc sq_slice; */
857     0,                          /* intobjargproc sq_ass_item; */
858     0,                          /* intintobjargproc sq_ass_slice; */
859     0,                          /* objobjproc sq_contains; */
860 
861     0,                          /* binaryfunc sq_inplace_concat; */
862     0,                          /* intargfunc sq_inplace_repeat; */
863 };
864 
865 static int
CDataType_clear(PyTypeObject * self)866 CDataType_clear(PyTypeObject *self)
867 {
868     StgDictObject *dict = PyType_stgdict((PyObject *)self);
869     if (dict)
870         Py_CLEAR(dict->proto);
871     return PyType_Type.tp_clear((PyObject *)self);
872 }
873 
874 static int
CDataType_traverse(PyTypeObject * self,visitproc visit,void * arg)875 CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
876 {
877     StgDictObject *dict = PyType_stgdict((PyObject *)self);
878     if (dict)
879         Py_VISIT(dict->proto);
880     return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
881 }
882 
883 static int
PyCStructType_setattro(PyObject * self,PyObject * key,PyObject * value)884 PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
885 {
886     /* XXX Should we disallow deleting _fields_? */
887     if (-1 == PyType_Type.tp_setattro(self, key, value))
888         return -1;
889 
890     if (value && PyUnicode_Check(key) &&
891         _PyUnicode_EqualToASCIIString(key, "_fields_"))
892         return PyCStructUnionType_update_stgdict(self, value, 1);
893     return 0;
894 }
895 
896 
897 static int
UnionType_setattro(PyObject * self,PyObject * key,PyObject * value)898 UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
899 {
900     /* XXX Should we disallow deleting _fields_? */
901     if (-1 == PyObject_GenericSetAttr(self, key, value))
902         return -1;
903 
904     if (PyUnicode_Check(key) &&
905         _PyUnicode_EqualToASCIIString(key, "_fields_"))
906         return PyCStructUnionType_update_stgdict(self, value, 0);
907     return 0;
908 }
909 
910 
911 PyTypeObject PyCStructType_Type = {
912     PyVarObject_HEAD_INIT(NULL, 0)
913     "_ctypes.PyCStructType",                            /* tp_name */
914     0,                                          /* tp_basicsize */
915     0,                                          /* tp_itemsize */
916     0,                                          /* tp_dealloc */
917     0,                                          /* tp_vectorcall_offset */
918     0,                                          /* tp_getattr */
919     0,                                          /* tp_setattr */
920     0,                                          /* tp_as_async */
921     0,                                          /* tp_repr */
922     0,                                          /* tp_as_number */
923     &CDataType_as_sequence,                     /* tp_as_sequence */
924     0,                                          /* tp_as_mapping */
925     0,                                          /* tp_hash */
926     0,                                          /* tp_call */
927     0,                                          /* tp_str */
928     0,                                          /* tp_getattro */
929     PyCStructType_setattro,                     /* tp_setattro */
930     0,                                          /* tp_as_buffer */
931     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
932     "metatype for the CData Objects",           /* tp_doc */
933     (traverseproc)CDataType_traverse,           /* tp_traverse */
934     (inquiry)CDataType_clear,                   /* tp_clear */
935     0,                                          /* tp_richcompare */
936     0,                                          /* tp_weaklistoffset */
937     0,                                          /* tp_iter */
938     0,                                          /* tp_iternext */
939     CDataType_methods,                          /* tp_methods */
940     0,                                          /* tp_members */
941     0,                                          /* tp_getset */
942     0,                                          /* tp_base */
943     0,                                          /* tp_dict */
944     0,                                          /* tp_descr_get */
945     0,                                          /* tp_descr_set */
946     0,                                          /* tp_dictoffset */
947     0,                                          /* tp_init */
948     0,                                          /* tp_alloc */
949     PyCStructType_new,                                  /* tp_new */
950     0,                                          /* tp_free */
951 };
952 
953 static PyTypeObject UnionType_Type = {
954     PyVarObject_HEAD_INIT(NULL, 0)
955     "_ctypes.UnionType",                        /* tp_name */
956     0,                                          /* tp_basicsize */
957     0,                                          /* tp_itemsize */
958     0,                                          /* tp_dealloc */
959     0,                                          /* tp_vectorcall_offset */
960     0,                                          /* tp_getattr */
961     0,                                          /* tp_setattr */
962     0,                                          /* tp_as_async */
963     0,                                          /* tp_repr */
964     0,                                          /* tp_as_number */
965     &CDataType_as_sequence,             /* tp_as_sequence */
966     0,                                          /* tp_as_mapping */
967     0,                                          /* tp_hash */
968     0,                                          /* tp_call */
969     0,                                          /* tp_str */
970     0,                                          /* tp_getattro */
971     UnionType_setattro,                         /* tp_setattro */
972     0,                                          /* tp_as_buffer */
973     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
974     "metatype for the CData Objects",           /* tp_doc */
975     (traverseproc)CDataType_traverse,           /* tp_traverse */
976     (inquiry)CDataType_clear,                   /* tp_clear */
977     0,                                          /* tp_richcompare */
978     0,                                          /* tp_weaklistoffset */
979     0,                                          /* tp_iter */
980     0,                                          /* tp_iternext */
981     CDataType_methods,                          /* tp_methods */
982     0,                                          /* tp_members */
983     0,                                          /* tp_getset */
984     0,                                          /* tp_base */
985     0,                                          /* tp_dict */
986     0,                                          /* tp_descr_get */
987     0,                                          /* tp_descr_set */
988     0,                                          /* tp_dictoffset */
989     0,                                          /* tp_init */
990     0,                                          /* tp_alloc */
991     UnionType_new,                              /* tp_new */
992     0,                                          /* tp_free */
993 };
994 
995 
996 /******************************************************************/
997 
998 /*
999 
1000 The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be
1001 created. It must check for a _type_ attribute in the class. Since are no
1002 runtime created properties, a CField is probably *not* needed ?
1003 
1004 class IntPointer(Pointer):
1005     _type_ = "i"
1006 
1007 The PyCPointer_Type provides the functionality: a contents method/property, a
1008 size property/method, and the sequence protocol.
1009 
1010 */
1011 
1012 static int
PyCPointerType_SetProto(StgDictObject * stgdict,PyObject * proto)1013 PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
1014 {
1015     if (!proto || !PyType_Check(proto)) {
1016         PyErr_SetString(PyExc_TypeError,
1017                         "_type_ must be a type");
1018         return -1;
1019     }
1020     if (!PyType_stgdict(proto)) {
1021         PyErr_SetString(PyExc_TypeError,
1022                         "_type_ must have storage info");
1023         return -1;
1024     }
1025     Py_INCREF(proto);
1026     Py_XSETREF(stgdict->proto, proto);
1027     return 0;
1028 }
1029 
1030 static PyCArgObject *
PyCPointerType_paramfunc(CDataObject * self)1031 PyCPointerType_paramfunc(CDataObject *self)
1032 {
1033     PyCArgObject *parg;
1034 
1035     parg = PyCArgObject_new();
1036     if (parg == NULL)
1037         return NULL;
1038 
1039     parg->tag = 'P';
1040     parg->pffi_type = &ffi_type_pointer;
1041     Py_INCREF(self);
1042     parg->obj = (PyObject *)self;
1043     parg->value.p = *(void **)self->b_ptr;
1044     return parg;
1045 }
1046 
1047 static PyObject *
PyCPointerType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1048 PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1049 {
1050     PyTypeObject *result;
1051     StgDictObject *stgdict;
1052     PyObject *proto;
1053     PyObject *typedict;
1054     _Py_IDENTIFIER(_type_);
1055 
1056     typedict = PyTuple_GetItem(args, 2);
1057     if (!typedict)
1058         return NULL;
1059 /*
1060   stgdict items size, align, length contain info about pointers itself,
1061   stgdict->proto has info about the pointed to type!
1062 */
1063     stgdict = (StgDictObject *)PyObject_CallObject(
1064         (PyObject *)&PyCStgDict_Type, NULL);
1065     if (!stgdict)
1066         return NULL;
1067     stgdict->size = sizeof(void *);
1068     stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
1069     stgdict->length = 1;
1070     stgdict->ffi_type_pointer = ffi_type_pointer;
1071     stgdict->paramfunc = PyCPointerType_paramfunc;
1072     stgdict->flags |= TYPEFLAG_ISPOINTER;
1073 
1074     proto = _PyDict_GetItemIdWithError(typedict, &PyId__type_); /* Borrowed ref */
1075     if (proto) {
1076         StgDictObject *itemdict;
1077         const char *current_format;
1078         if (-1 == PyCPointerType_SetProto(stgdict, proto)) {
1079             Py_DECREF((PyObject *)stgdict);
1080             return NULL;
1081         }
1082         itemdict = PyType_stgdict(proto);
1083         /* PyCPointerType_SetProto has verified proto has a stgdict. */
1084         assert(itemdict);
1085         /* If itemdict->format is NULL, then this is a pointer to an
1086            incomplete type.  We create a generic format string
1087            'pointer to bytes' in this case.  XXX Better would be to
1088            fix the format string later...
1089         */
1090         current_format = itemdict->format ? itemdict->format : "B";
1091         if (itemdict->shape != NULL) {
1092             /* pointer to an array: the shape needs to be prefixed */
1093             stgdict->format = _ctypes_alloc_format_string_with_shape(
1094                 itemdict->ndim, itemdict->shape, "&", current_format);
1095         } else {
1096             stgdict->format = _ctypes_alloc_format_string("&", current_format);
1097         }
1098         if (stgdict->format == NULL) {
1099             Py_DECREF((PyObject *)stgdict);
1100             return NULL;
1101         }
1102     }
1103     else if (PyErr_Occurred()) {
1104         Py_DECREF((PyObject *)stgdict);
1105         return NULL;
1106     }
1107 
1108     /* create the new instance (which is a class,
1109        since we are a metatype!) */
1110     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1111     if (result == NULL) {
1112         Py_DECREF((PyObject *)stgdict);
1113         return NULL;
1114     }
1115 
1116     /* replace the class dict by our updated spam dict */
1117     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1118         Py_DECREF(result);
1119         Py_DECREF((PyObject *)stgdict);
1120         return NULL;
1121     }
1122     Py_SETREF(result->tp_dict, (PyObject *)stgdict);
1123 
1124     return (PyObject *)result;
1125 }
1126 
1127 
1128 static PyObject *
PyCPointerType_set_type(PyTypeObject * self,PyObject * type)1129 PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
1130 {
1131     StgDictObject *dict;
1132     _Py_IDENTIFIER(_type_);
1133 
1134     dict = PyType_stgdict((PyObject *)self);
1135     if (!dict) {
1136         PyErr_SetString(PyExc_TypeError,
1137                         "abstract class");
1138         return NULL;
1139     }
1140 
1141     if (-1 == PyCPointerType_SetProto(dict, type))
1142         return NULL;
1143 
1144     if (-1 == _PyDict_SetItemId((PyObject *)dict, &PyId__type_, type))
1145         return NULL;
1146 
1147     Py_RETURN_NONE;
1148 }
1149 
1150 static PyObject *_byref(PyObject *);
1151 
1152 static PyObject *
PyCPointerType_from_param(PyObject * type,PyObject * value)1153 PyCPointerType_from_param(PyObject *type, PyObject *value)
1154 {
1155     StgDictObject *typedict;
1156 
1157     if (value == Py_None) {
1158         /* ConvParam will convert to a NULL pointer later */
1159         Py_INCREF(value);
1160         return value;
1161     }
1162 
1163     typedict = PyType_stgdict(type);
1164     if (!typedict) {
1165         PyErr_SetString(PyExc_TypeError,
1166                         "abstract class");
1167         return NULL;
1168     }
1169 
1170     /* If we expect POINTER(<type>), but receive a <type> instance, accept
1171        it by calling byref(<type>).
1172     */
1173     switch (PyObject_IsInstance(value, typedict->proto)) {
1174     case 1:
1175         Py_INCREF(value); /* _byref steals a refcount */
1176         return _byref(value);
1177     case -1:
1178         return NULL;
1179     default:
1180         break;
1181     }
1182 
1183     if (PointerObject_Check(value) || ArrayObject_Check(value)) {
1184         /* Array instances are also pointers when
1185            the item types are the same.
1186         */
1187         StgDictObject *v = PyObject_stgdict(value);
1188         assert(v); /* Cannot be NULL for pointer or array objects */
1189         int ret = PyObject_IsSubclass(v->proto, typedict->proto);
1190         if (ret < 0) {
1191             return NULL;
1192         }
1193         if (ret) {
1194             Py_INCREF(value);
1195             return value;
1196         }
1197     }
1198     return CDataType_from_param(type, value);
1199 }
1200 
1201 static PyMethodDef PyCPointerType_methods[] = {
1202     { "from_address", CDataType_from_address, METH_O, from_address_doc },
1203     { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
1204     { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
1205     { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
1206     { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc},
1207     { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O },
1208     { NULL, NULL },
1209 };
1210 
1211 PyTypeObject PyCPointerType_Type = {
1212     PyVarObject_HEAD_INIT(NULL, 0)
1213     "_ctypes.PyCPointerType",                                   /* tp_name */
1214     0,                                          /* tp_basicsize */
1215     0,                                          /* tp_itemsize */
1216     0,                                          /* tp_dealloc */
1217     0,                                          /* tp_vectorcall_offset */
1218     0,                                          /* tp_getattr */
1219     0,                                          /* tp_setattr */
1220     0,                                          /* tp_as_async */
1221     0,                                          /* tp_repr */
1222     0,                                          /* tp_as_number */
1223     &CDataType_as_sequence,             /* tp_as_sequence */
1224     0,                                          /* tp_as_mapping */
1225     0,                                          /* tp_hash */
1226     0,                                          /* tp_call */
1227     0,                                          /* tp_str */
1228     0,                                          /* tp_getattro */
1229     0,                                          /* tp_setattro */
1230     0,                                          /* tp_as_buffer */
1231     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1232     "metatype for the Pointer Objects",         /* tp_doc */
1233     (traverseproc)CDataType_traverse,           /* tp_traverse */
1234     (inquiry)CDataType_clear,                   /* tp_clear */
1235     0,                                          /* tp_richcompare */
1236     0,                                          /* tp_weaklistoffset */
1237     0,                                          /* tp_iter */
1238     0,                                          /* tp_iternext */
1239     PyCPointerType_methods,                     /* tp_methods */
1240     0,                                          /* tp_members */
1241     0,                                          /* tp_getset */
1242     0,                                          /* tp_base */
1243     0,                                          /* tp_dict */
1244     0,                                          /* tp_descr_get */
1245     0,                                          /* tp_descr_set */
1246     0,                                          /* tp_dictoffset */
1247     0,                                          /* tp_init */
1248     0,                                          /* tp_alloc */
1249     PyCPointerType_new,                         /* tp_new */
1250     0,                                          /* tp_free */
1251 };
1252 
1253 
1254 /******************************************************************/
1255 /*
1256   PyCArrayType_Type
1257 */
1258 /*
1259   PyCArrayType_new ensures that the new Array subclass created has a _length_
1260   attribute, and a _type_ attribute.
1261 */
1262 
1263 static int
CharArray_set_raw(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))1264 CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
1265 {
1266     char *ptr;
1267     Py_ssize_t size;
1268     Py_buffer view;
1269 
1270     if (value == NULL) {
1271         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
1272         return -1;
1273     }
1274     if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
1275         return -1;
1276     size = view.len;
1277     ptr = view.buf;
1278     if (size > self->b_size) {
1279         PyErr_SetString(PyExc_ValueError,
1280                         "byte string too long");
1281         goto fail;
1282     }
1283 
1284     memcpy(self->b_ptr, ptr, size);
1285 
1286     PyBuffer_Release(&view);
1287     return 0;
1288  fail:
1289     PyBuffer_Release(&view);
1290     return -1;
1291 }
1292 
1293 static PyObject *
CharArray_get_raw(CDataObject * self,void * Py_UNUSED (ignored))1294 CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored))
1295 {
1296     return PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
1297 }
1298 
1299 static PyObject *
CharArray_get_value(CDataObject * self,void * Py_UNUSED (ignored))1300 CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
1301 {
1302     Py_ssize_t i;
1303     char *ptr = self->b_ptr;
1304     for (i = 0; i < self->b_size; ++i)
1305         if (*ptr++ == '\0')
1306             break;
1307     return PyBytes_FromStringAndSize(self->b_ptr, i);
1308 }
1309 
1310 static int
CharArray_set_value(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))1311 CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
1312 {
1313     char *ptr;
1314     Py_ssize_t size;
1315 
1316     if (value == NULL) {
1317         PyErr_SetString(PyExc_TypeError,
1318                         "can't delete attribute");
1319         return -1;
1320     }
1321 
1322     if (!PyBytes_Check(value)) {
1323         PyErr_Format(PyExc_TypeError,
1324                      "bytes expected instead of %s instance",
1325                      Py_TYPE(value)->tp_name);
1326         return -1;
1327     } else
1328         Py_INCREF(value);
1329     size = PyBytes_GET_SIZE(value);
1330     if (size > self->b_size) {
1331         PyErr_SetString(PyExc_ValueError,
1332                         "byte string too long");
1333         Py_DECREF(value);
1334         return -1;
1335     }
1336 
1337     ptr = PyBytes_AS_STRING(value);
1338     memcpy(self->b_ptr, ptr, size);
1339     if (size < self->b_size)
1340         self->b_ptr[size] = '\0';
1341     Py_DECREF(value);
1342 
1343     return 0;
1344 }
1345 
1346 static PyGetSetDef CharArray_getsets[] = {
1347     { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
1348       "value", NULL },
1349     { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
1350       "string value"},
1351     { NULL, NULL }
1352 };
1353 
1354 #ifdef CTYPES_UNICODE
1355 static PyObject *
WCharArray_get_value(CDataObject * self,void * Py_UNUSED (ignored))1356 WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
1357 {
1358     Py_ssize_t i;
1359     wchar_t *ptr = (wchar_t *)self->b_ptr;
1360     for (i = 0; i < self->b_size/(Py_ssize_t)sizeof(wchar_t); ++i)
1361         if (*ptr++ == (wchar_t)0)
1362             break;
1363     return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
1364 }
1365 
1366 static int
WCharArray_set_value(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))1367 WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
1368 {
1369     Py_ssize_t result = 0;
1370 
1371     if (value == NULL) {
1372         PyErr_SetString(PyExc_TypeError,
1373                         "can't delete attribute");
1374         return -1;
1375     }
1376     if (!PyUnicode_Check(value)) {
1377         PyErr_Format(PyExc_TypeError,
1378                         "unicode string expected instead of %s instance",
1379                         Py_TYPE(value)->tp_name);
1380         return -1;
1381     } else
1382         Py_INCREF(value);
1383 
1384     Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0);
1385     if (len < 0) {
1386         return -1;
1387     }
1388     // PyUnicode_AsWideChar() returns number of wchars including trailing null byte,
1389     // when it is called with NULL.
1390     if (((size_t)len-1) > self->b_size/sizeof(wchar_t)) {
1391         PyErr_SetString(PyExc_ValueError, "string too long");
1392         result = -1;
1393         goto done;
1394     }
1395     result = PyUnicode_AsWideChar(value,
1396                                   (wchar_t *)self->b_ptr,
1397                                   self->b_size/sizeof(wchar_t));
1398     if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
1399         ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
1400   done:
1401     Py_DECREF(value);
1402 
1403     return result >= 0 ? 0 : -1;
1404 }
1405 
1406 static PyGetSetDef WCharArray_getsets[] = {
1407     { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
1408       "string value"},
1409     { NULL, NULL }
1410 };
1411 #endif
1412 
1413 /*
1414   The next three functions copied from Python's typeobject.c.
1415 
1416   They are used to attach methods, members, or getsets to a type *after* it
1417   has been created: Arrays of characters have additional getsets to treat them
1418   as strings.
1419  */
1420 /*
1421 static int
1422 add_methods(PyTypeObject *type, PyMethodDef *meth)
1423 {
1424     PyObject *dict = type->tp_dict;
1425     for (; meth->ml_name != NULL; meth++) {
1426         PyObject *descr;
1427         descr = PyDescr_NewMethod(type, meth);
1428         if (descr == NULL)
1429             return -1;
1430         if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0) {
1431             Py_DECREF(descr);
1432             return -1;
1433         }
1434         Py_DECREF(descr);
1435     }
1436     return 0;
1437 }
1438 
1439 static int
1440 add_members(PyTypeObject *type, PyMemberDef *memb)
1441 {
1442     PyObject *dict = type->tp_dict;
1443     for (; memb->name != NULL; memb++) {
1444         PyObject *descr;
1445         descr = PyDescr_NewMember(type, memb);
1446         if (descr == NULL)
1447             return -1;
1448         if (PyDict_SetItemString(dict, memb->name, descr) < 0) {
1449             Py_DECREF(descr);
1450             return -1;
1451         }
1452         Py_DECREF(descr);
1453     }
1454     return 0;
1455 }
1456 */
1457 
1458 static int
add_getset(PyTypeObject * type,PyGetSetDef * gsp)1459 add_getset(PyTypeObject *type, PyGetSetDef *gsp)
1460 {
1461     PyObject *dict = type->tp_dict;
1462     for (; gsp->name != NULL; gsp++) {
1463         PyObject *descr;
1464         descr = PyDescr_NewGetSet(type, gsp);
1465         if (descr == NULL)
1466             return -1;
1467         if (PyDict_SetItemString(dict, gsp->name, descr) < 0) {
1468             Py_DECREF(descr);
1469             return -1;
1470         }
1471         Py_DECREF(descr);
1472     }
1473     return 0;
1474 }
1475 
1476 static PyCArgObject *
PyCArrayType_paramfunc(CDataObject * self)1477 PyCArrayType_paramfunc(CDataObject *self)
1478 {
1479     PyCArgObject *p = PyCArgObject_new();
1480     if (p == NULL)
1481         return NULL;
1482     p->tag = 'P';
1483     p->pffi_type = &ffi_type_pointer;
1484     p->value.p = (char *)self->b_ptr;
1485     Py_INCREF(self);
1486     p->obj = (PyObject *)self;
1487     return p;
1488 }
1489 
1490 static PyObject *
PyCArrayType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1491 PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1492 {
1493     _Py_IDENTIFIER(_length_);
1494     _Py_IDENTIFIER(_type_);
1495     PyTypeObject *result;
1496     StgDictObject *stgdict;
1497     StgDictObject *itemdict;
1498     PyObject *length_attr, *type_attr;
1499     Py_ssize_t length;
1500     Py_ssize_t itemsize, itemalign;
1501 
1502     /* create the new instance (which is a class,
1503        since we are a metatype!) */
1504     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1505     if (result == NULL)
1506         return NULL;
1507 
1508     /* Initialize these variables to NULL so that we can simplify error
1509        handling by using Py_XDECREF.  */
1510     stgdict = NULL;
1511     type_attr = NULL;
1512 
1513     if (_PyObject_LookupAttrId((PyObject *)result, &PyId__length_, &length_attr) < 0) {
1514         goto error;
1515     }
1516     if (!length_attr) {
1517         PyErr_SetString(PyExc_AttributeError,
1518                         "class must define a '_length_' attribute");
1519         goto error;
1520     }
1521 
1522     if (!PyLong_Check(length_attr)) {
1523         Py_DECREF(length_attr);
1524         PyErr_SetString(PyExc_TypeError,
1525                         "The '_length_' attribute must be an integer");
1526         goto error;
1527     }
1528 
1529     if (_PyLong_Sign(length_attr) == -1) {
1530         Py_DECREF(length_attr);
1531         PyErr_SetString(PyExc_ValueError,
1532                         "The '_length_' attribute must not be negative");
1533         goto error;
1534     }
1535 
1536     length = PyLong_AsSsize_t(length_attr);
1537     Py_DECREF(length_attr);
1538     if (length == -1 && PyErr_Occurred()) {
1539         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1540             PyErr_SetString(PyExc_OverflowError,
1541                             "The '_length_' attribute is too large");
1542         }
1543         goto error;
1544     }
1545 
1546     if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &type_attr) < 0) {
1547         goto error;
1548     }
1549     if (!type_attr) {
1550         PyErr_SetString(PyExc_AttributeError,
1551                         "class must define a '_type_' attribute");
1552         goto error;
1553     }
1554 
1555     stgdict = (StgDictObject *)PyObject_CallObject(
1556         (PyObject *)&PyCStgDict_Type, NULL);
1557     if (!stgdict)
1558         goto error;
1559 
1560     itemdict = PyType_stgdict(type_attr);
1561     if (!itemdict) {
1562         PyErr_SetString(PyExc_TypeError,
1563                         "_type_ must have storage info");
1564         goto error;
1565     }
1566 
1567     assert(itemdict->format);
1568     stgdict->format = _ctypes_alloc_format_string(NULL, itemdict->format);
1569     if (stgdict->format == NULL)
1570         goto error;
1571     stgdict->ndim = itemdict->ndim + 1;
1572     stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t) * stgdict->ndim);
1573     if (stgdict->shape == NULL) {
1574         PyErr_NoMemory();
1575         goto error;
1576     }
1577     stgdict->shape[0] = length;
1578     if (stgdict->ndim > 1) {
1579         memmove(&stgdict->shape[1], itemdict->shape,
1580             sizeof(Py_ssize_t) * (stgdict->ndim - 1));
1581     }
1582 
1583     itemsize = itemdict->size;
1584     if (itemsize != 0 && length > PY_SSIZE_T_MAX / itemsize) {
1585         PyErr_SetString(PyExc_OverflowError,
1586                         "array too large");
1587         goto error;
1588     }
1589 
1590     itemalign = itemdict->align;
1591 
1592     if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
1593         stgdict->flags |= TYPEFLAG_HASPOINTER;
1594 
1595     stgdict->size = itemsize * length;
1596     stgdict->align = itemalign;
1597     stgdict->length = length;
1598     stgdict->proto = type_attr;
1599     type_attr = NULL;
1600 
1601     stgdict->paramfunc = &PyCArrayType_paramfunc;
1602 
1603     /* Arrays are passed as pointers to function calls. */
1604     stgdict->ffi_type_pointer = ffi_type_pointer;
1605 
1606     /* replace the class dict by our updated spam dict */
1607     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict))
1608         goto error;
1609     Py_SETREF(result->tp_dict, (PyObject *)stgdict);  /* steal the reference */
1610     stgdict = NULL;
1611 
1612     /* Special case for character arrays.
1613        A permanent annoyance: char arrays are also strings!
1614     */
1615     if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
1616         if (-1 == add_getset(result, CharArray_getsets))
1617             goto error;
1618 #ifdef CTYPES_UNICODE
1619     } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
1620         if (-1 == add_getset(result, WCharArray_getsets))
1621             goto error;
1622 #endif
1623     }
1624 
1625     return (PyObject *)result;
1626 error:
1627     Py_XDECREF((PyObject*)stgdict);
1628     Py_XDECREF(type_attr);
1629     Py_DECREF(result);
1630     return NULL;
1631 }
1632 
1633 PyTypeObject PyCArrayType_Type = {
1634     PyVarObject_HEAD_INIT(NULL, 0)
1635     "_ctypes.PyCArrayType",                     /* tp_name */
1636     0,                                          /* tp_basicsize */
1637     0,                                          /* tp_itemsize */
1638     0,                                          /* tp_dealloc */
1639     0,                                          /* tp_vectorcall_offset */
1640     0,                                          /* tp_getattr */
1641     0,                                          /* tp_setattr */
1642     0,                                          /* tp_as_async */
1643     0,                                          /* tp_repr */
1644     0,                                          /* tp_as_number */
1645     &CDataType_as_sequence,                     /* tp_as_sequence */
1646     0,                                          /* tp_as_mapping */
1647     0,                                          /* tp_hash */
1648     0,                                          /* tp_call */
1649     0,                                          /* tp_str */
1650     0,                                          /* tp_getattro */
1651     0,                                          /* tp_setattro */
1652     0,                                          /* tp_as_buffer */
1653     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1654     "metatype for the Array Objects",           /* tp_doc */
1655     0,                                          /* tp_traverse */
1656     0,                                          /* tp_clear */
1657     0,                                          /* tp_richcompare */
1658     0,                                          /* tp_weaklistoffset */
1659     0,                                          /* tp_iter */
1660     0,                                          /* tp_iternext */
1661     CDataType_methods,                          /* tp_methods */
1662     0,                                          /* tp_members */
1663     0,                                          /* tp_getset */
1664     0,                                          /* tp_base */
1665     0,                                          /* tp_dict */
1666     0,                                          /* tp_descr_get */
1667     0,                                          /* tp_descr_set */
1668     0,                                          /* tp_dictoffset */
1669     0,                                          /* tp_init */
1670     0,                                          /* tp_alloc */
1671     PyCArrayType_new,                                   /* tp_new */
1672     0,                                          /* tp_free */
1673 };
1674 
1675 
1676 /******************************************************************/
1677 /*
1678   PyCSimpleType_Type
1679 */
1680 /*
1681 
1682 PyCSimpleType_new ensures that the new Simple_Type subclass created has a valid
1683 _type_ attribute.
1684 
1685 */
1686 
1687 static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g";
1688 
1689 static PyObject *
c_wchar_p_from_param(PyObject * type,PyObject * value)1690 c_wchar_p_from_param(PyObject *type, PyObject *value)
1691 {
1692     _Py_IDENTIFIER(_as_parameter_);
1693     PyObject *as_parameter;
1694     int res;
1695     if (value == Py_None) {
1696         Py_RETURN_NONE;
1697     }
1698     if (PyUnicode_Check(value)) {
1699         PyCArgObject *parg;
1700         struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1701 
1702         parg = PyCArgObject_new();
1703         if (parg == NULL)
1704             return NULL;
1705         parg->pffi_type = &ffi_type_pointer;
1706         parg->tag = 'Z';
1707         parg->obj = fd->setfunc(&parg->value, value, 0);
1708         if (parg->obj == NULL) {
1709             Py_DECREF(parg);
1710             return NULL;
1711         }
1712         return (PyObject *)parg;
1713     }
1714     res = PyObject_IsInstance(value, type);
1715     if (res == -1)
1716         return NULL;
1717     if (res) {
1718         Py_INCREF(value);
1719         return value;
1720     }
1721     if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1722         /* c_wchar array instance or pointer(c_wchar(...)) */
1723         StgDictObject *dt = PyObject_stgdict(value);
1724         StgDictObject *dict;
1725         assert(dt); /* Cannot be NULL for pointer or array objects */
1726         dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1727         if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1728             Py_INCREF(value);
1729             return value;
1730         }
1731     }
1732     if (PyCArg_CheckExact(value)) {
1733         /* byref(c_char(...)) */
1734         PyCArgObject *a = (PyCArgObject *)value;
1735         StgDictObject *dict = PyObject_stgdict(a->obj);
1736         if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1737             Py_INCREF(value);
1738             return value;
1739         }
1740     }
1741 
1742     if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
1743         return NULL;
1744     }
1745     if (as_parameter) {
1746         value = c_wchar_p_from_param(type, as_parameter);
1747         Py_DECREF(as_parameter);
1748         return value;
1749     }
1750     /* XXX better message */
1751     PyErr_SetString(PyExc_TypeError,
1752                     "wrong type");
1753     return NULL;
1754 }
1755 
1756 static PyObject *
c_char_p_from_param(PyObject * type,PyObject * value)1757 c_char_p_from_param(PyObject *type, PyObject *value)
1758 {
1759     _Py_IDENTIFIER(_as_parameter_);
1760     PyObject *as_parameter;
1761     int res;
1762     if (value == Py_None) {
1763         Py_RETURN_NONE;
1764     }
1765     if (PyBytes_Check(value)) {
1766         PyCArgObject *parg;
1767         struct fielddesc *fd = _ctypes_get_fielddesc("z");
1768 
1769         parg = PyCArgObject_new();
1770         if (parg == NULL)
1771             return NULL;
1772         parg->pffi_type = &ffi_type_pointer;
1773         parg->tag = 'z';
1774         parg->obj = fd->setfunc(&parg->value, value, 0);
1775         if (parg->obj == NULL) {
1776             Py_DECREF(parg);
1777             return NULL;
1778         }
1779         return (PyObject *)parg;
1780     }
1781     res = PyObject_IsInstance(value, type);
1782     if (res == -1)
1783         return NULL;
1784     if (res) {
1785         Py_INCREF(value);
1786         return value;
1787     }
1788     if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1789         /* c_char array instance or pointer(c_char(...)) */
1790         StgDictObject *dt = PyObject_stgdict(value);
1791         StgDictObject *dict;
1792         assert(dt); /* Cannot be NULL for pointer or array objects */
1793         dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1794         if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1795             Py_INCREF(value);
1796             return value;
1797         }
1798     }
1799     if (PyCArg_CheckExact(value)) {
1800         /* byref(c_char(...)) */
1801         PyCArgObject *a = (PyCArgObject *)value;
1802         StgDictObject *dict = PyObject_stgdict(a->obj);
1803         if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1804             Py_INCREF(value);
1805             return value;
1806         }
1807     }
1808 
1809     if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
1810         return NULL;
1811     }
1812     if (as_parameter) {
1813         value = c_char_p_from_param(type, as_parameter);
1814         Py_DECREF(as_parameter);
1815         return value;
1816     }
1817     /* XXX better message */
1818     PyErr_SetString(PyExc_TypeError,
1819                     "wrong type");
1820     return NULL;
1821 }
1822 
1823 static PyObject *
c_void_p_from_param(PyObject * type,PyObject * value)1824 c_void_p_from_param(PyObject *type, PyObject *value)
1825 {
1826     _Py_IDENTIFIER(_as_parameter_);
1827     StgDictObject *stgd;
1828     PyObject *as_parameter;
1829     int res;
1830 
1831 /* None */
1832     if (value == Py_None) {
1833         Py_RETURN_NONE;
1834     }
1835     /* Should probably allow buffer interface as well */
1836 /* int, long */
1837     if (PyLong_Check(value)) {
1838         PyCArgObject *parg;
1839         struct fielddesc *fd = _ctypes_get_fielddesc("P");
1840 
1841         parg = PyCArgObject_new();
1842         if (parg == NULL)
1843             return NULL;
1844         parg->pffi_type = &ffi_type_pointer;
1845         parg->tag = 'P';
1846         parg->obj = fd->setfunc(&parg->value, value, 0);
1847         if (parg->obj == NULL) {
1848             Py_DECREF(parg);
1849             return NULL;
1850         }
1851         return (PyObject *)parg;
1852     }
1853     /* XXX struni: remove later */
1854 /* bytes */
1855     if (PyBytes_Check(value)) {
1856         PyCArgObject *parg;
1857         struct fielddesc *fd = _ctypes_get_fielddesc("z");
1858 
1859         parg = PyCArgObject_new();
1860         if (parg == NULL)
1861             return NULL;
1862         parg->pffi_type = &ffi_type_pointer;
1863         parg->tag = 'z';
1864         parg->obj = fd->setfunc(&parg->value, value, 0);
1865         if (parg->obj == NULL) {
1866             Py_DECREF(parg);
1867             return NULL;
1868         }
1869         return (PyObject *)parg;
1870     }
1871 /* unicode */
1872     if (PyUnicode_Check(value)) {
1873         PyCArgObject *parg;
1874         struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1875 
1876         parg = PyCArgObject_new();
1877         if (parg == NULL)
1878             return NULL;
1879         parg->pffi_type = &ffi_type_pointer;
1880         parg->tag = 'Z';
1881         parg->obj = fd->setfunc(&parg->value, value, 0);
1882         if (parg->obj == NULL) {
1883             Py_DECREF(parg);
1884             return NULL;
1885         }
1886         return (PyObject *)parg;
1887     }
1888 /* c_void_p instance (or subclass) */
1889     res = PyObject_IsInstance(value, type);
1890     if (res == -1)
1891         return NULL;
1892     if (res) {
1893         /* c_void_p instances */
1894         Py_INCREF(value);
1895         return value;
1896     }
1897 /* ctypes array or pointer instance */
1898     if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1899         /* Any array or pointer is accepted */
1900         Py_INCREF(value);
1901         return value;
1902     }
1903 /* byref(...) */
1904     if (PyCArg_CheckExact(value)) {
1905         /* byref(c_xxx()) */
1906         PyCArgObject *a = (PyCArgObject *)value;
1907         if (a->tag == 'P') {
1908             Py_INCREF(value);
1909             return value;
1910         }
1911     }
1912 /* function pointer */
1913     if (PyCFuncPtrObject_Check(value)) {
1914         PyCArgObject *parg;
1915         PyCFuncPtrObject *func;
1916         func = (PyCFuncPtrObject *)value;
1917         parg = PyCArgObject_new();
1918         if (parg == NULL)
1919             return NULL;
1920         parg->pffi_type = &ffi_type_pointer;
1921         parg->tag = 'P';
1922         Py_INCREF(value);
1923         parg->value.p = *(void **)func->b_ptr;
1924         parg->obj = value;
1925         return (PyObject *)parg;
1926     }
1927 /* c_char_p, c_wchar_p */
1928     stgd = PyObject_stgdict(value);
1929     if (stgd && CDataObject_Check(value) && stgd->proto && PyUnicode_Check(stgd->proto)) {
1930         PyCArgObject *parg;
1931 
1932         switch (PyUnicode_AsUTF8(stgd->proto)[0]) {
1933         case 'z': /* c_char_p */
1934         case 'Z': /* c_wchar_p */
1935             parg = PyCArgObject_new();
1936             if (parg == NULL)
1937                 return NULL;
1938             parg->pffi_type = &ffi_type_pointer;
1939             parg->tag = 'Z';
1940             Py_INCREF(value);
1941             parg->obj = value;
1942             /* Remember: b_ptr points to where the pointer is stored! */
1943             parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
1944             return (PyObject *)parg;
1945         }
1946     }
1947 
1948     if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
1949         return NULL;
1950     }
1951     if (as_parameter) {
1952         value = c_void_p_from_param(type, as_parameter);
1953         Py_DECREF(as_parameter);
1954         return value;
1955     }
1956     /* XXX better message */
1957     PyErr_SetString(PyExc_TypeError,
1958                     "wrong type");
1959     return NULL;
1960 }
1961 
1962 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1963 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
1964 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1965 
CreateSwappedType(PyTypeObject * type,PyObject * args,PyObject * kwds,PyObject * proto,struct fielddesc * fmt)1966 static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
1967                                    PyObject *proto, struct fielddesc *fmt)
1968 {
1969     PyTypeObject *result;
1970     StgDictObject *stgdict;
1971     PyObject *name = PyTuple_GET_ITEM(args, 0);
1972     PyObject *newname;
1973     PyObject *swapped_args;
1974     static PyObject *suffix;
1975     Py_ssize_t i;
1976 
1977     swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
1978     if (!swapped_args)
1979         return NULL;
1980 
1981     if (suffix == NULL)
1982 #ifdef WORDS_BIGENDIAN
1983         suffix = PyUnicode_InternFromString("_le");
1984 #else
1985         suffix = PyUnicode_InternFromString("_be");
1986 #endif
1987     if (suffix == NULL) {
1988         Py_DECREF(swapped_args);
1989         return NULL;
1990     }
1991 
1992     newname = PyUnicode_Concat(name, suffix);
1993     if (newname == NULL) {
1994         Py_DECREF(swapped_args);
1995         return NULL;
1996     }
1997 
1998     PyTuple_SET_ITEM(swapped_args, 0, newname);
1999     for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
2000         PyObject *v = PyTuple_GET_ITEM(args, i);
2001         Py_INCREF(v);
2002         PyTuple_SET_ITEM(swapped_args, i, v);
2003     }
2004 
2005     /* create the new instance (which is a class,
2006        since we are a metatype!) */
2007     result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
2008     Py_DECREF(swapped_args);
2009     if (result == NULL)
2010         return NULL;
2011 
2012     stgdict = (StgDictObject *)PyObject_CallObject(
2013         (PyObject *)&PyCStgDict_Type, NULL);
2014     if (!stgdict) {
2015         Py_DECREF(result);
2016         return NULL;
2017     }
2018 
2019     stgdict->ffi_type_pointer = *fmt->pffi_type;
2020     stgdict->align = fmt->pffi_type->alignment;
2021     stgdict->length = 0;
2022     stgdict->size = fmt->pffi_type->size;
2023     stgdict->setfunc = fmt->setfunc_swapped;
2024     stgdict->getfunc = fmt->getfunc_swapped;
2025 
2026     Py_INCREF(proto);
2027     stgdict->proto = proto;
2028 
2029     /* replace the class dict by our updated spam dict */
2030     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2031         Py_DECREF(result);
2032         Py_DECREF((PyObject *)stgdict);
2033         return NULL;
2034     }
2035     Py_SETREF(result->tp_dict, (PyObject *)stgdict);
2036 
2037     return (PyObject *)result;
2038 }
2039 
2040 static PyCArgObject *
PyCSimpleType_paramfunc(CDataObject * self)2041 PyCSimpleType_paramfunc(CDataObject *self)
2042 {
2043     StgDictObject *dict;
2044     const char *fmt;
2045     PyCArgObject *parg;
2046     struct fielddesc *fd;
2047 
2048     dict = PyObject_stgdict((PyObject *)self);
2049     assert(dict); /* Cannot be NULL for CDataObject instances */
2050     fmt = PyUnicode_AsUTF8(dict->proto);
2051     assert(fmt);
2052 
2053     fd = _ctypes_get_fielddesc(fmt);
2054     assert(fd);
2055 
2056     parg = PyCArgObject_new();
2057     if (parg == NULL)
2058         return NULL;
2059 
2060     parg->tag = fmt[0];
2061     parg->pffi_type = fd->pffi_type;
2062     Py_INCREF(self);
2063     parg->obj = (PyObject *)self;
2064     memcpy(&parg->value, self->b_ptr, self->b_size);
2065     return parg;
2066 }
2067 
2068 static PyObject *
PyCSimpleType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)2069 PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2070 {
2071     _Py_IDENTIFIER(_type_);
2072     PyTypeObject *result;
2073     StgDictObject *stgdict;
2074     PyObject *proto;
2075     const char *proto_str;
2076     Py_ssize_t proto_len;
2077     PyMethodDef *ml;
2078     struct fielddesc *fmt;
2079 
2080     /* create the new instance (which is a class,
2081        since we are a metatype!) */
2082     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2083     if (result == NULL)
2084         return NULL;
2085 
2086     if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &proto) < 0) {
2087         return NULL;
2088     }
2089     if (!proto) {
2090         PyErr_SetString(PyExc_AttributeError,
2091                         "class must define a '_type_' attribute");
2092   error:
2093         Py_XDECREF(proto);
2094         Py_DECREF(result);
2095         return NULL;
2096     }
2097     if (PyUnicode_Check(proto)) {
2098         proto_str = PyUnicode_AsUTF8AndSize(proto, &proto_len);
2099         if (!proto_str)
2100             goto error;
2101     } else {
2102         PyErr_SetString(PyExc_TypeError,
2103             "class must define a '_type_' string attribute");
2104         goto error;
2105     }
2106     if (proto_len != 1) {
2107         PyErr_SetString(PyExc_ValueError,
2108                         "class must define a '_type_' attribute "
2109                         "which must be a string of length 1");
2110         goto error;
2111     }
2112     if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
2113         PyErr_Format(PyExc_AttributeError,
2114                      "class must define a '_type_' attribute which must be\n"
2115                      "a single character string containing one of '%s'.",
2116                      SIMPLE_TYPE_CHARS);
2117         goto error;
2118     }
2119     fmt = _ctypes_get_fielddesc(proto_str);
2120     if (fmt == NULL) {
2121         PyErr_Format(PyExc_ValueError,
2122                      "_type_ '%s' not supported", proto_str);
2123         goto error;
2124     }
2125 
2126     stgdict = (StgDictObject *)PyObject_CallObject(
2127         (PyObject *)&PyCStgDict_Type, NULL);
2128     if (!stgdict)
2129         goto error;
2130 
2131     stgdict->ffi_type_pointer = *fmt->pffi_type;
2132     stgdict->align = fmt->pffi_type->alignment;
2133     stgdict->length = 0;
2134     stgdict->size = fmt->pffi_type->size;
2135     stgdict->setfunc = fmt->setfunc;
2136     stgdict->getfunc = fmt->getfunc;
2137 #ifdef WORDS_BIGENDIAN
2138     stgdict->format = _ctypes_alloc_format_string_for_type(proto_str[0], 1);
2139 #else
2140     stgdict->format = _ctypes_alloc_format_string_for_type(proto_str[0], 0);
2141 #endif
2142     if (stgdict->format == NULL) {
2143         Py_DECREF(result);
2144         Py_DECREF(proto);
2145         Py_DECREF((PyObject *)stgdict);
2146         return NULL;
2147     }
2148 
2149     stgdict->paramfunc = PyCSimpleType_paramfunc;
2150 /*
2151     if (result->tp_base != &Simple_Type) {
2152         stgdict->setfunc = NULL;
2153         stgdict->getfunc = NULL;
2154     }
2155 */
2156 
2157     /* This consumes the refcount on proto which we have */
2158     stgdict->proto = proto;
2159 
2160     /* replace the class dict by our updated spam dict */
2161     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2162         Py_DECREF(result);
2163         Py_DECREF((PyObject *)stgdict);
2164         return NULL;
2165     }
2166     Py_SETREF(result->tp_dict, (PyObject *)stgdict);
2167 
2168     /* Install from_param class methods in ctypes base classes.
2169        Overrides the PyCSimpleType_from_param generic method.
2170      */
2171     if (result->tp_base == &Simple_Type) {
2172         switch (*proto_str) {
2173         case 'z': /* c_char_p */
2174             ml = &c_char_p_method;
2175             stgdict->flags |= TYPEFLAG_ISPOINTER;
2176             break;
2177         case 'Z': /* c_wchar_p */
2178             ml = &c_wchar_p_method;
2179             stgdict->flags |= TYPEFLAG_ISPOINTER;
2180             break;
2181         case 'P': /* c_void_p */
2182             ml = &c_void_p_method;
2183             stgdict->flags |= TYPEFLAG_ISPOINTER;
2184             break;
2185         case 's':
2186         case 'X':
2187         case 'O':
2188             ml = NULL;
2189             stgdict->flags |= TYPEFLAG_ISPOINTER;
2190             break;
2191         default:
2192             ml = NULL;
2193             break;
2194         }
2195 
2196         if (ml) {
2197             PyObject *meth;
2198             int x;
2199             meth = PyDescr_NewClassMethod(result, ml);
2200             if (!meth) {
2201                 Py_DECREF(result);
2202                 return NULL;
2203             }
2204             x = PyDict_SetItemString(result->tp_dict,
2205                                      ml->ml_name,
2206                                      meth);
2207             Py_DECREF(meth);
2208             if (x == -1) {
2209                 Py_DECREF(result);
2210                 return NULL;
2211             }
2212         }
2213     }
2214 
2215     if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
2216         PyObject *swapped = CreateSwappedType(type, args, kwds,
2217                                               proto, fmt);
2218         StgDictObject *sw_dict;
2219         if (swapped == NULL) {
2220             Py_DECREF(result);
2221             return NULL;
2222         }
2223         sw_dict = PyType_stgdict(swapped);
2224 #ifdef WORDS_BIGENDIAN
2225         PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
2226         PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
2227         PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
2228         PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
2229         /* We are creating the type for the OTHER endian */
2230         sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1);
2231 #else
2232         PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
2233         PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
2234         PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
2235         PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
2236         /* We are creating the type for the OTHER endian */
2237         sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1);
2238 #endif
2239         Py_DECREF(swapped);
2240         if (PyErr_Occurred()) {
2241             Py_DECREF(result);
2242             return NULL;
2243         }
2244     };
2245 
2246     return (PyObject *)result;
2247 }
2248 
2249 /*
2250  * This is a *class method*.
2251  * Convert a parameter into something that ConvParam can handle.
2252  */
2253 static PyObject *
PyCSimpleType_from_param(PyObject * type,PyObject * value)2254 PyCSimpleType_from_param(PyObject *type, PyObject *value)
2255 {
2256     _Py_IDENTIFIER(_as_parameter_);
2257     StgDictObject *dict;
2258     const char *fmt;
2259     PyCArgObject *parg;
2260     struct fielddesc *fd;
2261     PyObject *as_parameter;
2262     int res;
2263 
2264     /* If the value is already an instance of the requested type,
2265        we can use it as is */
2266     res = PyObject_IsInstance(value, type);
2267     if (res == -1)
2268         return NULL;
2269     if (res) {
2270         Py_INCREF(value);
2271         return value;
2272     }
2273 
2274     dict = PyType_stgdict(type);
2275     if (!dict) {
2276         PyErr_SetString(PyExc_TypeError,
2277                         "abstract class");
2278         return NULL;
2279     }
2280 
2281     /* I think we can rely on this being a one-character string */
2282     fmt = PyUnicode_AsUTF8(dict->proto);
2283     assert(fmt);
2284 
2285     fd = _ctypes_get_fielddesc(fmt);
2286     assert(fd);
2287 
2288     parg = PyCArgObject_new();
2289     if (parg == NULL)
2290         return NULL;
2291 
2292     parg->tag = fmt[0];
2293     parg->pffi_type = fd->pffi_type;
2294     parg->obj = fd->setfunc(&parg->value, value, 0);
2295     if (parg->obj)
2296         return (PyObject *)parg;
2297     PyErr_Clear();
2298     Py_DECREF(parg);
2299 
2300     if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
2301         return NULL;
2302     }
2303     if (as_parameter) {
2304         if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
2305             Py_DECREF(as_parameter);
2306             return NULL;
2307         }
2308         value = PyCSimpleType_from_param(type, as_parameter);
2309         Py_LeaveRecursiveCall();
2310         Py_DECREF(as_parameter);
2311         return value;
2312     }
2313     PyErr_SetString(PyExc_TypeError,
2314                     "wrong type");
2315     return NULL;
2316 }
2317 
2318 static PyMethodDef PyCSimpleType_methods[] = {
2319     { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc },
2320     { "from_address", CDataType_from_address, METH_O, from_address_doc },
2321     { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
2322     { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
2323     { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
2324     { NULL, NULL },
2325 };
2326 
2327 PyTypeObject PyCSimpleType_Type = {
2328     PyVarObject_HEAD_INIT(NULL, 0)
2329     "_ctypes.PyCSimpleType",                                    /* tp_name */
2330     0,                                          /* tp_basicsize */
2331     0,                                          /* tp_itemsize */
2332     0,                                          /* tp_dealloc */
2333     0,                                          /* tp_vectorcall_offset */
2334     0,                                          /* tp_getattr */
2335     0,                                          /* tp_setattr */
2336     0,                                          /* tp_as_async */
2337     0,                                          /* tp_repr */
2338     0,                                          /* tp_as_number */
2339     &CDataType_as_sequence,             /* tp_as_sequence */
2340     0,                                          /* tp_as_mapping */
2341     0,                                          /* tp_hash */
2342     0,                                          /* tp_call */
2343     0,                                          /* tp_str */
2344     0,                                          /* tp_getattro */
2345     0,                                          /* tp_setattro */
2346     0,                                          /* tp_as_buffer */
2347     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2348     "metatype for the PyCSimpleType Objects",           /* tp_doc */
2349     0,                                          /* tp_traverse */
2350     0,                                          /* tp_clear */
2351     0,                                          /* tp_richcompare */
2352     0,                                          /* tp_weaklistoffset */
2353     0,                                          /* tp_iter */
2354     0,                                          /* tp_iternext */
2355     PyCSimpleType_methods,                      /* tp_methods */
2356     0,                                          /* tp_members */
2357     0,                                          /* tp_getset */
2358     0,                                          /* tp_base */
2359     0,                                          /* tp_dict */
2360     0,                                          /* tp_descr_get */
2361     0,                                          /* tp_descr_set */
2362     0,                                          /* tp_dictoffset */
2363     0,                                          /* tp_init */
2364     0,                                          /* tp_alloc */
2365     PyCSimpleType_new,                                  /* tp_new */
2366     0,                                          /* tp_free */
2367 };
2368 
2369 /******************************************************************/
2370 /*
2371   PyCFuncPtrType_Type
2372  */
2373 
2374 static PyObject *
converters_from_argtypes(PyObject * ob)2375 converters_from_argtypes(PyObject *ob)
2376 {
2377     _Py_IDENTIFIER(from_param);
2378     PyObject *converters;
2379     Py_ssize_t i;
2380     Py_ssize_t nArgs;
2381 
2382     ob = PySequence_Tuple(ob); /* new reference */
2383     if (!ob) {
2384         PyErr_SetString(PyExc_TypeError,
2385                         "_argtypes_ must be a sequence of types");
2386         return NULL;
2387     }
2388 
2389     nArgs = PyTuple_GET_SIZE(ob);
2390     converters = PyTuple_New(nArgs);
2391     if (!converters) {
2392         Py_DECREF(ob);
2393         return NULL;
2394     }
2395 
2396     /* I have to check if this is correct. Using c_char, which has a size
2397        of 1, will be assumed to be pushed as only one byte!
2398        Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
2399     */
2400 
2401     for (i = 0; i < nArgs; ++i) {
2402         PyObject *cnv;
2403         PyObject *tp = PyTuple_GET_ITEM(ob, i);
2404         StgDictObject *stgdict = PyType_stgdict(tp);
2405 
2406         if (stgdict != NULL) {
2407             if (stgdict->flags & TYPEFLAG_HASUNION) {
2408                 Py_DECREF(converters);
2409                 Py_DECREF(ob);
2410                 if (!PyErr_Occurred()) {
2411                     PyErr_Format(PyExc_TypeError,
2412                                  "item %zd in _argtypes_ passes a union by "
2413                                  "value, which is unsupported.",
2414                                  i + 1);
2415                 }
2416                 return NULL;
2417             }
2418             if (stgdict->flags & TYPEFLAG_HASBITFIELD) {
2419                 Py_DECREF(converters);
2420                 Py_DECREF(ob);
2421                 if (!PyErr_Occurred()) {
2422                     PyErr_Format(PyExc_TypeError,
2423                                  "item %zd in _argtypes_ passes a struct/"
2424                                  "union with a bitfield by value, which is "
2425                                  "unsupported.",
2426                                  i + 1);
2427                 }
2428                 return NULL;
2429             }
2430         }
2431 
2432         if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) {
2433             Py_DECREF(converters);
2434             Py_DECREF(ob);
2435             if (!PyErr_Occurred()) {
2436                 PyErr_Format(PyExc_TypeError,
2437                              "item %zd in _argtypes_ has no from_param method",
2438                              i+1);
2439             }
2440             return NULL;
2441         }
2442         PyTuple_SET_ITEM(converters, i, cnv);
2443     }
2444     Py_DECREF(ob);
2445     return converters;
2446 }
2447 
2448 static int
make_funcptrtype_dict(StgDictObject * stgdict)2449 make_funcptrtype_dict(StgDictObject *stgdict)
2450 {
2451     PyObject *ob;
2452     PyObject *converters = NULL;
2453     _Py_IDENTIFIER(_flags_);
2454     _Py_IDENTIFIER(_argtypes_);
2455     _Py_IDENTIFIER(_restype_);
2456     _Py_IDENTIFIER(_check_retval_);
2457 
2458     stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
2459     stgdict->length = 1;
2460     stgdict->size = sizeof(void *);
2461     stgdict->setfunc = NULL;
2462     stgdict->getfunc = NULL;
2463     stgdict->ffi_type_pointer = ffi_type_pointer;
2464 
2465     ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__flags_);
2466     if (!ob || !PyLong_Check(ob)) {
2467         if (!PyErr_Occurred()) {
2468             PyErr_SetString(PyExc_TypeError,
2469                 "class must define _flags_ which must be an integer");
2470         }
2471         return -1;
2472     }
2473     stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER;
2474 
2475     /* _argtypes_ is optional... */
2476     ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__argtypes_);
2477     if (ob) {
2478         converters = converters_from_argtypes(ob);
2479         if (!converters)
2480             return -1;
2481         Py_INCREF(ob);
2482         stgdict->argtypes = ob;
2483         stgdict->converters = converters;
2484     }
2485     else if (PyErr_Occurred()) {
2486         return -1;
2487     }
2488 
2489     ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__restype_);
2490     if (ob) {
2491         if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2492             PyErr_SetString(PyExc_TypeError,
2493                 "_restype_ must be a type, a callable, or None");
2494             return -1;
2495         }
2496         Py_INCREF(ob);
2497         stgdict->restype = ob;
2498         if (_PyObject_LookupAttrId(ob, &PyId__check_retval_,
2499                                    &stgdict->checker) < 0)
2500         {
2501             return -1;
2502         }
2503     }
2504     else if (PyErr_Occurred()) {
2505         return -1;
2506     }
2507 /* XXX later, maybe.
2508     ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__errcheck_);
2509     if (ob) {
2510         if (!PyCallable_Check(ob)) {
2511             PyErr_SetString(PyExc_TypeError,
2512                 "_errcheck_ must be callable");
2513             return -1;
2514         }
2515         Py_INCREF(ob);
2516         stgdict->errcheck = ob;
2517     }
2518     else if (PyErr_Occurred()) {
2519         return -1;
2520     }
2521 */
2522     return 0;
2523 }
2524 
2525 static PyCArgObject *
PyCFuncPtrType_paramfunc(CDataObject * self)2526 PyCFuncPtrType_paramfunc(CDataObject *self)
2527 {
2528     PyCArgObject *parg;
2529 
2530     parg = PyCArgObject_new();
2531     if (parg == NULL)
2532         return NULL;
2533 
2534     parg->tag = 'P';
2535     parg->pffi_type = &ffi_type_pointer;
2536     Py_INCREF(self);
2537     parg->obj = (PyObject *)self;
2538     parg->value.p = *(void **)self->b_ptr;
2539     return parg;
2540 }
2541 
2542 static PyObject *
PyCFuncPtrType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)2543 PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2544 {
2545     PyTypeObject *result;
2546     StgDictObject *stgdict;
2547 
2548     stgdict = (StgDictObject *)PyObject_CallObject(
2549         (PyObject *)&PyCStgDict_Type, NULL);
2550     if (!stgdict)
2551         return NULL;
2552 
2553     stgdict->paramfunc = PyCFuncPtrType_paramfunc;
2554     /* We do NOT expose the function signature in the format string.  It
2555        is impossible, generally, because the only requirement for the
2556        argtypes items is that they have a .from_param method - we do not
2557        know the types of the arguments (although, in practice, most
2558        argtypes would be a ctypes type).
2559     */
2560     stgdict->format = _ctypes_alloc_format_string(NULL, "X{}");
2561     if (stgdict->format == NULL) {
2562         Py_DECREF((PyObject *)stgdict);
2563         return NULL;
2564     }
2565     stgdict->flags |= TYPEFLAG_ISPOINTER;
2566 
2567     /* create the new instance (which is a class,
2568        since we are a metatype!) */
2569     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2570     if (result == NULL) {
2571         Py_DECREF((PyObject *)stgdict);
2572         return NULL;
2573     }
2574 
2575     /* replace the class dict by our updated storage dict */
2576     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2577         Py_DECREF(result);
2578         Py_DECREF((PyObject *)stgdict);
2579         return NULL;
2580     }
2581     Py_SETREF(result->tp_dict, (PyObject *)stgdict);
2582 
2583     if (-1 == make_funcptrtype_dict(stgdict)) {
2584         Py_DECREF(result);
2585         return NULL;
2586     }
2587 
2588     return (PyObject *)result;
2589 }
2590 
2591 PyTypeObject PyCFuncPtrType_Type = {
2592     PyVarObject_HEAD_INIT(NULL, 0)
2593     "_ctypes.PyCFuncPtrType",                           /* tp_name */
2594     0,                                          /* tp_basicsize */
2595     0,                                          /* tp_itemsize */
2596     0,                                          /* tp_dealloc */
2597     0,                                          /* tp_vectorcall_offset */
2598     0,                                          /* tp_getattr */
2599     0,                                          /* tp_setattr */
2600     0,                                          /* tp_as_async */
2601     0,                                          /* tp_repr */
2602     0,                                          /* tp_as_number */
2603     &CDataType_as_sequence,                     /* tp_as_sequence */
2604     0,                                          /* tp_as_mapping */
2605     0,                                          /* tp_hash */
2606     0,                                          /* tp_call */
2607     0,                                          /* tp_str */
2608     0,                                          /* tp_getattro */
2609     0,                                          /* tp_setattro */
2610     0,                                          /* tp_as_buffer */
2611     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2612     "metatype for C function pointers",         /* tp_doc */
2613     (traverseproc)CDataType_traverse,           /* tp_traverse */
2614     (inquiry)CDataType_clear,                   /* tp_clear */
2615     0,                                          /* tp_richcompare */
2616     0,                                          /* tp_weaklistoffset */
2617     0,                                          /* tp_iter */
2618     0,                                          /* tp_iternext */
2619     CDataType_methods,                          /* tp_methods */
2620     0,                                          /* tp_members */
2621     0,                                          /* tp_getset */
2622     0,                                          /* tp_base */
2623     0,                                          /* tp_dict */
2624     0,                                          /* tp_descr_get */
2625     0,                                          /* tp_descr_set */
2626     0,                                          /* tp_dictoffset */
2627     0,                                          /* tp_init */
2628     0,                                          /* tp_alloc */
2629     PyCFuncPtrType_new,                         /* tp_new */
2630     0,                                          /* tp_free */
2631 };
2632 
2633 
2634 /*****************************************************************
2635  * Code to keep needed objects alive
2636  */
2637 
2638 static CDataObject *
PyCData_GetContainer(CDataObject * self)2639 PyCData_GetContainer(CDataObject *self)
2640 {
2641     while (self->b_base)
2642         self = self->b_base;
2643     if (self->b_objects == NULL) {
2644         if (self->b_length) {
2645             self->b_objects = PyDict_New();
2646             if (self->b_objects == NULL)
2647                 return NULL;
2648         } else {
2649             Py_INCREF(Py_None);
2650             self->b_objects = Py_None;
2651         }
2652     }
2653     return self;
2654 }
2655 
2656 static PyObject *
GetKeepedObjects(CDataObject * target)2657 GetKeepedObjects(CDataObject *target)
2658 {
2659     CDataObject *container;
2660     container = PyCData_GetContainer(target);
2661     if (container == NULL)
2662         return NULL;
2663     return container->b_objects;
2664 }
2665 
2666 static PyObject *
unique_key(CDataObject * target,Py_ssize_t index)2667 unique_key(CDataObject *target, Py_ssize_t index)
2668 {
2669     char string[256];
2670     char *cp = string;
2671     size_t bytes_left;
2672 
2673     Py_BUILD_ASSERT(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
2674     cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2675     while (target->b_base) {
2676         bytes_left = sizeof(string) - (cp - string) - 1;
2677         /* Hex format needs 2 characters per byte */
2678         if (bytes_left < sizeof(Py_ssize_t) * 2) {
2679             PyErr_SetString(PyExc_ValueError,
2680                             "ctypes object structure too deep");
2681             return NULL;
2682         }
2683         cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
2684         target = target->b_base;
2685     }
2686     return PyUnicode_FromStringAndSize(string, cp-string);
2687 }
2688 
2689 /*
2690  * Keep a reference to 'keep' in the 'target', at index 'index'.
2691  *
2692  * If 'keep' is None, do nothing.
2693  *
2694  * Otherwise create a dictionary (if it does not yet exist) id the root
2695  * objects 'b_objects' item, which will store the 'keep' object under a unique
2696  * key.
2697  *
2698  * The unique_key helper travels the target's b_base pointer down to the root,
2699  * building a string containing hex-formatted indexes found during traversal,
2700  * separated by colons.
2701  *
2702  * The index tuple is used as a key into the root object's b_objects dict.
2703  *
2704  * Note: This function steals a refcount of the third argument, even if it
2705  * fails!
2706  */
2707 static int
KeepRef(CDataObject * target,Py_ssize_t index,PyObject * keep)2708 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
2709 {
2710     int result;
2711     CDataObject *ob;
2712     PyObject *key;
2713 
2714 /* Optimization: no need to store None */
2715     if (keep == Py_None) {
2716         Py_DECREF(Py_None);
2717         return 0;
2718     }
2719     ob = PyCData_GetContainer(target);
2720     if (ob == NULL) {
2721         Py_DECREF(keep);
2722         return -1;
2723     }
2724     if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
2725         Py_XSETREF(ob->b_objects, keep); /* refcount consumed */
2726         return 0;
2727     }
2728     key = unique_key(target, index);
2729     if (key == NULL) {
2730         Py_DECREF(keep);
2731         return -1;
2732     }
2733     result = PyDict_SetItem(ob->b_objects, key, keep);
2734     Py_DECREF(key);
2735     Py_DECREF(keep);
2736     return result;
2737 }
2738 
2739 /******************************************************************/
2740 /*
2741   PyCData_Type
2742  */
2743 static int
PyCData_traverse(CDataObject * self,visitproc visit,void * arg)2744 PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
2745 {
2746     Py_VISIT(self->b_objects);
2747     Py_VISIT((PyObject *)self->b_base);
2748     return 0;
2749 }
2750 
2751 static int
PyCData_clear(CDataObject * self)2752 PyCData_clear(CDataObject *self)
2753 {
2754     Py_CLEAR(self->b_objects);
2755     if ((self->b_needsfree)
2756         && _CDataObject_HasExternalBuffer(self))
2757         PyMem_Free(self->b_ptr);
2758     self->b_ptr = NULL;
2759     Py_CLEAR(self->b_base);
2760     return 0;
2761 }
2762 
2763 static void
PyCData_dealloc(PyObject * self)2764 PyCData_dealloc(PyObject *self)
2765 {
2766     PyCData_clear((CDataObject *)self);
2767     Py_TYPE(self)->tp_free(self);
2768 }
2769 
2770 static PyMemberDef PyCData_members[] = {
2771     { "_b_base_", T_OBJECT,
2772       offsetof(CDataObject, b_base), READONLY,
2773       "the base object" },
2774     { "_b_needsfree_", T_INT,
2775       offsetof(CDataObject, b_needsfree), READONLY,
2776       "whether the object owns the memory or not" },
2777     { "_objects", T_OBJECT,
2778       offsetof(CDataObject, b_objects), READONLY,
2779       "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2780     { NULL },
2781 };
2782 
PyCData_NewGetBuffer(PyObject * myself,Py_buffer * view,int flags)2783 static int PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
2784 {
2785     CDataObject *self = (CDataObject *)myself;
2786     StgDictObject *dict = PyObject_stgdict(myself);
2787     Py_ssize_t i;
2788 
2789     if (view == NULL) return 0;
2790 
2791     view->buf = self->b_ptr;
2792     view->obj = myself;
2793     Py_INCREF(myself);
2794     view->len = self->b_size;
2795     view->readonly = 0;
2796     /* use default format character if not set */
2797     view->format = dict->format ? dict->format : "B";
2798     view->ndim = dict->ndim;
2799     view->shape = dict->shape;
2800     view->itemsize = self->b_size;
2801     if (view->itemsize) {
2802         for (i = 0; i < view->ndim; ++i) {
2803             view->itemsize /= dict->shape[i];
2804         }
2805     }
2806     view->strides = NULL;
2807     view->suboffsets = NULL;
2808     view->internal = NULL;
2809     return 0;
2810 }
2811 
2812 static PyBufferProcs PyCData_as_buffer = {
2813     PyCData_NewGetBuffer,
2814     NULL,
2815 };
2816 
2817 /*
2818  * CData objects are mutable, so they cannot be hashable!
2819  */
2820 static Py_hash_t
PyCData_nohash(PyObject * self)2821 PyCData_nohash(PyObject *self)
2822 {
2823     PyErr_SetString(PyExc_TypeError, "unhashable type");
2824     return -1;
2825 }
2826 
2827 static PyObject *
PyCData_reduce(PyObject * myself,PyObject * args)2828 PyCData_reduce(PyObject *myself, PyObject *args)
2829 {
2830     CDataObject *self = (CDataObject *)myself;
2831 
2832     if (PyObject_stgdict(myself)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
2833         PyErr_SetString(PyExc_ValueError,
2834                         "ctypes objects containing pointers cannot be pickled");
2835         return NULL;
2836     }
2837     PyObject *dict = PyObject_GetAttrString(myself, "__dict__");
2838     if (dict == NULL) {
2839         return NULL;
2840     }
2841     return Py_BuildValue("O(O(NN))", _unpickle, Py_TYPE(myself), dict,
2842                          PyBytes_FromStringAndSize(self->b_ptr, self->b_size));
2843 }
2844 
2845 static PyObject *
PyCData_setstate(PyObject * myself,PyObject * args)2846 PyCData_setstate(PyObject *myself, PyObject *args)
2847 {
2848     void *data;
2849     Py_ssize_t len;
2850     int res;
2851     PyObject *dict, *mydict;
2852     CDataObject *self = (CDataObject *)myself;
2853     if (!PyArg_ParseTuple(args, "O!s#",
2854                           &PyDict_Type, &dict, &data, &len))
2855     {
2856         return NULL;
2857     }
2858     if (len > self->b_size)
2859         len = self->b_size;
2860     memmove(self->b_ptr, data, len);
2861     mydict = PyObject_GetAttrString(myself, "__dict__");
2862     if (mydict == NULL) {
2863         return NULL;
2864     }
2865     if (!PyDict_Check(mydict)) {
2866         PyErr_Format(PyExc_TypeError,
2867                      "%.200s.__dict__ must be a dictionary, not %.200s",
2868                      Py_TYPE(myself)->tp_name, Py_TYPE(mydict)->tp_name);
2869         Py_DECREF(mydict);
2870         return NULL;
2871     }
2872     res = PyDict_Update(mydict, dict);
2873     Py_DECREF(mydict);
2874     if (res == -1)
2875         return NULL;
2876     Py_RETURN_NONE;
2877 }
2878 
2879 /*
2880  * default __ctypes_from_outparam__ method returns self.
2881  */
2882 static PyObject *
PyCData_from_outparam(PyObject * self,PyObject * args)2883 PyCData_from_outparam(PyObject *self, PyObject *args)
2884 {
2885     Py_INCREF(self);
2886     return self;
2887 }
2888 
2889 static PyMethodDef PyCData_methods[] = {
2890     { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
2891     { "__reduce__", PyCData_reduce, METH_NOARGS, },
2892     { "__setstate__", PyCData_setstate, METH_VARARGS, },
2893     { NULL, NULL },
2894 };
2895 
2896 PyTypeObject PyCData_Type = {
2897     PyVarObject_HEAD_INIT(NULL, 0)
2898     "_ctypes._CData",
2899     sizeof(CDataObject),                        /* tp_basicsize */
2900     0,                                          /* tp_itemsize */
2901     PyCData_dealloc,                                    /* tp_dealloc */
2902     0,                                          /* tp_vectorcall_offset */
2903     0,                                          /* tp_getattr */
2904     0,                                          /* tp_setattr */
2905     0,                                          /* tp_as_async */
2906     0,                                          /* tp_repr */
2907     0,                                          /* tp_as_number */
2908     0,                                          /* tp_as_sequence */
2909     0,                                          /* tp_as_mapping */
2910     PyCData_nohash,                             /* tp_hash */
2911     0,                                          /* tp_call */
2912     0,                                          /* tp_str */
2913     0,                                          /* tp_getattro */
2914     0,                                          /* tp_setattro */
2915     &PyCData_as_buffer,                         /* tp_as_buffer */
2916     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2917     "XXX to be provided",                       /* tp_doc */
2918     (traverseproc)PyCData_traverse,             /* tp_traverse */
2919     (inquiry)PyCData_clear,                     /* tp_clear */
2920     0,                                          /* tp_richcompare */
2921     0,                                          /* tp_weaklistoffset */
2922     0,                                          /* tp_iter */
2923     0,                                          /* tp_iternext */
2924     PyCData_methods,                                    /* tp_methods */
2925     PyCData_members,                                    /* tp_members */
2926     0,                                          /* tp_getset */
2927     0,                                          /* tp_base */
2928     0,                                          /* tp_dict */
2929     0,                                          /* tp_descr_get */
2930     0,                                          /* tp_descr_set */
2931     0,                                          /* tp_dictoffset */
2932     0,                                          /* tp_init */
2933     0,                                          /* tp_alloc */
2934     0,                                          /* tp_new */
2935     0,                                          /* tp_free */
2936 };
2937 
PyCData_MallocBuffer(CDataObject * obj,StgDictObject * dict)2938 static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
2939 {
2940     if ((size_t)dict->size <= sizeof(obj->b_value)) {
2941         /* No need to call malloc, can use the default buffer */
2942         obj->b_ptr = (char *)&obj->b_value;
2943         /* The b_needsfree flag does not mean that we actually did
2944            call PyMem_Malloc to allocate the memory block; instead it
2945            means we are the *owner* of the memory and are responsible
2946            for freeing resources associated with the memory.  This is
2947            also the reason that b_needsfree is exposed to Python.
2948          */
2949         obj->b_needsfree = 1;
2950     } else {
2951         /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2952            33% of the creation time for c_int().
2953         */
2954         obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2955         if (obj->b_ptr == NULL) {
2956             PyErr_NoMemory();
2957             return -1;
2958         }
2959         obj->b_needsfree = 1;
2960         memset(obj->b_ptr, 0, dict->size);
2961     }
2962     obj->b_size = dict->size;
2963     return 0;
2964 }
2965 
2966 PyObject *
PyCData_FromBaseObj(PyObject * type,PyObject * base,Py_ssize_t index,char * adr)2967 PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
2968 {
2969     CDataObject *cmem;
2970     StgDictObject *dict;
2971 
2972     assert(PyType_Check(type));
2973     dict = PyType_stgdict(type);
2974     if (!dict) {
2975         PyErr_SetString(PyExc_TypeError,
2976                         "abstract class");
2977         return NULL;
2978     }
2979     dict->flags |= DICTFLAG_FINAL;
2980     cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2981     if (cmem == NULL)
2982         return NULL;
2983     assert(CDataObject_Check(cmem));
2984 
2985     cmem->b_length = dict->length;
2986     cmem->b_size = dict->size;
2987     if (base) { /* use base's buffer */
2988         assert(CDataObject_Check(base));
2989         cmem->b_ptr = adr;
2990         cmem->b_needsfree = 0;
2991         Py_INCREF(base);
2992         cmem->b_base = (CDataObject *)base;
2993         cmem->b_index = index;
2994     } else { /* copy contents of adr */
2995         if (-1 == PyCData_MallocBuffer(cmem, dict)) {
2996             Py_DECREF(cmem);
2997             return NULL;
2998         }
2999         memcpy(cmem->b_ptr, adr, dict->size);
3000         cmem->b_index = index;
3001     }
3002     return (PyObject *)cmem;
3003 }
3004 
3005 /*
3006  Box a memory block into a CData instance.
3007 */
3008 PyObject *
PyCData_AtAddress(PyObject * type,void * buf)3009 PyCData_AtAddress(PyObject *type, void *buf)
3010 {
3011     CDataObject *pd;
3012     StgDictObject *dict;
3013 
3014     if (PySys_Audit("ctypes.cdata", "n", (Py_ssize_t)buf) < 0) {
3015         return NULL;
3016     }
3017 
3018     assert(PyType_Check(type));
3019     dict = PyType_stgdict(type);
3020     if (!dict) {
3021         PyErr_SetString(PyExc_TypeError,
3022                         "abstract class");
3023         return NULL;
3024     }
3025     dict->flags |= DICTFLAG_FINAL;
3026 
3027     pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
3028     if (!pd)
3029         return NULL;
3030     assert(CDataObject_Check(pd));
3031     pd->b_ptr = (char *)buf;
3032     pd->b_length = dict->length;
3033     pd->b_size = dict->size;
3034     return (PyObject *)pd;
3035 }
3036 
3037 /*
3038   This function returns TRUE for c_int, c_void_p, and these kind of
3039   classes.  FALSE otherwise FALSE also for subclasses of c_int and
3040   such.
3041 */
_ctypes_simple_instance(PyObject * obj)3042 int _ctypes_simple_instance(PyObject *obj)
3043 {
3044     PyTypeObject *type = (PyTypeObject *)obj;
3045 
3046     if (PyCSimpleTypeObject_Check(type))
3047         return type->tp_base != &Simple_Type;
3048     return 0;
3049 }
3050 
3051 PyObject *
PyCData_get(PyObject * type,GETFUNC getfunc,PyObject * src,Py_ssize_t index,Py_ssize_t size,char * adr)3052 PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
3053           Py_ssize_t index, Py_ssize_t size, char *adr)
3054 {
3055     StgDictObject *dict;
3056     if (getfunc)
3057         return getfunc(adr, size);
3058     assert(type);
3059     dict = PyType_stgdict(type);
3060     if (dict && dict->getfunc && !_ctypes_simple_instance(type))
3061         return dict->getfunc(adr, size);
3062     return PyCData_FromBaseObj(type, src, index, adr);
3063 }
3064 
3065 /*
3066   Helper function for PyCData_set below.
3067 */
3068 static PyObject *
_PyCData_set(CDataObject * dst,PyObject * type,SETFUNC setfunc,PyObject * value,Py_ssize_t size,char * ptr)3069 _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
3070            Py_ssize_t size, char *ptr)
3071 {
3072     CDataObject *src;
3073     int err;
3074 
3075     if (setfunc)
3076         return setfunc(ptr, value, size);
3077 
3078     if (!CDataObject_Check(value)) {
3079         StgDictObject *dict = PyType_stgdict(type);
3080         if (dict && dict->setfunc)
3081             return dict->setfunc(ptr, value, size);
3082         /*
3083            If value is a tuple, we try to call the type with the tuple
3084            and use the result!
3085         */
3086         assert(PyType_Check(type));
3087         if (PyTuple_Check(value)) {
3088             PyObject *ob;
3089             PyObject *result;
3090             ob = PyObject_CallObject(type, value);
3091             if (ob == NULL) {
3092                 _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
3093                                   ((PyTypeObject *)type)->tp_name);
3094                 return NULL;
3095             }
3096             result = _PyCData_set(dst, type, setfunc, ob,
3097                                 size, ptr);
3098             Py_DECREF(ob);
3099             return result;
3100         } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
3101             *(void **)ptr = NULL;
3102             Py_RETURN_NONE;
3103         } else {
3104             PyErr_Format(PyExc_TypeError,
3105                          "expected %s instance, got %s",
3106                          ((PyTypeObject *)type)->tp_name,
3107                          Py_TYPE(value)->tp_name);
3108             return NULL;
3109         }
3110     }
3111     src = (CDataObject *)value;
3112 
3113     err = PyObject_IsInstance(value, type);
3114     if (err == -1)
3115         return NULL;
3116     if (err) {
3117         memcpy(ptr,
3118                src->b_ptr,
3119                size);
3120 
3121         if (PyCPointerTypeObject_Check(type)) {
3122             /* XXX */
3123         }
3124 
3125         value = GetKeepedObjects(src);
3126         if (value == NULL)
3127             return NULL;
3128 
3129         Py_INCREF(value);
3130         return value;
3131     }
3132 
3133     if (PyCPointerTypeObject_Check(type)
3134         && ArrayObject_Check(value)) {
3135         StgDictObject *p1, *p2;
3136         PyObject *keep;
3137         p1 = PyObject_stgdict(value);
3138         assert(p1); /* Cannot be NULL for array instances */
3139         p2 = PyType_stgdict(type);
3140         assert(p2); /* Cannot be NULL for pointer types */
3141 
3142         if (p1->proto != p2->proto) {
3143             PyErr_Format(PyExc_TypeError,
3144                          "incompatible types, %s instance instead of %s instance",
3145                          Py_TYPE(value)->tp_name,
3146                          ((PyTypeObject *)type)->tp_name);
3147             return NULL;
3148         }
3149         *(void **)ptr = src->b_ptr;
3150 
3151         keep = GetKeepedObjects(src);
3152         if (keep == NULL)
3153             return NULL;
3154 
3155         /*
3156           We are assigning an array object to a field which represents
3157           a pointer. This has the same effect as converting an array
3158           into a pointer. So, again, we have to keep the whole object
3159           pointed to (which is the array in this case) alive, and not
3160           only it's object list.  So we create a tuple, containing
3161           b_objects list PLUS the array itself, and return that!
3162         */
3163         return PyTuple_Pack(2, keep, value);
3164     }
3165     PyErr_Format(PyExc_TypeError,
3166                  "incompatible types, %s instance instead of %s instance",
3167                  Py_TYPE(value)->tp_name,
3168                  ((PyTypeObject *)type)->tp_name);
3169     return NULL;
3170 }
3171 
3172 /*
3173  * Set a slice in object 'dst', which has the type 'type',
3174  * to the value 'value'.
3175  */
3176 int
PyCData_set(PyObject * dst,PyObject * type,SETFUNC setfunc,PyObject * value,Py_ssize_t index,Py_ssize_t size,char * ptr)3177 PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
3178           Py_ssize_t index, Py_ssize_t size, char *ptr)
3179 {
3180     CDataObject *mem = (CDataObject *)dst;
3181     PyObject *result;
3182 
3183     if (!CDataObject_Check(dst)) {
3184         PyErr_SetString(PyExc_TypeError,
3185                         "not a ctype instance");
3186         return -1;
3187     }
3188 
3189     result = _PyCData_set(mem, type, setfunc, value,
3190                         size, ptr);
3191     if (result == NULL)
3192         return -1;
3193 
3194     /* KeepRef steals a refcount from it's last argument */
3195     /* If KeepRef fails, we are stumped.  The dst memory block has already
3196        been changed */
3197     return KeepRef(mem, index, result);
3198 }
3199 
3200 
3201 /******************************************************************/
3202 static PyObject *
GenericPyCData_new(PyTypeObject * type,PyObject * args,PyObject * kwds)3203 GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3204 {
3205     CDataObject *obj;
3206     StgDictObject *dict;
3207 
3208     dict = PyType_stgdict((PyObject *)type);
3209     if (!dict) {
3210         PyErr_SetString(PyExc_TypeError,
3211                         "abstract class");
3212         return NULL;
3213     }
3214     dict->flags |= DICTFLAG_FINAL;
3215 
3216     obj = (CDataObject *)type->tp_alloc(type, 0);
3217     if (!obj)
3218         return NULL;
3219 
3220     obj->b_base = NULL;
3221     obj->b_index = 0;
3222     obj->b_objects = NULL;
3223     obj->b_length = dict->length;
3224 
3225     if (-1 == PyCData_MallocBuffer(obj, dict)) {
3226         Py_DECREF(obj);
3227         return NULL;
3228     }
3229     return (PyObject *)obj;
3230 }
3231 /*****************************************************************/
3232 /*
3233   PyCFuncPtr_Type
3234 */
3235 
3236 static int
PyCFuncPtr_set_errcheck(PyCFuncPtrObject * self,PyObject * ob,void * Py_UNUSED (ignored))3237 PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
3238 {
3239     if (ob && !PyCallable_Check(ob)) {
3240         PyErr_SetString(PyExc_TypeError,
3241                         "the errcheck attribute must be callable");
3242         return -1;
3243     }
3244     Py_XINCREF(ob);
3245     Py_XSETREF(self->errcheck, ob);
3246     return 0;
3247 }
3248 
3249 static PyObject *
PyCFuncPtr_get_errcheck(PyCFuncPtrObject * self,void * Py_UNUSED (ignored))3250 PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
3251 {
3252     if (self->errcheck) {
3253         Py_INCREF(self->errcheck);
3254         return self->errcheck;
3255     }
3256     Py_RETURN_NONE;
3257 }
3258 
3259 static int
PyCFuncPtr_set_restype(PyCFuncPtrObject * self,PyObject * ob,void * Py_UNUSED (ignored))3260 PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
3261 {
3262     _Py_IDENTIFIER(_check_retval_);
3263     PyObject *checker, *oldchecker;
3264     if (ob == NULL) {
3265         oldchecker = self->checker;
3266         self->checker = NULL;
3267         Py_CLEAR(self->restype);
3268         Py_XDECREF(oldchecker);
3269         return 0;
3270     }
3271     if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
3272         PyErr_SetString(PyExc_TypeError,
3273                         "restype must be a type, a callable, or None");
3274         return -1;
3275     }
3276     if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, &checker) < 0) {
3277         return -1;
3278     }
3279     oldchecker = self->checker;
3280     self->checker = checker;
3281     Py_INCREF(ob);
3282     Py_XSETREF(self->restype, ob);
3283     Py_XDECREF(oldchecker);
3284     return 0;
3285 }
3286 
3287 static PyObject *
PyCFuncPtr_get_restype(PyCFuncPtrObject * self,void * Py_UNUSED (ignored))3288 PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
3289 {
3290     StgDictObject *dict;
3291     if (self->restype) {
3292         Py_INCREF(self->restype);
3293         return self->restype;
3294     }
3295     dict = PyObject_stgdict((PyObject *)self);
3296     assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3297     if (dict->restype) {
3298         Py_INCREF(dict->restype);
3299         return dict->restype;
3300     } else {
3301         Py_RETURN_NONE;
3302     }
3303 }
3304 
3305 static int
PyCFuncPtr_set_argtypes(PyCFuncPtrObject * self,PyObject * ob,void * Py_UNUSED (ignored))3306 PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
3307 {
3308     PyObject *converters;
3309 
3310     if (ob == NULL || ob == Py_None) {
3311         Py_CLEAR(self->converters);
3312         Py_CLEAR(self->argtypes);
3313     } else {
3314         converters = converters_from_argtypes(ob);
3315         if (!converters)
3316             return -1;
3317         Py_XSETREF(self->converters, converters);
3318         Py_INCREF(ob);
3319         Py_XSETREF(self->argtypes, ob);
3320     }
3321     return 0;
3322 }
3323 
3324 static PyObject *
PyCFuncPtr_get_argtypes(PyCFuncPtrObject * self,void * Py_UNUSED (ignored))3325 PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
3326 {
3327     StgDictObject *dict;
3328     if (self->argtypes) {
3329         Py_INCREF(self->argtypes);
3330         return self->argtypes;
3331     }
3332     dict = PyObject_stgdict((PyObject *)self);
3333     assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3334     if (dict->argtypes) {
3335         Py_INCREF(dict->argtypes);
3336         return dict->argtypes;
3337     } else {
3338         Py_RETURN_NONE;
3339     }
3340 }
3341 
3342 static PyGetSetDef PyCFuncPtr_getsets[] = {
3343     { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
3344       "a function to check for errors", NULL },
3345     { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
3346       "specify the result type", NULL },
3347     { "argtypes", (getter)PyCFuncPtr_get_argtypes,
3348       (setter)PyCFuncPtr_set_argtypes,
3349       "specify the argument types", NULL },
3350     { NULL, NULL }
3351 };
3352 
3353 #ifdef MS_WIN32
FindAddress(void * handle,const char * name,PyObject * type)3354 static PPROC FindAddress(void *handle, const char *name, PyObject *type)
3355 {
3356     PPROC address;
3357 #ifdef MS_WIN64
3358     /* win64 has no stdcall calling conv, so it should
3359        also not have the name mangling of it.
3360     */
3361     Py_BEGIN_ALLOW_THREADS
3362     address = (PPROC)GetProcAddress(handle, name);
3363     Py_END_ALLOW_THREADS
3364     return address;
3365 #else
3366     char *mangled_name;
3367     int i;
3368     StgDictObject *dict;
3369 
3370     Py_BEGIN_ALLOW_THREADS
3371     address = (PPROC)GetProcAddress(handle, name);
3372     Py_END_ALLOW_THREADS
3373     if (address)
3374         return address;
3375     if (((size_t)name & ~0xFFFF) == 0) {
3376         return NULL;
3377     }
3378 
3379     dict = PyType_stgdict((PyObject *)type);
3380     /* It should not happen that dict is NULL, but better be safe */
3381     if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
3382         return address;
3383 
3384     /* for stdcall, try mangled names:
3385        funcname -> _funcname@<n>
3386        where n is 0, 4, 8, 12, ..., 128
3387      */
3388     mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
3389     if (!mangled_name)
3390         return NULL;
3391     for (i = 0; i < 32; ++i) {
3392         sprintf(mangled_name, "_%s@%d", name, i*4);
3393         Py_BEGIN_ALLOW_THREADS
3394         address = (PPROC)GetProcAddress(handle, mangled_name);
3395         Py_END_ALLOW_THREADS
3396         if (address)
3397             return address;
3398     }
3399     return NULL;
3400 #endif
3401 }
3402 #endif
3403 
3404 /* Return 1 if usable, 0 else and exception set. */
3405 static int
_check_outarg_type(PyObject * arg,Py_ssize_t index)3406 _check_outarg_type(PyObject *arg, Py_ssize_t index)
3407 {
3408     StgDictObject *dict;
3409 
3410     if (PyCPointerTypeObject_Check(arg))
3411         return 1;
3412 
3413     if (PyCArrayTypeObject_Check(arg))
3414         return 1;
3415 
3416     dict = PyType_stgdict(arg);
3417     if (dict
3418         /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
3419         && PyUnicode_Check(dict->proto)
3420 /* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
3421         && (strchr("PzZ", PyUnicode_AsUTF8(dict->proto)[0]))) {
3422         return 1;
3423     }
3424 
3425     PyErr_Format(PyExc_TypeError,
3426                  "'out' parameter %d must be a pointer type, not %s",
3427                  Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
3428                  PyType_Check(arg) ?
3429                  ((PyTypeObject *)arg)->tp_name :
3430              Py_TYPE(arg)->tp_name);
3431     return 0;
3432 }
3433 
3434 /* Returns 1 on success, 0 on error */
3435 static int
_validate_paramflags(PyTypeObject * type,PyObject * paramflags)3436 _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
3437 {
3438     Py_ssize_t i, len;
3439     StgDictObject *dict;
3440     PyObject *argtypes;
3441 
3442     dict = PyType_stgdict((PyObject *)type);
3443     if (!dict) {
3444         PyErr_SetString(PyExc_TypeError,
3445                         "abstract class");
3446         return 0;
3447     }
3448     argtypes = dict->argtypes;
3449 
3450     if (paramflags == NULL || dict->argtypes == NULL)
3451         return 1;
3452 
3453     if (!PyTuple_Check(paramflags)) {
3454         PyErr_SetString(PyExc_TypeError,
3455                         "paramflags must be a tuple or None");
3456         return 0;
3457     }
3458 
3459     len = PyTuple_GET_SIZE(paramflags);
3460     if (len != PyTuple_GET_SIZE(dict->argtypes)) {
3461         PyErr_SetString(PyExc_ValueError,
3462                         "paramflags must have the same length as argtypes");
3463         return 0;
3464     }
3465 
3466     for (i = 0; i < len; ++i) {
3467         PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3468         int flag;
3469         char *name;
3470         PyObject *defval;
3471         PyObject *typ;
3472         if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) {
3473             PyErr_SetString(PyExc_TypeError,
3474                    "paramflags must be a sequence of (int [,string [,value]]) tuples");
3475             return 0;
3476         }
3477         typ = PyTuple_GET_ITEM(argtypes, i);
3478         switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3479         case 0:
3480         case PARAMFLAG_FIN:
3481         case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3482         case PARAMFLAG_FIN | PARAMFLAG_FOUT:
3483             break;
3484         case PARAMFLAG_FOUT:
3485             if (!_check_outarg_type(typ, i+1))
3486                 return 0;
3487             break;
3488         default:
3489             PyErr_Format(PyExc_TypeError,
3490                          "paramflag value %d not supported",
3491                          flag);
3492             return 0;
3493         }
3494     }
3495     return 1;
3496 }
3497 
3498 static int
_get_name(PyObject * obj,const char ** pname)3499 _get_name(PyObject *obj, const char **pname)
3500 {
3501 #ifdef MS_WIN32
3502     if (PyLong_Check(obj)) {
3503         /* We have to use MAKEINTRESOURCEA for Windows CE.
3504            Works on Windows as well, of course.
3505         */
3506         *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF);
3507         return 1;
3508     }
3509 #endif
3510     if (PyBytes_Check(obj)) {
3511         *pname = PyBytes_AS_STRING(obj);
3512         return *pname ? 1 : 0;
3513     }
3514     if (PyUnicode_Check(obj)) {
3515         *pname = PyUnicode_AsUTF8(obj);
3516         return *pname ? 1 : 0;
3517     }
3518     PyErr_SetString(PyExc_TypeError,
3519                     "function name must be string, bytes object or integer");
3520     return 0;
3521 }
3522 
3523 
3524 static PyObject *
PyCFuncPtr_FromDll(PyTypeObject * type,PyObject * args,PyObject * kwds)3525 PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
3526 {
3527     const char *name;
3528     int (* address)(void);
3529     PyObject *ftuple;
3530     PyObject *dll;
3531     PyObject *obj;
3532     PyCFuncPtrObject *self;
3533     void *handle;
3534     PyObject *paramflags = NULL;
3535 
3536     if (!PyArg_ParseTuple(args, "O|O", &ftuple, &paramflags))
3537         return NULL;
3538     if (paramflags == Py_None)
3539         paramflags = NULL;
3540 
3541     ftuple = PySequence_Tuple(ftuple);
3542     if (!ftuple)
3543         /* Here ftuple is a borrowed reference */
3544         return NULL;
3545 
3546     if (!PyArg_ParseTuple(ftuple, "O&O;illegal func_spec argument",
3547                           _get_name, &name, &dll))
3548     {
3549         Py_DECREF(ftuple);
3550         return NULL;
3551     }
3552 
3553 #ifdef MS_WIN32
3554     if (PySys_Audit("ctypes.dlsym",
3555                     ((uintptr_t)name & ~0xFFFF) ? "Os" : "On",
3556                     dll, name) < 0) {
3557         return NULL;
3558     }
3559 #else
3560     if (PySys_Audit("ctypes.dlsym", "Os", dll, name) < 0) {
3561         return NULL;
3562     }
3563 #endif
3564 
3565     obj = PyObject_GetAttrString(dll, "_handle");
3566     if (!obj) {
3567         Py_DECREF(ftuple);
3568         return NULL;
3569     }
3570     if (!PyLong_Check(obj)) {
3571         PyErr_SetString(PyExc_TypeError,
3572                         "the _handle attribute of the second argument must be an integer");
3573         Py_DECREF(ftuple);
3574         Py_DECREF(obj);
3575         return NULL;
3576     }
3577     handle = (void *)PyLong_AsVoidPtr(obj);
3578     Py_DECREF(obj);
3579     if (PyErr_Occurred()) {
3580         PyErr_SetString(PyExc_ValueError,
3581                         "could not convert the _handle attribute to a pointer");
3582         Py_DECREF(ftuple);
3583         return NULL;
3584     }
3585 
3586 #ifdef MS_WIN32
3587     address = FindAddress(handle, name, (PyObject *)type);
3588     if (!address) {
3589         if (!IS_INTRESOURCE(name))
3590             PyErr_Format(PyExc_AttributeError,
3591                          "function '%s' not found",
3592                          name);
3593         else
3594             PyErr_Format(PyExc_AttributeError,
3595                          "function ordinal %d not found",
3596                          (WORD)(size_t)name);
3597         Py_DECREF(ftuple);
3598         return NULL;
3599     }
3600 #else
3601     address = (PPROC)ctypes_dlsym(handle, name);
3602     if (!address) {
3603 #ifdef __CYGWIN__
3604 /* dlerror() isn't very helpful on cygwin */
3605         PyErr_Format(PyExc_AttributeError,
3606                      "function '%s' not found",
3607                      name);
3608 #else
3609         PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
3610 #endif
3611         Py_DECREF(ftuple);
3612         return NULL;
3613     }
3614 #endif
3615     if (!_validate_paramflags(type, paramflags)) {
3616         Py_DECREF(ftuple);
3617         return NULL;
3618     }
3619 
3620     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3621     if (!self) {
3622         Py_DECREF(ftuple);
3623         return NULL;
3624     }
3625 
3626     Py_XINCREF(paramflags);
3627     self->paramflags = paramflags;
3628 
3629     *(void **)self->b_ptr = address;
3630     Py_INCREF(dll);
3631     Py_DECREF(ftuple);
3632     if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
3633         Py_DECREF((PyObject *)self);
3634         return NULL;
3635     }
3636 
3637     Py_INCREF(self);
3638     self->callable = (PyObject *)self;
3639     return (PyObject *)self;
3640 }
3641 
3642 #ifdef MS_WIN32
3643 static PyObject *
PyCFuncPtr_FromVtblIndex(PyTypeObject * type,PyObject * args,PyObject * kwds)3644 PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
3645 {
3646     PyCFuncPtrObject *self;
3647     int index;
3648     char *name = NULL;
3649     PyObject *paramflags = NULL;
3650     GUID *iid = NULL;
3651     Py_ssize_t iid_len = 0;
3652 
3653     if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
3654         return NULL;
3655     if (paramflags == Py_None)
3656         paramflags = NULL;
3657 
3658     if (!_validate_paramflags(type, paramflags))
3659         return NULL;
3660 
3661     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3662     self->index = index + 0x1000;
3663     Py_XINCREF(paramflags);
3664     self->paramflags = paramflags;
3665     if (iid_len == sizeof(GUID))
3666         self->iid = iid;
3667     return (PyObject *)self;
3668 }
3669 #endif
3670 
3671 /*
3672   PyCFuncPtr_new accepts different argument lists in addition to the standard
3673   _basespec_ keyword arg:
3674 
3675   one argument form
3676   "i" - function address
3677   "O" - must be a callable, creates a C callable function
3678 
3679   two or more argument forms (the third argument is a paramflags tuple)
3680   "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
3681   "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
3682   "is|..." - vtable index, method name, creates callable calling COM vtbl
3683 */
3684 static PyObject *
PyCFuncPtr_new(PyTypeObject * type,PyObject * args,PyObject * kwds)3685 PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3686 {
3687     PyCFuncPtrObject *self;
3688     PyObject *callable;
3689     StgDictObject *dict;
3690     CThunkObject *thunk;
3691 
3692     if (PyTuple_GET_SIZE(args) == 0)
3693         return GenericPyCData_new(type, args, kwds);
3694 
3695     if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
3696         return PyCFuncPtr_FromDll(type, args, kwds);
3697 
3698 #ifdef MS_WIN32
3699     if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0)))
3700         return PyCFuncPtr_FromVtblIndex(type, args, kwds);
3701 #endif
3702 
3703     if (1 == PyTuple_GET_SIZE(args)
3704         && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
3705         CDataObject *ob;
3706         void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
3707         if (ptr == NULL && PyErr_Occurred())
3708             return NULL;
3709         ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
3710         if (ob == NULL)
3711             return NULL;
3712         *(void **)ob->b_ptr = ptr;
3713         return (PyObject *)ob;
3714     }
3715 
3716     if (!PyArg_ParseTuple(args, "O", &callable))
3717         return NULL;
3718     if (!PyCallable_Check(callable)) {
3719         PyErr_SetString(PyExc_TypeError,
3720                         "argument must be callable or integer function address");
3721         return NULL;
3722     }
3723 
3724     /* XXX XXX This would allow passing additional options.  For COM
3725        method *implementations*, we would probably want different
3726        behaviour than in 'normal' callback functions: return a HRESULT if
3727        an exception occurs in the callback, and print the traceback not
3728        only on the console, but also to OutputDebugString() or something
3729        like that.
3730     */
3731 /*
3732     if (kwds && _PyDict_GetItemIdWithError(kwds, &PyId_options)) {
3733         ...
3734     }
3735     else if (PyErr_Occurred()) {
3736         return NULL;
3737     }
3738 */
3739 
3740     dict = PyType_stgdict((PyObject *)type);
3741     /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
3742     if (!dict || !dict->argtypes) {
3743         PyErr_SetString(PyExc_TypeError,
3744                "cannot construct instance of this class:"
3745             " no argtypes");
3746         return NULL;
3747     }
3748 
3749     thunk = _ctypes_alloc_callback(callable,
3750                                   dict->argtypes,
3751                                   dict->restype,
3752                                   dict->flags);
3753     if (!thunk)
3754         return NULL;
3755 
3756     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3757     if (self == NULL) {
3758         Py_DECREF(thunk);
3759         return NULL;
3760     }
3761 
3762     Py_INCREF(callable);
3763     self->callable = callable;
3764 
3765     self->thunk = thunk;
3766     *(void **)self->b_ptr = (void *)thunk->pcl_exec;
3767 
3768     Py_INCREF((PyObject *)thunk); /* for KeepRef */
3769     if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3770         Py_DECREF((PyObject *)self);
3771         return NULL;
3772     }
3773     return (PyObject *)self;
3774 }
3775 
3776 
3777 /*
3778   _byref consumes a refcount to its argument
3779 */
3780 static PyObject *
_byref(PyObject * obj)3781 _byref(PyObject *obj)
3782 {
3783     PyCArgObject *parg;
3784     if (!CDataObject_Check(obj)) {
3785         PyErr_SetString(PyExc_TypeError,
3786                         "expected CData instance");
3787         return NULL;
3788     }
3789 
3790     parg = PyCArgObject_new();
3791     if (parg == NULL) {
3792         Py_DECREF(obj);
3793         return NULL;
3794     }
3795 
3796     parg->tag = 'P';
3797     parg->pffi_type = &ffi_type_pointer;
3798     parg->obj = obj;
3799     parg->value.p = ((CDataObject *)obj)->b_ptr;
3800     return (PyObject *)parg;
3801 }
3802 
3803 static PyObject *
_get_arg(int * pindex,PyObject * name,PyObject * defval,PyObject * inargs,PyObject * kwds)3804 _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
3805 {
3806     PyObject *v;
3807 
3808     if (*pindex < PyTuple_GET_SIZE(inargs)) {
3809         v = PyTuple_GET_ITEM(inargs, *pindex);
3810         ++*pindex;
3811         Py_INCREF(v);
3812         return v;
3813     }
3814     if (kwds && name) {
3815         v = PyDict_GetItemWithError(kwds, name);
3816         if (v) {
3817             ++*pindex;
3818             Py_INCREF(v);
3819             return v;
3820         }
3821         else if (PyErr_Occurred()) {
3822             return NULL;
3823         }
3824     }
3825     if (defval) {
3826         Py_INCREF(defval);
3827         return defval;
3828     }
3829     /* we can't currently emit a better error message */
3830     if (name)
3831         PyErr_Format(PyExc_TypeError,
3832                      "required argument '%S' missing", name);
3833     else
3834         PyErr_Format(PyExc_TypeError,
3835                      "not enough arguments");
3836     return NULL;
3837 }
3838 
3839 /*
3840  This function implements higher level functionality plus the ability to call
3841  functions with keyword arguments by looking at parameter flags.  parameter
3842  flags is a tuple of 1, 2 or 3-tuples.  The first entry in each is an integer
3843  specifying the direction of the data transfer for this parameter - 'in',
3844  'out' or 'inout' (zero means the same as 'in').  The second entry is the
3845  parameter name, and the third is the default value if the parameter is
3846  missing in the function call.
3847 
3848  This function builds and returns a new tuple 'callargs' which contains the
3849  parameters to use in the call.  Items on this tuple are copied from the
3850  'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
3851  'argtypes' tuple for 'out' parameters.  It also calculates numretvals which
3852  is the number of return values for the function, outmask/inoutmask are
3853  bitmasks containing indexes into the callargs tuple specifying which
3854  parameters have to be returned.  _build_result builds the return value of the
3855  function.
3856 */
3857 static PyObject *
_build_callargs(PyCFuncPtrObject * self,PyObject * argtypes,PyObject * inargs,PyObject * kwds,int * poutmask,int * pinoutmask,unsigned int * pnumretvals)3858 _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
3859                 PyObject *inargs, PyObject *kwds,
3860                 int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
3861 {
3862     PyObject *paramflags = self->paramflags;
3863     PyObject *callargs;
3864     StgDictObject *dict;
3865     Py_ssize_t i, len;
3866     int inargs_index = 0;
3867     /* It's a little bit difficult to determine how many arguments the
3868     function call requires/accepts.  For simplicity, we count the consumed
3869     args and compare this to the number of supplied args. */
3870     Py_ssize_t actual_args;
3871 
3872     *poutmask = 0;
3873     *pinoutmask = 0;
3874     *pnumretvals = 0;
3875 
3876     /* Trivial cases, where we either return inargs itself, or a slice of it. */
3877     if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
3878 #ifdef MS_WIN32
3879         if (self->index)
3880             return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
3881 #endif
3882         Py_INCREF(inargs);
3883         return inargs;
3884     }
3885 
3886     len = PyTuple_GET_SIZE(argtypes);
3887     callargs = PyTuple_New(len); /* the argument tuple we build */
3888     if (callargs == NULL)
3889         return NULL;
3890 
3891 #ifdef MS_WIN32
3892     /* For a COM method, skip the first arg */
3893     if (self->index) {
3894         inargs_index = 1;
3895     }
3896 #endif
3897     for (i = 0; i < len; ++i) {
3898         PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3899         PyObject *ob;
3900         unsigned int flag;
3901         PyObject *name = NULL;
3902         PyObject *defval = NULL;
3903 
3904         /* This way seems to be ~2 us faster than the PyArg_ParseTuple
3905            calls below. */
3906         /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
3907         Py_ssize_t tsize = PyTuple_GET_SIZE(item);
3908         flag = PyLong_AsUnsignedLongMask(PyTuple_GET_ITEM(item, 0));
3909         name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
3910         defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
3911 
3912         switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3913         case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3914             /* ['in', 'lcid'] parameter.  Always taken from defval,
3915              if given, else the integer 0. */
3916             if (defval == NULL)
3917                 defval = _PyLong_Zero;
3918             Py_INCREF(defval);
3919             PyTuple_SET_ITEM(callargs, i, defval);
3920             break;
3921         case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
3922             *pinoutmask |= (1 << i); /* mark as inout arg */
3923             (*pnumretvals)++;
3924             /* fall through */
3925         case 0:
3926         case PARAMFLAG_FIN:
3927             /* 'in' parameter.  Copy it from inargs. */
3928             ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
3929             if (ob == NULL)
3930                 goto error;
3931             PyTuple_SET_ITEM(callargs, i, ob);
3932             break;
3933         case PARAMFLAG_FOUT:
3934             /* XXX Refactor this code into a separate function. */
3935             /* 'out' parameter.
3936                argtypes[i] must be a POINTER to a c type.
3937 
3938                Cannot by supplied in inargs, but a defval will be used
3939                if available.  XXX Should we support getting it from kwds?
3940             */
3941             if (defval) {
3942                 /* XXX Using mutable objects as defval will
3943                    make the function non-threadsafe, unless we
3944                    copy the object in each invocation */
3945                 Py_INCREF(defval);
3946                 PyTuple_SET_ITEM(callargs, i, defval);
3947                 *poutmask |= (1 << i); /* mark as out arg */
3948                 (*pnumretvals)++;
3949                 break;
3950             }
3951             ob = PyTuple_GET_ITEM(argtypes, i);
3952             dict = PyType_stgdict(ob);
3953             if (dict == NULL) {
3954                 /* Cannot happen: _validate_paramflags()
3955                   would not accept such an object */
3956                 PyErr_Format(PyExc_RuntimeError,
3957                              "NULL stgdict unexpected");
3958                 goto error;
3959             }
3960             if (PyUnicode_Check(dict->proto)) {
3961                 PyErr_Format(
3962                     PyExc_TypeError,
3963                     "%s 'out' parameter must be passed as default value",
3964                     ((PyTypeObject *)ob)->tp_name);
3965                 goto error;
3966             }
3967             if (PyCArrayTypeObject_Check(ob))
3968                 ob = _PyObject_CallNoArg(ob);
3969             else
3970                 /* Create an instance of the pointed-to type */
3971                 ob = _PyObject_CallNoArg(dict->proto);
3972             /*
3973                XXX Is the following correct any longer?
3974                We must not pass a byref() to the array then but
3975                the array instance itself. Then, we cannot retrieve
3976                the result from the PyCArgObject.
3977             */
3978             if (ob == NULL)
3979                 goto error;
3980             /* The .from_param call that will occur later will pass this
3981                as a byref parameter. */
3982             PyTuple_SET_ITEM(callargs, i, ob);
3983             *poutmask |= (1 << i); /* mark as out arg */
3984             (*pnumretvals)++;
3985             break;
3986         default:
3987             PyErr_Format(PyExc_ValueError,
3988                          "paramflag %u not yet implemented", flag);
3989             goto error;
3990             break;
3991         }
3992     }
3993 
3994     /* We have counted the arguments we have consumed in 'inargs_index'.  This
3995        must be the same as len(inargs) + len(kwds), otherwise we have
3996        either too much or not enough arguments. */
3997 
3998     actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_GET_SIZE(kwds) : 0);
3999     if (actual_args != inargs_index) {
4000         /* When we have default values or named parameters, this error
4001            message is misleading.  See unittests/test_paramflags.py
4002          */
4003         PyErr_Format(PyExc_TypeError,
4004                      "call takes exactly %d arguments (%zd given)",
4005                      inargs_index, actual_args);
4006         goto error;
4007     }
4008 
4009     /* outmask is a bitmask containing indexes into callargs.  Items at
4010        these indexes contain values to return.
4011      */
4012     return callargs;
4013   error:
4014     Py_DECREF(callargs);
4015     return NULL;
4016 }
4017 
4018 /* See also:
4019    http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
4020 */
4021 /*
4022   Build return value of a function.
4023 
4024   Consumes the refcount on result and callargs.
4025 */
4026 static PyObject *
_build_result(PyObject * result,PyObject * callargs,int outmask,int inoutmask,unsigned int numretvals)4027 _build_result(PyObject *result, PyObject *callargs,
4028               int outmask, int inoutmask, unsigned int numretvals)
4029 {
4030     unsigned int i, index;
4031     int bit;
4032     PyObject *tup = NULL;
4033 
4034     if (callargs == NULL)
4035         return result;
4036     if (result == NULL || numretvals == 0) {
4037         Py_DECREF(callargs);
4038         return result;
4039     }
4040     Py_DECREF(result);
4041 
4042     /* tup will not be allocated if numretvals == 1 */
4043     /* allocate tuple to hold the result */
4044     if (numretvals > 1) {
4045         tup = PyTuple_New(numretvals);
4046         if (tup == NULL) {
4047             Py_DECREF(callargs);
4048             return NULL;
4049         }
4050     }
4051 
4052     index = 0;
4053     for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
4054         PyObject *v;
4055         if (bit & inoutmask) {
4056             v = PyTuple_GET_ITEM(callargs, i);
4057             Py_INCREF(v);
4058             if (numretvals == 1) {
4059                 Py_DECREF(callargs);
4060                 return v;
4061             }
4062             PyTuple_SET_ITEM(tup, index, v);
4063             index++;
4064         } else if (bit & outmask) {
4065             _Py_IDENTIFIER(__ctypes_from_outparam__);
4066 
4067             v = PyTuple_GET_ITEM(callargs, i);
4068             v = _PyObject_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL);
4069             if (v == NULL || numretvals == 1) {
4070                 Py_DECREF(callargs);
4071                 return v;
4072             }
4073             PyTuple_SET_ITEM(tup, index, v);
4074             index++;
4075         }
4076         if (index == numretvals)
4077             break;
4078     }
4079 
4080     Py_DECREF(callargs);
4081     return tup;
4082 }
4083 
4084 static PyObject *
PyCFuncPtr_call(PyCFuncPtrObject * self,PyObject * inargs,PyObject * kwds)4085 PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
4086 {
4087     PyObject *restype;
4088     PyObject *converters;
4089     PyObject *checker;
4090     PyObject *argtypes;
4091     StgDictObject *dict = PyObject_stgdict((PyObject *)self);
4092     PyObject *result;
4093     PyObject *callargs;
4094     PyObject *errcheck;
4095 #ifdef MS_WIN32
4096     IUnknown *piunk = NULL;
4097 #endif
4098     void *pProc = NULL;
4099 
4100     int inoutmask;
4101     int outmask;
4102     unsigned int numretvals;
4103 
4104     assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
4105     restype = self->restype ? self->restype : dict->restype;
4106     converters = self->converters ? self->converters : dict->converters;
4107     checker = self->checker ? self->checker : dict->checker;
4108     argtypes = self->argtypes ? self->argtypes : dict->argtypes;
4109 /* later, we probably want to have an errcheck field in stgdict */
4110     errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
4111 
4112 
4113     pProc = *(void **)self->b_ptr;
4114 #ifdef MS_WIN32
4115     if (self->index) {
4116         /* It's a COM method */
4117         CDataObject *this;
4118         this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
4119         if (!this) {
4120             PyErr_SetString(PyExc_ValueError,
4121                             "native com method call without 'this' parameter");
4122             return NULL;
4123         }
4124         if (!CDataObject_Check(this)) {
4125             PyErr_SetString(PyExc_TypeError,
4126                             "Expected a COM this pointer as first argument");
4127             return NULL;
4128         }
4129         /* there should be more checks? No, in Python */
4130         /* First arg is a pointer to an interface instance */
4131         if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
4132             PyErr_SetString(PyExc_ValueError,
4133                             "NULL COM pointer access");
4134             return NULL;
4135         }
4136         piunk = *(IUnknown **)this->b_ptr;
4137         if (NULL == piunk->lpVtbl) {
4138             PyErr_SetString(PyExc_ValueError,
4139                             "COM method call without VTable");
4140             return NULL;
4141         }
4142         pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
4143     }
4144 #endif
4145     callargs = _build_callargs(self, argtypes,
4146                                inargs, kwds,
4147                                &outmask, &inoutmask, &numretvals);
4148     if (callargs == NULL)
4149         return NULL;
4150 
4151     if (converters) {
4152         int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
4153                                         Py_ssize_t, int);
4154         int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
4155                                       Py_ssize_t, int);
4156 
4157         if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
4158             /* For cdecl functions, we allow more actual arguments
4159                than the length of the argtypes tuple.
4160             */
4161             if (required > actual) {
4162                 Py_DECREF(callargs);
4163                 PyErr_Format(PyExc_TypeError,
4164               "this function takes at least %d argument%s (%d given)",
4165                                  required,
4166                                  required == 1 ? "" : "s",
4167                                  actual);
4168                 return NULL;
4169             }
4170         } else if (required != actual) {
4171             Py_DECREF(callargs);
4172             PyErr_Format(PyExc_TypeError,
4173                  "this function takes %d argument%s (%d given)",
4174                      required,
4175                      required == 1 ? "" : "s",
4176                      actual);
4177             return NULL;
4178         }
4179     }
4180 
4181     result = _ctypes_callproc(pProc,
4182                        callargs,
4183 #ifdef MS_WIN32
4184                        piunk,
4185                        self->iid,
4186 #endif
4187                        dict->flags,
4188                        converters,
4189                        restype,
4190                        checker);
4191 /* The 'errcheck' protocol */
4192     if (result != NULL && errcheck) {
4193         PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
4194                                                    result,
4195                                                    self,
4196                                                    callargs,
4197                                                    NULL);
4198         /* If the errcheck function failed, return NULL.
4199            If the errcheck function returned callargs unchanged,
4200            continue normal processing.
4201            If the errcheck function returned something else,
4202            use that as result.
4203         */
4204         if (v == NULL || v != callargs) {
4205             Py_DECREF(result);
4206             Py_DECREF(callargs);
4207             return v;
4208         }
4209         Py_DECREF(v);
4210     }
4211 
4212     return _build_result(result, callargs,
4213                          outmask, inoutmask, numretvals);
4214 }
4215 
4216 static int
PyCFuncPtr_traverse(PyCFuncPtrObject * self,visitproc visit,void * arg)4217 PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
4218 {
4219     Py_VISIT(self->callable);
4220     Py_VISIT(self->restype);
4221     Py_VISIT(self->checker);
4222     Py_VISIT(self->errcheck);
4223     Py_VISIT(self->argtypes);
4224     Py_VISIT(self->converters);
4225     Py_VISIT(self->paramflags);
4226     Py_VISIT(self->thunk);
4227     return PyCData_traverse((CDataObject *)self, visit, arg);
4228 }
4229 
4230 static int
PyCFuncPtr_clear(PyCFuncPtrObject * self)4231 PyCFuncPtr_clear(PyCFuncPtrObject *self)
4232 {
4233     Py_CLEAR(self->callable);
4234     Py_CLEAR(self->restype);
4235     Py_CLEAR(self->checker);
4236     Py_CLEAR(self->errcheck);
4237     Py_CLEAR(self->argtypes);
4238     Py_CLEAR(self->converters);
4239     Py_CLEAR(self->paramflags);
4240     Py_CLEAR(self->thunk);
4241     return PyCData_clear((CDataObject *)self);
4242 }
4243 
4244 static void
PyCFuncPtr_dealloc(PyCFuncPtrObject * self)4245 PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
4246 {
4247     PyCFuncPtr_clear(self);
4248     Py_TYPE(self)->tp_free((PyObject *)self);
4249 }
4250 
4251 static PyObject *
PyCFuncPtr_repr(PyCFuncPtrObject * self)4252 PyCFuncPtr_repr(PyCFuncPtrObject *self)
4253 {
4254 #ifdef MS_WIN32
4255     if (self->index)
4256         return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
4257                                    self->index - 0x1000,
4258                                    Py_TYPE(self)->tp_name,
4259                                    self);
4260 #endif
4261     return PyUnicode_FromFormat("<%s object at %p>",
4262                                Py_TYPE(self)->tp_name,
4263                                self);
4264 }
4265 
4266 static int
PyCFuncPtr_bool(PyCFuncPtrObject * self)4267 PyCFuncPtr_bool(PyCFuncPtrObject *self)
4268 {
4269     return ((*(void **)self->b_ptr != NULL)
4270 #ifdef MS_WIN32
4271         || (self->index != 0)
4272 #endif
4273         );
4274 }
4275 
4276 static PyNumberMethods PyCFuncPtr_as_number = {
4277     0, /* nb_add */
4278     0, /* nb_subtract */
4279     0, /* nb_multiply */
4280     0, /* nb_remainder */
4281     0, /* nb_divmod */
4282     0, /* nb_power */
4283     0, /* nb_negative */
4284     0, /* nb_positive */
4285     0, /* nb_absolute */
4286     (inquiry)PyCFuncPtr_bool, /* nb_bool */
4287 };
4288 
4289 PyTypeObject PyCFuncPtr_Type = {
4290     PyVarObject_HEAD_INIT(NULL, 0)
4291     "_ctypes.PyCFuncPtr",
4292     sizeof(PyCFuncPtrObject),                           /* tp_basicsize */
4293     0,                                          /* tp_itemsize */
4294     (destructor)PyCFuncPtr_dealloc,             /* tp_dealloc */
4295     0,                                          /* tp_vectorcall_offset */
4296     0,                                          /* tp_getattr */
4297     0,                                          /* tp_setattr */
4298     0,                                          /* tp_as_async */
4299     (reprfunc)PyCFuncPtr_repr,                  /* tp_repr */
4300     &PyCFuncPtr_as_number,                      /* tp_as_number */
4301     0,                                          /* tp_as_sequence */
4302     0,                                          /* tp_as_mapping */
4303     0,                                          /* tp_hash */
4304     (ternaryfunc)PyCFuncPtr_call,               /* tp_call */
4305     0,                                          /* tp_str */
4306     0,                                          /* tp_getattro */
4307     0,                                          /* tp_setattro */
4308     &PyCData_as_buffer,                         /* tp_as_buffer */
4309     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4310     "Function Pointer",                         /* tp_doc */
4311     (traverseproc)PyCFuncPtr_traverse,          /* tp_traverse */
4312     (inquiry)PyCFuncPtr_clear,                  /* tp_clear */
4313     0,                                          /* tp_richcompare */
4314     0,                                          /* tp_weaklistoffset */
4315     0,                                          /* tp_iter */
4316     0,                                          /* tp_iternext */
4317     0,                                          /* tp_methods */
4318     0,                                          /* tp_members */
4319     PyCFuncPtr_getsets,                         /* tp_getset */
4320     0,                                          /* tp_base */
4321     0,                                          /* tp_dict */
4322     0,                                          /* tp_descr_get */
4323     0,                                          /* tp_descr_set */
4324     0,                                          /* tp_dictoffset */
4325     0,                                          /* tp_init */
4326     0,                                          /* tp_alloc */
4327     PyCFuncPtr_new,                             /* tp_new */
4328     0,                                          /* tp_free */
4329 };
4330 
4331 /*****************************************************************/
4332 /*
4333   Struct_Type
4334 */
4335 /*
4336   This function is called to initialize a Structure or Union with positional
4337   arguments. It calls itself recursively for all Structure or Union base
4338   classes, then retrieves the _fields_ member to associate the argument
4339   position with the correct field name.
4340 
4341   Returns -1 on error, or the index of next argument on success.
4342  */
4343 static Py_ssize_t
_init_pos_args(PyObject * self,PyTypeObject * type,PyObject * args,PyObject * kwds,Py_ssize_t index)4344 _init_pos_args(PyObject *self, PyTypeObject *type,
4345                PyObject *args, PyObject *kwds,
4346                Py_ssize_t index)
4347 {
4348     StgDictObject *dict;
4349     PyObject *fields;
4350     Py_ssize_t i;
4351     _Py_IDENTIFIER(_fields_);
4352 
4353     if (PyType_stgdict((PyObject *)type->tp_base)) {
4354         index = _init_pos_args(self, type->tp_base,
4355                                args, kwds,
4356                                index);
4357         if (index == -1)
4358             return -1;
4359     }
4360 
4361     dict = PyType_stgdict((PyObject *)type);
4362     fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_);
4363     if (fields == NULL) {
4364         if (PyErr_Occurred()) {
4365             return -1;
4366         }
4367         return index;
4368     }
4369 
4370     for (i = 0;
4371          i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
4372          ++i) {
4373         PyObject *pair = PySequence_GetItem(fields, i);
4374         PyObject *name, *val;
4375         int res;
4376         if (!pair)
4377             return -1;
4378         name = PySequence_GetItem(pair, 0);
4379         if (!name) {
4380             Py_DECREF(pair);
4381             return -1;
4382         }
4383         val = PyTuple_GET_ITEM(args, i + index);
4384         if (kwds) {
4385             if (PyDict_GetItemWithError(kwds, name)) {
4386                 PyErr_Format(PyExc_TypeError,
4387                             "duplicate values for field %R",
4388                             name);
4389                 Py_DECREF(pair);
4390                 Py_DECREF(name);
4391                 return -1;
4392             }
4393             else if (PyErr_Occurred()) {
4394                 Py_DECREF(pair);
4395                 Py_DECREF(name);
4396                 return -1;
4397             }
4398         }
4399 
4400         res = PyObject_SetAttr(self, name, val);
4401         Py_DECREF(pair);
4402         Py_DECREF(name);
4403         if (res == -1)
4404             return -1;
4405     }
4406     return index + dict->length;
4407 }
4408 
4409 static int
Struct_init(PyObject * self,PyObject * args,PyObject * kwds)4410 Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
4411 {
4412 /* Optimization possible: Store the attribute names _fields_[x][0]
4413  * in C accessible fields somewhere ?
4414  */
4415     if (!PyTuple_Check(args)) {
4416         PyErr_SetString(PyExc_TypeError,
4417                         "args not a tuple?");
4418         return -1;
4419     }
4420     if (PyTuple_GET_SIZE(args)) {
4421         Py_ssize_t res = _init_pos_args(self, Py_TYPE(self),
4422                                         args, kwds, 0);
4423         if (res == -1)
4424             return -1;
4425         if (res < PyTuple_GET_SIZE(args)) {
4426             PyErr_SetString(PyExc_TypeError,
4427                             "too many initializers");
4428             return -1;
4429         }
4430     }
4431 
4432     if (kwds) {
4433         PyObject *key, *value;
4434         Py_ssize_t pos = 0;
4435         while(PyDict_Next(kwds, &pos, &key, &value)) {
4436             if (-1 == PyObject_SetAttr(self, key, value))
4437                 return -1;
4438         }
4439     }
4440     return 0;
4441 }
4442 
4443 static PyTypeObject Struct_Type = {
4444     PyVarObject_HEAD_INIT(NULL, 0)
4445     "_ctypes.Structure",
4446     sizeof(CDataObject),                        /* tp_basicsize */
4447     0,                                          /* tp_itemsize */
4448     0,                                          /* tp_dealloc */
4449     0,                                          /* tp_vectorcall_offset */
4450     0,                                          /* tp_getattr */
4451     0,                                          /* tp_setattr */
4452     0,                                          /* tp_as_async */
4453     0,                                          /* tp_repr */
4454     0,                                          /* tp_as_number */
4455     0,                                          /* tp_as_sequence */
4456     0,                                          /* tp_as_mapping */
4457     0,                                          /* tp_hash */
4458     0,                                          /* tp_call */
4459     0,                                          /* tp_str */
4460     0,                                          /* tp_getattro */
4461     0,                                          /* tp_setattro */
4462     &PyCData_as_buffer,                         /* tp_as_buffer */
4463     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4464     "Structure base class",                     /* tp_doc */
4465     (traverseproc)PyCData_traverse,             /* tp_traverse */
4466     (inquiry)PyCData_clear,                     /* tp_clear */
4467     0,                                          /* tp_richcompare */
4468     0,                                          /* tp_weaklistoffset */
4469     0,                                          /* tp_iter */
4470     0,                                          /* tp_iternext */
4471     0,                                          /* tp_methods */
4472     0,                                          /* tp_members */
4473     0,                                          /* tp_getset */
4474     0,                                          /* tp_base */
4475     0,                                          /* tp_dict */
4476     0,                                          /* tp_descr_get */
4477     0,                                          /* tp_descr_set */
4478     0,                                          /* tp_dictoffset */
4479     Struct_init,                                /* tp_init */
4480     0,                                          /* tp_alloc */
4481     GenericPyCData_new,                         /* tp_new */
4482     0,                                          /* tp_free */
4483 };
4484 
4485 static PyTypeObject Union_Type = {
4486     PyVarObject_HEAD_INIT(NULL, 0)
4487     "_ctypes.Union",
4488     sizeof(CDataObject),                        /* tp_basicsize */
4489     0,                                          /* tp_itemsize */
4490     0,                                          /* tp_dealloc */
4491     0,                                          /* tp_vectorcall_offset */
4492     0,                                          /* tp_getattr */
4493     0,                                          /* tp_setattr */
4494     0,                                          /* tp_as_async */
4495     0,                                          /* tp_repr */
4496     0,                                          /* tp_as_number */
4497     0,                                          /* tp_as_sequence */
4498     0,                                          /* tp_as_mapping */
4499     0,                                          /* tp_hash */
4500     0,                                          /* tp_call */
4501     0,                                          /* tp_str */
4502     0,                                          /* tp_getattro */
4503     0,                                          /* tp_setattro */
4504     &PyCData_as_buffer,                         /* tp_as_buffer */
4505     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4506     "Union base class",                         /* tp_doc */
4507     (traverseproc)PyCData_traverse,             /* tp_traverse */
4508     (inquiry)PyCData_clear,                     /* tp_clear */
4509     0,                                          /* tp_richcompare */
4510     0,                                          /* tp_weaklistoffset */
4511     0,                                          /* tp_iter */
4512     0,                                          /* tp_iternext */
4513     0,                                          /* tp_methods */
4514     0,                                          /* tp_members */
4515     0,                                          /* tp_getset */
4516     0,                                          /* tp_base */
4517     0,                                          /* tp_dict */
4518     0,                                          /* tp_descr_get */
4519     0,                                          /* tp_descr_set */
4520     0,                                          /* tp_dictoffset */
4521     Struct_init,                                /* tp_init */
4522     0,                                          /* tp_alloc */
4523     GenericPyCData_new,                         /* tp_new */
4524     0,                                          /* tp_free */
4525 };
4526 
4527 
4528 /******************************************************************/
4529 /*
4530   PyCArray_Type
4531 */
4532 static int
Array_init(CDataObject * self,PyObject * args,PyObject * kw)4533 Array_init(CDataObject *self, PyObject *args, PyObject *kw)
4534 {
4535     Py_ssize_t i;
4536     Py_ssize_t n;
4537 
4538     if (!PyTuple_Check(args)) {
4539         PyErr_SetString(PyExc_TypeError,
4540                         "args not a tuple?");
4541         return -1;
4542     }
4543     n = PyTuple_GET_SIZE(args);
4544     for (i = 0; i < n; ++i) {
4545         PyObject *v;
4546         v = PyTuple_GET_ITEM(args, i);
4547         if (-1 == PySequence_SetItem((PyObject *)self, i, v))
4548             return -1;
4549     }
4550     return 0;
4551 }
4552 
4553 static PyObject *
Array_item(PyObject * myself,Py_ssize_t index)4554 Array_item(PyObject *myself, Py_ssize_t index)
4555 {
4556     CDataObject *self = (CDataObject *)myself;
4557     Py_ssize_t offset, size;
4558     StgDictObject *stgdict;
4559 
4560 
4561     if (index < 0 || index >= self->b_length) {
4562         PyErr_SetString(PyExc_IndexError,
4563                         "invalid index");
4564         return NULL;
4565     }
4566 
4567     stgdict = PyObject_stgdict((PyObject *)self);
4568     assert(stgdict); /* Cannot be NULL for array instances */
4569     /* Would it be clearer if we got the item size from
4570        stgdict->proto's stgdict?
4571     */
4572     size = stgdict->size / stgdict->length;
4573     offset = index * size;
4574 
4575     return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
4576                      index, size, self->b_ptr + offset);
4577 }
4578 
4579 static PyObject *
Array_subscript(PyObject * myself,PyObject * item)4580 Array_subscript(PyObject *myself, PyObject *item)
4581 {
4582     CDataObject *self = (CDataObject *)myself;
4583 
4584     if (PyIndex_Check(item)) {
4585         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4586 
4587         if (i == -1 && PyErr_Occurred())
4588             return NULL;
4589         if (i < 0)
4590             i += self->b_length;
4591         return Array_item(myself, i);
4592     }
4593     else if (PySlice_Check(item)) {
4594         StgDictObject *stgdict, *itemdict;
4595         PyObject *proto;
4596         PyObject *np;
4597         Py_ssize_t start, stop, step, slicelen, i;
4598         size_t cur;
4599 
4600         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
4601             return NULL;
4602         }
4603         slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step);
4604 
4605         stgdict = PyObject_stgdict((PyObject *)self);
4606         assert(stgdict); /* Cannot be NULL for array object instances */
4607         proto = stgdict->proto;
4608         itemdict = PyType_stgdict(proto);
4609         assert(itemdict); /* proto is the item type of the array, a
4610                              ctypes type, so this cannot be NULL */
4611 
4612         if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4613             char *ptr = (char *)self->b_ptr;
4614             char *dest;
4615 
4616             if (slicelen <= 0)
4617                 return PyBytes_FromStringAndSize("", 0);
4618             if (step == 1) {
4619                 return PyBytes_FromStringAndSize(ptr + start,
4620                                                  slicelen);
4621             }
4622             dest = (char *)PyMem_Malloc(slicelen);
4623 
4624             if (dest == NULL)
4625                 return PyErr_NoMemory();
4626 
4627             for (cur = start, i = 0; i < slicelen;
4628                  cur += step, i++) {
4629                 dest[i] = ptr[cur];
4630             }
4631 
4632             np = PyBytes_FromStringAndSize(dest, slicelen);
4633             PyMem_Free(dest);
4634             return np;
4635         }
4636 #ifdef CTYPES_UNICODE
4637         if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4638             wchar_t *ptr = (wchar_t *)self->b_ptr;
4639             wchar_t *dest;
4640 
4641             if (slicelen <= 0)
4642                 return PyUnicode_New(0, 0);
4643             if (step == 1) {
4644                 return PyUnicode_FromWideChar(ptr + start,
4645                                               slicelen);
4646             }
4647 
4648             dest = PyMem_New(wchar_t, slicelen);
4649             if (dest == NULL) {
4650                 PyErr_NoMemory();
4651                 return NULL;
4652             }
4653 
4654             for (cur = start, i = 0; i < slicelen;
4655                  cur += step, i++) {
4656                 dest[i] = ptr[cur];
4657             }
4658 
4659             np = PyUnicode_FromWideChar(dest, slicelen);
4660             PyMem_Free(dest);
4661             return np;
4662         }
4663 #endif
4664 
4665         np = PyList_New(slicelen);
4666         if (np == NULL)
4667             return NULL;
4668 
4669         for (cur = start, i = 0; i < slicelen;
4670              cur += step, i++) {
4671             PyObject *v = Array_item(myself, cur);
4672             if (v == NULL) {
4673                 Py_DECREF(np);
4674                 return NULL;
4675             }
4676             PyList_SET_ITEM(np, i, v);
4677         }
4678         return np;
4679     }
4680     else {
4681         PyErr_SetString(PyExc_TypeError,
4682                         "indices must be integers");
4683         return NULL;
4684     }
4685 
4686 }
4687 
4688 static int
Array_ass_item(PyObject * myself,Py_ssize_t index,PyObject * value)4689 Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
4690 {
4691     CDataObject *self = (CDataObject *)myself;
4692     Py_ssize_t size, offset;
4693     StgDictObject *stgdict;
4694     char *ptr;
4695 
4696     if (value == NULL) {
4697         PyErr_SetString(PyExc_TypeError,
4698                         "Array does not support item deletion");
4699         return -1;
4700     }
4701 
4702     stgdict = PyObject_stgdict((PyObject *)self);
4703     assert(stgdict); /* Cannot be NULL for array object instances */
4704     if (index < 0 || index >= stgdict->length) {
4705         PyErr_SetString(PyExc_IndexError,
4706                         "invalid index");
4707         return -1;
4708     }
4709     size = stgdict->size / stgdict->length;
4710     offset = index * size;
4711     ptr = self->b_ptr + offset;
4712 
4713     return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
4714                      index, size, ptr);
4715 }
4716 
4717 static int
Array_ass_subscript(PyObject * myself,PyObject * item,PyObject * value)4718 Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value)
4719 {
4720     CDataObject *self = (CDataObject *)myself;
4721 
4722     if (value == NULL) {
4723         PyErr_SetString(PyExc_TypeError,
4724                         "Array does not support item deletion");
4725         return -1;
4726     }
4727 
4728     if (PyIndex_Check(item)) {
4729         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4730 
4731         if (i == -1 && PyErr_Occurred())
4732             return -1;
4733         if (i < 0)
4734             i += self->b_length;
4735         return Array_ass_item(myself, i, value);
4736     }
4737     else if (PySlice_Check(item)) {
4738         Py_ssize_t start, stop, step, slicelen, otherlen, i;
4739         size_t cur;
4740 
4741         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
4742             return -1;
4743         }
4744         slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step);
4745         if ((step < 0 && start < stop) ||
4746             (step > 0 && start > stop))
4747             stop = start;
4748 
4749         otherlen = PySequence_Length(value);
4750         if (otherlen != slicelen) {
4751             PyErr_SetString(PyExc_ValueError,
4752                 "Can only assign sequence of same size");
4753             return -1;
4754         }
4755         for (cur = start, i = 0; i < otherlen; cur += step, i++) {
4756             PyObject *item = PySequence_GetItem(value, i);
4757             int result;
4758             if (item == NULL)
4759                 return -1;
4760             result = Array_ass_item(myself, cur, item);
4761             Py_DECREF(item);
4762             if (result == -1)
4763                 return -1;
4764         }
4765         return 0;
4766     }
4767     else {
4768         PyErr_SetString(PyExc_TypeError,
4769                         "indices must be integer");
4770         return -1;
4771     }
4772 }
4773 
4774 static Py_ssize_t
Array_length(PyObject * myself)4775 Array_length(PyObject *myself)
4776 {
4777     CDataObject *self = (CDataObject *)myself;
4778     return self->b_length;
4779 }
4780 
4781 static PySequenceMethods Array_as_sequence = {
4782     Array_length,                               /* sq_length; */
4783     0,                                          /* sq_concat; */
4784     0,                                          /* sq_repeat; */
4785     Array_item,                                 /* sq_item; */
4786     0,                                          /* sq_slice; */
4787     Array_ass_item,                             /* sq_ass_item; */
4788     0,                                          /* sq_ass_slice; */
4789     0,                                          /* sq_contains; */
4790 
4791     0,                                          /* sq_inplace_concat; */
4792     0,                                          /* sq_inplace_repeat; */
4793 };
4794 
4795 static PyMappingMethods Array_as_mapping = {
4796     Array_length,
4797     Array_subscript,
4798     Array_ass_subscript,
4799 };
4800 
4801 PyTypeObject PyCArray_Type = {
4802     PyVarObject_HEAD_INIT(NULL, 0)
4803     "_ctypes.Array",
4804     sizeof(CDataObject),                        /* tp_basicsize */
4805     0,                                          /* tp_itemsize */
4806     0,                                          /* tp_dealloc */
4807     0,                                          /* tp_vectorcall_offset */
4808     0,                                          /* tp_getattr */
4809     0,                                          /* tp_setattr */
4810     0,                                          /* tp_as_async */
4811     0,                                          /* tp_repr */
4812     0,                                          /* tp_as_number */
4813     &Array_as_sequence,                         /* tp_as_sequence */
4814     &Array_as_mapping,                          /* tp_as_mapping */
4815     0,                                          /* tp_hash */
4816     0,                                          /* tp_call */
4817     0,                                          /* tp_str */
4818     0,                                          /* tp_getattro */
4819     0,                                          /* tp_setattro */
4820     &PyCData_as_buffer,                         /* tp_as_buffer */
4821     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4822     "XXX to be provided",                       /* tp_doc */
4823     (traverseproc)PyCData_traverse,             /* tp_traverse */
4824     (inquiry)PyCData_clear,                     /* tp_clear */
4825     0,                                          /* tp_richcompare */
4826     0,                                          /* tp_weaklistoffset */
4827     0,                                          /* tp_iter */
4828     0,                                          /* tp_iternext */
4829     0,                                          /* tp_methods */
4830     0,                                          /* tp_members */
4831     0,                                          /* tp_getset */
4832     0,                                          /* tp_base */
4833     0,                                          /* tp_dict */
4834     0,                                          /* tp_descr_get */
4835     0,                                          /* tp_descr_set */
4836     0,                                          /* tp_dictoffset */
4837     (initproc)Array_init,                       /* tp_init */
4838     0,                                          /* tp_alloc */
4839     GenericPyCData_new,                         /* tp_new */
4840     0,                                          /* tp_free */
4841 };
4842 
4843 PyObject *
PyCArrayType_from_ctype(PyObject * itemtype,Py_ssize_t length)4844 PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
4845 {
4846     static PyObject *cache;
4847     PyObject *key;
4848     PyObject *result;
4849     char name[256];
4850     PyObject *len;
4851 
4852     if (cache == NULL) {
4853         cache = PyDict_New();
4854         if (cache == NULL)
4855             return NULL;
4856     }
4857     len = PyLong_FromSsize_t(length);
4858     if (len == NULL)
4859         return NULL;
4860     key = PyTuple_Pack(2, itemtype, len);
4861     Py_DECREF(len);
4862     if (!key)
4863         return NULL;
4864     result = PyDict_GetItemProxy(cache, key);
4865     if (result) {
4866         Py_INCREF(result);
4867         Py_DECREF(key);
4868         return result;
4869     }
4870     else if (PyErr_Occurred()) {
4871         Py_DECREF(key);
4872         return NULL;
4873     }
4874 
4875     if (!PyType_Check(itemtype)) {
4876         PyErr_SetString(PyExc_TypeError,
4877                         "Expected a type object");
4878         Py_DECREF(key);
4879         return NULL;
4880     }
4881 #ifdef MS_WIN64
4882     sprintf(name, "%.200s_Array_%Id",
4883         ((PyTypeObject *)itemtype)->tp_name, length);
4884 #else
4885     sprintf(name, "%.200s_Array_%ld",
4886         ((PyTypeObject *)itemtype)->tp_name, (long)length);
4887 #endif
4888 
4889     result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type,
4890                                    "s(O){s:n,s:O}",
4891                                    name,
4892                                    &PyCArray_Type,
4893                                    "_length_",
4894                                    length,
4895                                    "_type_",
4896                                    itemtype
4897         );
4898     if (result == NULL) {
4899         Py_DECREF(key);
4900         return NULL;
4901     }
4902     if (-1 == PyDict_SetItemProxy(cache, key, result)) {
4903         Py_DECREF(key);
4904         Py_DECREF(result);
4905         return NULL;
4906     }
4907     Py_DECREF(key);
4908     return result;
4909 }
4910 
4911 
4912 /******************************************************************/
4913 /*
4914   Simple_Type
4915 */
4916 
4917 static int
Simple_set_value(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))4918 Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
4919 {
4920     PyObject *result;
4921     StgDictObject *dict = PyObject_stgdict((PyObject *)self);
4922 
4923     if (value == NULL) {
4924         PyErr_SetString(PyExc_TypeError,
4925                         "can't delete attribute");
4926         return -1;
4927     }
4928     assert(dict); /* Cannot be NULL for CDataObject instances */
4929     assert(dict->setfunc);
4930     result = dict->setfunc(self->b_ptr, value, dict->size);
4931     if (!result)
4932         return -1;
4933 
4934     /* consumes the refcount the setfunc returns */
4935     return KeepRef(self, 0, result);
4936 }
4937 
4938 static int
Simple_init(CDataObject * self,PyObject * args,PyObject * kw)4939 Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
4940 {
4941     PyObject *value = NULL;
4942     if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
4943         return -1;
4944     if (value)
4945         return Simple_set_value(self, value, NULL);
4946     return 0;
4947 }
4948 
4949 static PyObject *
Simple_get_value(CDataObject * self,void * Py_UNUSED (ignored))4950 Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored))
4951 {
4952     StgDictObject *dict;
4953     dict = PyObject_stgdict((PyObject *)self);
4954     assert(dict); /* Cannot be NULL for CDataObject instances */
4955     assert(dict->getfunc);
4956     return dict->getfunc(self->b_ptr, self->b_size);
4957 }
4958 
4959 static PyGetSetDef Simple_getsets[] = {
4960     { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4961       "current value", NULL },
4962     { NULL, NULL }
4963 };
4964 
4965 static PyObject *
Simple_from_outparm(PyObject * self,PyObject * args)4966 Simple_from_outparm(PyObject *self, PyObject *args)
4967 {
4968     if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) {
4969         Py_INCREF(self);
4970         return self;
4971     }
4972     /* call stgdict->getfunc */
4973     return Simple_get_value((CDataObject *)self, NULL);
4974 }
4975 
4976 static PyMethodDef Simple_methods[] = {
4977     { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
4978     { NULL, NULL },
4979 };
4980 
Simple_bool(CDataObject * self)4981 static int Simple_bool(CDataObject *self)
4982 {
4983     return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
4984 }
4985 
4986 static PyNumberMethods Simple_as_number = {
4987     0, /* nb_add */
4988     0, /* nb_subtract */
4989     0, /* nb_multiply */
4990     0, /* nb_remainder */
4991     0, /* nb_divmod */
4992     0, /* nb_power */
4993     0, /* nb_negative */
4994     0, /* nb_positive */
4995     0, /* nb_absolute */
4996     (inquiry)Simple_bool, /* nb_bool */
4997 };
4998 
4999 /* "%s(%s)" % (self.__class__.__name__, self.value) */
5000 static PyObject *
Simple_repr(CDataObject * self)5001 Simple_repr(CDataObject *self)
5002 {
5003     PyObject *val, *result;
5004 
5005     if (Py_TYPE(self)->tp_base != &Simple_Type) {
5006         return PyUnicode_FromFormat("<%s object at %p>",
5007                                    Py_TYPE(self)->tp_name, self);
5008     }
5009 
5010     val = Simple_get_value(self, NULL);
5011     if (val == NULL)
5012         return NULL;
5013 
5014     result = PyUnicode_FromFormat("%s(%R)",
5015                                   Py_TYPE(self)->tp_name, val);
5016     Py_DECREF(val);
5017     return result;
5018 }
5019 
5020 static PyTypeObject Simple_Type = {
5021     PyVarObject_HEAD_INIT(NULL, 0)
5022     "_ctypes._SimpleCData",
5023     sizeof(CDataObject),                        /* tp_basicsize */
5024     0,                                          /* tp_itemsize */
5025     0,                                          /* tp_dealloc */
5026     0,                                          /* tp_vectorcall_offset */
5027     0,                                          /* tp_getattr */
5028     0,                                          /* tp_setattr */
5029     0,                                          /* tp_as_async */
5030     (reprfunc)&Simple_repr,                     /* tp_repr */
5031     &Simple_as_number,                          /* tp_as_number */
5032     0,                                          /* tp_as_sequence */
5033     0,                                          /* tp_as_mapping */
5034     0,                                          /* tp_hash */
5035     0,                                          /* tp_call */
5036     0,                                          /* tp_str */
5037     0,                                          /* tp_getattro */
5038     0,                                          /* tp_setattro */
5039     &PyCData_as_buffer,                         /* tp_as_buffer */
5040     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5041     "XXX to be provided",                       /* tp_doc */
5042     (traverseproc)PyCData_traverse,             /* tp_traverse */
5043     (inquiry)PyCData_clear,                     /* tp_clear */
5044     0,                                          /* tp_richcompare */
5045     0,                                          /* tp_weaklistoffset */
5046     0,                                          /* tp_iter */
5047     0,                                          /* tp_iternext */
5048     Simple_methods,                             /* tp_methods */
5049     0,                                          /* tp_members */
5050     Simple_getsets,                             /* tp_getset */
5051     0,                                          /* tp_base */
5052     0,                                          /* tp_dict */
5053     0,                                          /* tp_descr_get */
5054     0,                                          /* tp_descr_set */
5055     0,                                          /* tp_dictoffset */
5056     (initproc)Simple_init,                      /* tp_init */
5057     0,                                          /* tp_alloc */
5058     GenericPyCData_new,                         /* tp_new */
5059     0,                                          /* tp_free */
5060 };
5061 
5062 /******************************************************************/
5063 /*
5064   PyCPointer_Type
5065 */
5066 static PyObject *
Pointer_item(PyObject * myself,Py_ssize_t index)5067 Pointer_item(PyObject *myself, Py_ssize_t index)
5068 {
5069     CDataObject *self = (CDataObject *)myself;
5070     Py_ssize_t size;
5071     Py_ssize_t offset;
5072     StgDictObject *stgdict, *itemdict;
5073     PyObject *proto;
5074 
5075     if (*(void **)self->b_ptr == NULL) {
5076         PyErr_SetString(PyExc_ValueError,
5077                         "NULL pointer access");
5078         return NULL;
5079     }
5080 
5081     stgdict = PyObject_stgdict((PyObject *)self);
5082     assert(stgdict); /* Cannot be NULL for pointer object instances */
5083 
5084     proto = stgdict->proto;
5085     assert(proto);
5086     itemdict = PyType_stgdict(proto);
5087     assert(itemdict); /* proto is the item type of the pointer, a ctypes
5088                          type, so this cannot be NULL */
5089 
5090     size = itemdict->size;
5091     offset = index * itemdict->size;
5092 
5093     return PyCData_get(proto, stgdict->getfunc, (PyObject *)self,
5094                      index, size, (*(char **)self->b_ptr) + offset);
5095 }
5096 
5097 static int
Pointer_ass_item(PyObject * myself,Py_ssize_t index,PyObject * value)5098 Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
5099 {
5100     CDataObject *self = (CDataObject *)myself;
5101     Py_ssize_t size;
5102     Py_ssize_t offset;
5103     StgDictObject *stgdict, *itemdict;
5104     PyObject *proto;
5105 
5106     if (value == NULL) {
5107         PyErr_SetString(PyExc_TypeError,
5108                         "Pointer does not support item deletion");
5109         return -1;
5110     }
5111 
5112     if (*(void **)self->b_ptr == NULL) {
5113         PyErr_SetString(PyExc_ValueError,
5114                         "NULL pointer access");
5115         return -1;
5116     }
5117 
5118     stgdict = PyObject_stgdict((PyObject *)self);
5119     assert(stgdict); /* Cannot be NULL for pointer instances */
5120 
5121     proto = stgdict->proto;
5122     assert(proto);
5123 
5124     itemdict = PyType_stgdict(proto);
5125     assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
5126                          is always a ctypes type */
5127 
5128     size = itemdict->size;
5129     offset = index * itemdict->size;
5130 
5131     return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value,
5132                      index, size, (*(char **)self->b_ptr) + offset);
5133 }
5134 
5135 static PyObject *
Pointer_get_contents(CDataObject * self,void * closure)5136 Pointer_get_contents(CDataObject *self, void *closure)
5137 {
5138     StgDictObject *stgdict;
5139 
5140     if (*(void **)self->b_ptr == NULL) {
5141         PyErr_SetString(PyExc_ValueError,
5142                         "NULL pointer access");
5143         return NULL;
5144     }
5145 
5146     stgdict = PyObject_stgdict((PyObject *)self);
5147     assert(stgdict); /* Cannot be NULL for pointer instances */
5148     return PyCData_FromBaseObj(stgdict->proto,
5149                              (PyObject *)self, 0,
5150                              *(void **)self->b_ptr);
5151 }
5152 
5153 static int
Pointer_set_contents(CDataObject * self,PyObject * value,void * closure)5154 Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
5155 {
5156     StgDictObject *stgdict;
5157     CDataObject *dst;
5158     PyObject *keep;
5159 
5160     if (value == NULL) {
5161         PyErr_SetString(PyExc_TypeError,
5162                         "Pointer does not support item deletion");
5163         return -1;
5164     }
5165     stgdict = PyObject_stgdict((PyObject *)self);
5166     assert(stgdict); /* Cannot be NULL for pointer instances */
5167     assert(stgdict->proto);
5168     if (!CDataObject_Check(value)) {
5169         int res = PyObject_IsInstance(value, stgdict->proto);
5170         if (res == -1)
5171             return -1;
5172         if (!res) {
5173             PyErr_Format(PyExc_TypeError,
5174                          "expected %s instead of %s",
5175                          ((PyTypeObject *)(stgdict->proto))->tp_name,
5176                          Py_TYPE(value)->tp_name);
5177             return -1;
5178         }
5179     }
5180 
5181     dst = (CDataObject *)value;
5182     *(void **)self->b_ptr = dst->b_ptr;
5183 
5184     /*
5185        A Pointer instance must keep the value it points to alive.  So, a
5186        pointer instance has b_length set to 2 instead of 1, and we set
5187        'value' itself as the second item of the b_objects list, additionally.
5188     */
5189     Py_INCREF(value);
5190     if (-1 == KeepRef(self, 1, value))
5191         return -1;
5192 
5193     keep = GetKeepedObjects(dst);
5194     if (keep == NULL)
5195         return -1;
5196 
5197     Py_INCREF(keep);
5198     return KeepRef(self, 0, keep);
5199 }
5200 
5201 static PyGetSetDef Pointer_getsets[] = {
5202     { "contents", (getter)Pointer_get_contents,
5203       (setter)Pointer_set_contents,
5204       "the object this pointer points to (read-write)", NULL },
5205     { NULL, NULL }
5206 };
5207 
5208 static int
Pointer_init(CDataObject * self,PyObject * args,PyObject * kw)5209 Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
5210 {
5211     PyObject *value = NULL;
5212 
5213     if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
5214         return -1;
5215     if (value == NULL)
5216         return 0;
5217     return Pointer_set_contents(self, value, NULL);
5218 }
5219 
5220 static PyObject *
Pointer_new(PyTypeObject * type,PyObject * args,PyObject * kw)5221 Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
5222 {
5223     StgDictObject *dict = PyType_stgdict((PyObject *)type);
5224     if (!dict || !dict->proto) {
5225         PyErr_SetString(PyExc_TypeError,
5226                         "Cannot create instance: has no _type_");
5227         return NULL;
5228     }
5229     return GenericPyCData_new(type, args, kw);
5230 }
5231 
5232 static PyObject *
Pointer_subscript(PyObject * myself,PyObject * item)5233 Pointer_subscript(PyObject *myself, PyObject *item)
5234 {
5235     CDataObject *self = (CDataObject *)myself;
5236     if (PyIndex_Check(item)) {
5237         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
5238         if (i == -1 && PyErr_Occurred())
5239             return NULL;
5240         return Pointer_item(myself, i);
5241     }
5242     else if (PySlice_Check(item)) {
5243         PySliceObject *slice = (PySliceObject *)item;
5244         Py_ssize_t start, stop, step;
5245         PyObject *np;
5246         StgDictObject *stgdict, *itemdict;
5247         PyObject *proto;
5248         Py_ssize_t i, len, cur;
5249 
5250         /* Since pointers have no length, and we want to apply
5251            different semantics to negative indices than normal
5252            slicing, we have to dissect the slice object ourselves.*/
5253         if (slice->step == Py_None) {
5254             step = 1;
5255         }
5256         else {
5257             step = PyNumber_AsSsize_t(slice->step,
5258                                       PyExc_ValueError);
5259             if (step == -1 && PyErr_Occurred())
5260                 return NULL;
5261             if (step == 0) {
5262                 PyErr_SetString(PyExc_ValueError,
5263                                 "slice step cannot be zero");
5264                 return NULL;
5265             }
5266         }
5267         if (slice->start == Py_None) {
5268             if (step < 0) {
5269                 PyErr_SetString(PyExc_ValueError,
5270                                 "slice start is required "
5271                                 "for step < 0");
5272                 return NULL;
5273             }
5274             start = 0;
5275         }
5276         else {
5277             start = PyNumber_AsSsize_t(slice->start,
5278                                        PyExc_ValueError);
5279             if (start == -1 && PyErr_Occurred())
5280                 return NULL;
5281         }
5282         if (slice->stop == Py_None) {
5283             PyErr_SetString(PyExc_ValueError,
5284                             "slice stop is required");
5285             return NULL;
5286         }
5287         stop = PyNumber_AsSsize_t(slice->stop,
5288                                   PyExc_ValueError);
5289         if (stop == -1 && PyErr_Occurred())
5290             return NULL;
5291         if ((step > 0 && start > stop) ||
5292             (step < 0 && start < stop))
5293             len = 0;
5294         else if (step > 0)
5295             len = (stop - start - 1) / step + 1;
5296         else
5297             len = (stop - start + 1) / step + 1;
5298 
5299         stgdict = PyObject_stgdict((PyObject *)self);
5300         assert(stgdict); /* Cannot be NULL for pointer instances */
5301         proto = stgdict->proto;
5302         assert(proto);
5303         itemdict = PyType_stgdict(proto);
5304         assert(itemdict);
5305         if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
5306             char *ptr = *(char **)self->b_ptr;
5307             char *dest;
5308 
5309             if (len <= 0)
5310                 return PyBytes_FromStringAndSize("", 0);
5311             if (step == 1) {
5312                 return PyBytes_FromStringAndSize(ptr + start,
5313                                                  len);
5314             }
5315             dest = (char *)PyMem_Malloc(len);
5316             if (dest == NULL)
5317                 return PyErr_NoMemory();
5318             for (cur = start, i = 0; i < len; cur += step, i++) {
5319                 dest[i] = ptr[cur];
5320             }
5321             np = PyBytes_FromStringAndSize(dest, len);
5322             PyMem_Free(dest);
5323             return np;
5324         }
5325 #ifdef CTYPES_UNICODE
5326         if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
5327             wchar_t *ptr = *(wchar_t **)self->b_ptr;
5328             wchar_t *dest;
5329 
5330             if (len <= 0)
5331                 return PyUnicode_New(0, 0);
5332             if (step == 1) {
5333                 return PyUnicode_FromWideChar(ptr + start,
5334                                               len);
5335             }
5336             dest = PyMem_New(wchar_t, len);
5337             if (dest == NULL)
5338                 return PyErr_NoMemory();
5339             for (cur = start, i = 0; i < len; cur += step, i++) {
5340                 dest[i] = ptr[cur];
5341             }
5342             np = PyUnicode_FromWideChar(dest, len);
5343             PyMem_Free(dest);
5344             return np;
5345         }
5346 #endif
5347 
5348         np = PyList_New(len);
5349         if (np == NULL)
5350             return NULL;
5351 
5352         for (cur = start, i = 0; i < len; cur += step, i++) {
5353             PyObject *v = Pointer_item(myself, cur);
5354             PyList_SET_ITEM(np, i, v);
5355         }
5356         return np;
5357     }
5358     else {
5359         PyErr_SetString(PyExc_TypeError,
5360                         "Pointer indices must be integer");
5361         return NULL;
5362     }
5363 }
5364 
5365 static PySequenceMethods Pointer_as_sequence = {
5366     0,                                          /* inquiry sq_length; */
5367     0,                                          /* binaryfunc sq_concat; */
5368     0,                                          /* intargfunc sq_repeat; */
5369     Pointer_item,                               /* intargfunc sq_item; */
5370     0,                                          /* intintargfunc sq_slice; */
5371     Pointer_ass_item,                           /* intobjargproc sq_ass_item; */
5372     0,                                          /* intintobjargproc sq_ass_slice; */
5373     0,                                          /* objobjproc sq_contains; */
5374     /* Added in release 2.0 */
5375     0,                                          /* binaryfunc sq_inplace_concat; */
5376     0,                                          /* intargfunc sq_inplace_repeat; */
5377 };
5378 
5379 static PyMappingMethods Pointer_as_mapping = {
5380     0,
5381     Pointer_subscript,
5382 };
5383 
5384 static int
Pointer_bool(CDataObject * self)5385 Pointer_bool(CDataObject *self)
5386 {
5387     return (*(void **)self->b_ptr != NULL);
5388 }
5389 
5390 static PyNumberMethods Pointer_as_number = {
5391     0, /* nb_add */
5392     0, /* nb_subtract */
5393     0, /* nb_multiply */
5394     0, /* nb_remainder */
5395     0, /* nb_divmod */
5396     0, /* nb_power */
5397     0, /* nb_negative */
5398     0, /* nb_positive */
5399     0, /* nb_absolute */
5400     (inquiry)Pointer_bool, /* nb_bool */
5401 };
5402 
5403 PyTypeObject PyCPointer_Type = {
5404     PyVarObject_HEAD_INIT(NULL, 0)
5405     "_ctypes._Pointer",
5406     sizeof(CDataObject),                        /* tp_basicsize */
5407     0,                                          /* tp_itemsize */
5408     0,                                          /* tp_dealloc */
5409     0,                                          /* tp_vectorcall_offset */
5410     0,                                          /* tp_getattr */
5411     0,                                          /* tp_setattr */
5412     0,                                          /* tp_as_async */
5413     0,                                          /* tp_repr */
5414     &Pointer_as_number,                         /* tp_as_number */
5415     &Pointer_as_sequence,                       /* tp_as_sequence */
5416     &Pointer_as_mapping,                        /* tp_as_mapping */
5417     0,                                          /* tp_hash */
5418     0,                                          /* tp_call */
5419     0,                                          /* tp_str */
5420     0,                                          /* tp_getattro */
5421     0,                                          /* tp_setattro */
5422     &PyCData_as_buffer,                         /* tp_as_buffer */
5423     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5424     "XXX to be provided",                       /* tp_doc */
5425     (traverseproc)PyCData_traverse,             /* tp_traverse */
5426     (inquiry)PyCData_clear,                     /* tp_clear */
5427     0,                                          /* tp_richcompare */
5428     0,                                          /* tp_weaklistoffset */
5429     0,                                          /* tp_iter */
5430     0,                                          /* tp_iternext */
5431     0,                                          /* tp_methods */
5432     0,                                          /* tp_members */
5433     Pointer_getsets,                            /* tp_getset */
5434     0,                                          /* tp_base */
5435     0,                                          /* tp_dict */
5436     0,                                          /* tp_descr_get */
5437     0,                                          /* tp_descr_set */
5438     0,                                          /* tp_dictoffset */
5439     (initproc)Pointer_init,                     /* tp_init */
5440     0,                                          /* tp_alloc */
5441     Pointer_new,                                /* tp_new */
5442     0,                                          /* tp_free */
5443 };
5444 
5445 
5446 /******************************************************************/
5447 /*
5448  *  Module initialization.
5449  */
5450 
5451 static const char module_docs[] =
5452 "Create and manipulate C compatible data types in Python.";
5453 
5454 #ifdef MS_WIN32
5455 
5456 static const char comerror_doc[] = "Raised when a COM method call failed.";
5457 
5458 int
comerror_init(PyObject * self,PyObject * args,PyObject * kwds)5459 comerror_init(PyObject *self, PyObject *args, PyObject *kwds)
5460 {
5461     PyObject *hresult, *text, *details;
5462     PyObject *a;
5463     int status;
5464 
5465     if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
5466         return -1;
5467 
5468     if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details))
5469         return -1;
5470 
5471     a = PySequence_GetSlice(args, 1, PyTuple_GET_SIZE(args));
5472     if (!a)
5473         return -1;
5474     status = PyObject_SetAttrString(self, "args", a);
5475     Py_DECREF(a);
5476     if (status < 0)
5477         return -1;
5478 
5479     if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
5480         return -1;
5481 
5482     if (PyObject_SetAttrString(self, "text", text) < 0)
5483         return -1;
5484 
5485     if (PyObject_SetAttrString(self, "details", details) < 0)
5486         return -1;
5487 
5488     Py_INCREF(args);
5489     Py_SETREF(((PyBaseExceptionObject *)self)->args, args);
5490 
5491     return 0;
5492 }
5493 
5494 static PyTypeObject PyComError_Type = {
5495     PyVarObject_HEAD_INIT(NULL, 0)
5496     "_ctypes.COMError",         /* tp_name */
5497     sizeof(PyBaseExceptionObject), /* tp_basicsize */
5498     0,                          /* tp_itemsize */
5499     0,                          /* tp_dealloc */
5500     0,                          /* tp_vectorcall_offset */
5501     0,                          /* tp_getattr */
5502     0,                          /* tp_setattr */
5503     0,                          /* tp_as_async */
5504     0,                          /* tp_repr */
5505     0,                          /* tp_as_number */
5506     0,                          /* tp_as_sequence */
5507     0,                          /* tp_as_mapping */
5508     0,                          /* tp_hash */
5509     0,                          /* tp_call */
5510     0,                          /* tp_str */
5511     0,                          /* tp_getattro */
5512     0,                          /* tp_setattro */
5513     0,                          /* tp_as_buffer */
5514     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
5515     PyDoc_STR(comerror_doc),    /* tp_doc */
5516     0,                          /* tp_traverse */
5517     0,                          /* tp_clear */
5518     0,                          /* tp_richcompare */
5519     0,                          /* tp_weaklistoffset */
5520     0,                          /* tp_iter */
5521     0,                          /* tp_iternext */
5522     0,                          /* tp_methods */
5523     0,                          /* tp_members */
5524     0,                          /* tp_getset */
5525     0,                          /* tp_base */
5526     0,                          /* tp_dict */
5527     0,                          /* tp_descr_get */
5528     0,                          /* tp_descr_set */
5529     0,                          /* tp_dictoffset */
5530     (initproc)comerror_init,    /* tp_init */
5531     0,                          /* tp_alloc */
5532     0,                          /* tp_new */
5533 };
5534 
5535 
5536 static int
create_comerror(void)5537 create_comerror(void)
5538 {
5539     PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception;
5540     if (PyType_Ready(&PyComError_Type) < 0)
5541         return -1;
5542     Py_INCREF(&PyComError_Type);
5543     ComError = (PyObject*)&PyComError_Type;
5544     return 0;
5545 }
5546 
5547 #endif
5548 
5549 static PyObject *
string_at(const char * ptr,int size)5550 string_at(const char *ptr, int size)
5551 {
5552     if (PySys_Audit("ctypes.string_at", "ni", (Py_ssize_t)ptr, size) < 0) {
5553         return NULL;
5554     }
5555     if (size == -1)
5556         return PyBytes_FromStringAndSize(ptr, strlen(ptr));
5557     return PyBytes_FromStringAndSize(ptr, size);
5558 }
5559 
5560 static int
cast_check_pointertype(PyObject * arg)5561 cast_check_pointertype(PyObject *arg)
5562 {
5563     StgDictObject *dict;
5564 
5565     if (PyCPointerTypeObject_Check(arg))
5566         return 1;
5567     if (PyCFuncPtrTypeObject_Check(arg))
5568         return 1;
5569     dict = PyType_stgdict(arg);
5570     if (dict != NULL && dict->proto != NULL) {
5571         if (PyUnicode_Check(dict->proto)
5572             && (strchr("sPzUZXO", PyUnicode_AsUTF8(dict->proto)[0]))) {
5573             /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
5574             return 1;
5575         }
5576     }
5577     PyErr_Format(PyExc_TypeError,
5578                  "cast() argument 2 must be a pointer type, not %s",
5579                  PyType_Check(arg)
5580                  ? ((PyTypeObject *)arg)->tp_name
5581                  : Py_TYPE(arg)->tp_name);
5582     return 0;
5583 }
5584 
5585 static PyObject *
cast(void * ptr,PyObject * src,PyObject * ctype)5586 cast(void *ptr, PyObject *src, PyObject *ctype)
5587 {
5588     CDataObject *result;
5589     if (0 == cast_check_pointertype(ctype))
5590         return NULL;
5591     result = (CDataObject *)_PyObject_CallNoArg(ctype);
5592     if (result == NULL)
5593         return NULL;
5594 
5595     /*
5596       The casted objects '_objects' member:
5597 
5598       It must certainly contain the source objects one.
5599       It must contain the source object itself.
5600      */
5601     if (CDataObject_Check(src)) {
5602         CDataObject *obj = (CDataObject *)src;
5603         CDataObject *container;
5604 
5605         /* PyCData_GetContainer will initialize src.b_objects, we need
5606            this so it can be shared */
5607         container = PyCData_GetContainer(obj);
5608         if (container == NULL)
5609             goto failed;
5610 
5611         /* But we need a dictionary! */
5612         if (obj->b_objects == Py_None) {
5613             Py_DECREF(Py_None);
5614             obj->b_objects = PyDict_New();
5615             if (obj->b_objects == NULL)
5616                 goto failed;
5617         }
5618         Py_XINCREF(obj->b_objects);
5619         result->b_objects = obj->b_objects;
5620         if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
5621             PyObject *index;
5622             int rc;
5623             index = PyLong_FromVoidPtr((void *)src);
5624             if (index == NULL)
5625                 goto failed;
5626             rc = PyDict_SetItem(result->b_objects, index, src);
5627             Py_DECREF(index);
5628             if (rc == -1)
5629                 goto failed;
5630         }
5631     }
5632     /* Should we assert that result is a pointer type? */
5633     memcpy(result->b_ptr, &ptr, sizeof(void *));
5634     return (PyObject *)result;
5635 
5636   failed:
5637     Py_DECREF(result);
5638     return NULL;
5639 }
5640 
5641 #ifdef CTYPES_UNICODE
5642 static PyObject *
wstring_at(const wchar_t * ptr,int size)5643 wstring_at(const wchar_t *ptr, int size)
5644 {
5645     Py_ssize_t ssize = size;
5646     if (PySys_Audit("ctypes.wstring_at", "nn", (Py_ssize_t)ptr, ssize) < 0) {
5647         return NULL;
5648     }
5649     if (ssize == -1)
5650         ssize = wcslen(ptr);
5651     return PyUnicode_FromWideChar(ptr, ssize);
5652 }
5653 #endif
5654 
5655 
5656 static struct PyModuleDef _ctypesmodule = {
5657     PyModuleDef_HEAD_INIT,
5658     "_ctypes",
5659     module_docs,
5660     -1,
5661     _ctypes_module_methods,
5662     NULL,
5663     NULL,
5664     NULL,
5665     NULL
5666 };
5667 
5668 PyMODINIT_FUNC
PyInit__ctypes(void)5669 PyInit__ctypes(void)
5670 {
5671     PyObject *m;
5672 
5673 /* Note:
5674    ob_type is the metatype (the 'type'), defaults to PyType_Type,
5675    tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
5676 */
5677     PyEval_InitThreads();
5678     m = PyModule_Create(&_ctypesmodule);
5679     if (!m)
5680         return NULL;
5681 
5682     _ctypes_ptrtype_cache = PyDict_New();
5683     if (_ctypes_ptrtype_cache == NULL)
5684         return NULL;
5685 
5686     PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache);
5687 
5688     _unpickle = PyObject_GetAttrString(m, "_unpickle");
5689     if (_unpickle == NULL)
5690         return NULL;
5691 
5692     if (PyType_Ready(&PyCArg_Type) < 0)
5693         return NULL;
5694 
5695     if (PyType_Ready(&PyCThunk_Type) < 0)
5696         return NULL;
5697 
5698     /* StgDict is derived from PyDict_Type */
5699     PyCStgDict_Type.tp_base = &PyDict_Type;
5700     if (PyType_Ready(&PyCStgDict_Type) < 0)
5701         return NULL;
5702 
5703     /*************************************************
5704      *
5705      * Metaclasses
5706      */
5707 
5708     PyCStructType_Type.tp_base = &PyType_Type;
5709     if (PyType_Ready(&PyCStructType_Type) < 0)
5710         return NULL;
5711 
5712     UnionType_Type.tp_base = &PyType_Type;
5713     if (PyType_Ready(&UnionType_Type) < 0)
5714         return NULL;
5715 
5716     PyCPointerType_Type.tp_base = &PyType_Type;
5717     if (PyType_Ready(&PyCPointerType_Type) < 0)
5718         return NULL;
5719 
5720     PyCArrayType_Type.tp_base = &PyType_Type;
5721     if (PyType_Ready(&PyCArrayType_Type) < 0)
5722         return NULL;
5723 
5724     PyCSimpleType_Type.tp_base = &PyType_Type;
5725     if (PyType_Ready(&PyCSimpleType_Type) < 0)
5726         return NULL;
5727 
5728     PyCFuncPtrType_Type.tp_base = &PyType_Type;
5729     if (PyType_Ready(&PyCFuncPtrType_Type) < 0)
5730         return NULL;
5731 
5732     /*************************************************
5733      *
5734      * Classes using a custom metaclass
5735      */
5736 
5737     if (PyType_Ready(&PyCData_Type) < 0)
5738         return NULL;
5739 
5740     Py_TYPE(&Struct_Type) = &PyCStructType_Type;
5741     Struct_Type.tp_base = &PyCData_Type;
5742     if (PyType_Ready(&Struct_Type) < 0)
5743         return NULL;
5744     Py_INCREF(&Struct_Type);
5745     PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
5746 
5747     Py_TYPE(&Union_Type) = &UnionType_Type;
5748     Union_Type.tp_base = &PyCData_Type;
5749     if (PyType_Ready(&Union_Type) < 0)
5750         return NULL;
5751     Py_INCREF(&Union_Type);
5752     PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
5753 
5754     Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type;
5755     PyCPointer_Type.tp_base = &PyCData_Type;
5756     if (PyType_Ready(&PyCPointer_Type) < 0)
5757         return NULL;
5758     Py_INCREF(&PyCPointer_Type);
5759     PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);
5760 
5761     Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type;
5762     PyCArray_Type.tp_base = &PyCData_Type;
5763     if (PyType_Ready(&PyCArray_Type) < 0)
5764         return NULL;
5765     Py_INCREF(&PyCArray_Type);
5766     PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);
5767 
5768     Py_TYPE(&Simple_Type) = &PyCSimpleType_Type;
5769     Simple_Type.tp_base = &PyCData_Type;
5770     if (PyType_Ready(&Simple_Type) < 0)
5771         return NULL;
5772     Py_INCREF(&Simple_Type);
5773     PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
5774 
5775     Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type;
5776     PyCFuncPtr_Type.tp_base = &PyCData_Type;
5777     if (PyType_Ready(&PyCFuncPtr_Type) < 0)
5778         return NULL;
5779     Py_INCREF(&PyCFuncPtr_Type);
5780     PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);
5781 
5782     /*************************************************
5783      *
5784      * Simple classes
5785      */
5786 
5787     /* PyCField_Type is derived from PyBaseObject_Type */
5788     if (PyType_Ready(&PyCField_Type) < 0)
5789         return NULL;
5790 
5791     /*************************************************
5792      *
5793      * Other stuff
5794      */
5795 
5796     DictRemover_Type.tp_new = PyType_GenericNew;
5797     if (PyType_Ready(&DictRemover_Type) < 0)
5798         return NULL;
5799 
5800     if (PyType_Ready(&StructParam_Type) < 0) {
5801         return NULL;
5802     }
5803 
5804 #ifdef MS_WIN32
5805     if (create_comerror() < 0)
5806         return NULL;
5807     PyModule_AddObject(m, "COMError", ComError);
5808 
5809     PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
5810     PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
5811 #endif
5812     PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL));
5813     PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
5814     PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
5815     PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
5816     PyModule_AddStringConstant(m, "__version__", "1.1.0");
5817 
5818     PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
5819     PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
5820     PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
5821     PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
5822 #ifdef CTYPES_UNICODE
5823     PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
5824 #endif
5825 
5826 /* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
5827 #if !HAVE_DECL_RTLD_LOCAL
5828 #define RTLD_LOCAL 0
5829 #endif
5830 
5831 /* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
5832    RTLD_LOCAL.
5833 */
5834 #if !HAVE_DECL_RTLD_GLOBAL
5835 #define RTLD_GLOBAL RTLD_LOCAL
5836 #endif
5837 
5838     PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL));
5839     PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL));
5840 
5841     PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5842     if (PyExc_ArgError) {
5843         Py_INCREF(PyExc_ArgError);
5844         PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
5845     }
5846     return m;
5847 }
5848 
5849 /*
5850  Local Variables:
5851  compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
5852  End:
5853 */
5854