• 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"         // PyMemberDef
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_CallNoArg(
1064         (PyObject *)&PyCStgDict_Type);
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     const 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_CallNoArg(
1556         (PyObject *)&PyCStgDict_Type);
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_CallNoArg(
2013         (PyObject *)&PyCStgDict_Type);
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_CallNoArg(
2127         (PyObject *)&PyCStgDict_Type);
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 /*
2405  *      The following checks, relating to bpo-16575 and bpo-16576, have been
2406  *      disabled. The reason is that, although there is a definite problem with
2407  *      how libffi handles unions (https://github.com/libffi/libffi/issues/33),
2408  *      there are numerous libraries which pass structures containing unions
2409  *      by values - especially on Windows but examples also exist on Linux
2410  *      (https://bugs.python.org/msg359834).
2411  *
2412  *      It may not be possible to get proper support for unions and bitfields
2413  *      until support is forthcoming in libffi, but for now, adding the checks
2414  *      has caused problems in otherwise-working software, which suggests it
2415  *      is better to disable the checks.
2416  *
2417  *      Although specific examples reported relate specifically to unions and
2418  *      not bitfields, the bitfields check is also being disabled as a
2419  *      precaution.
2420 
2421         StgDictObject *stgdict = PyType_stgdict(tp);
2422 
2423         if (stgdict != NULL) {
2424             if (stgdict->flags & TYPEFLAG_HASUNION) {
2425                 Py_DECREF(converters);
2426                 Py_DECREF(ob);
2427                 if (!PyErr_Occurred()) {
2428                     PyErr_Format(PyExc_TypeError,
2429                                  "item %zd in _argtypes_ passes a union by "
2430                                  "value, which is unsupported.",
2431                                  i + 1);
2432                 }
2433                 return NULL;
2434             }
2435             if (stgdict->flags & TYPEFLAG_HASBITFIELD) {
2436                 Py_DECREF(converters);
2437                 Py_DECREF(ob);
2438                 if (!PyErr_Occurred()) {
2439                     PyErr_Format(PyExc_TypeError,
2440                                  "item %zd in _argtypes_ passes a struct/"
2441                                  "union with a bitfield by value, which is "
2442                                  "unsupported.",
2443                                  i + 1);
2444                 }
2445                 return NULL;
2446             }
2447         }
2448  */
2449 
2450         if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) {
2451             Py_DECREF(converters);
2452             Py_DECREF(ob);
2453             if (!PyErr_Occurred()) {
2454                 PyErr_Format(PyExc_TypeError,
2455                              "item %zd in _argtypes_ has no from_param method",
2456                              i+1);
2457             }
2458             return NULL;
2459         }
2460         PyTuple_SET_ITEM(converters, i, cnv);
2461     }
2462     Py_DECREF(ob);
2463     return converters;
2464 }
2465 
2466 static int
make_funcptrtype_dict(StgDictObject * stgdict)2467 make_funcptrtype_dict(StgDictObject *stgdict)
2468 {
2469     PyObject *ob;
2470     PyObject *converters = NULL;
2471     _Py_IDENTIFIER(_flags_);
2472     _Py_IDENTIFIER(_argtypes_);
2473     _Py_IDENTIFIER(_restype_);
2474     _Py_IDENTIFIER(_check_retval_);
2475 
2476     stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
2477     stgdict->length = 1;
2478     stgdict->size = sizeof(void *);
2479     stgdict->setfunc = NULL;
2480     stgdict->getfunc = NULL;
2481     stgdict->ffi_type_pointer = ffi_type_pointer;
2482 
2483     ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__flags_);
2484     if (!ob || !PyLong_Check(ob)) {
2485         if (!PyErr_Occurred()) {
2486             PyErr_SetString(PyExc_TypeError,
2487                 "class must define _flags_ which must be an integer");
2488         }
2489         return -1;
2490     }
2491     stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER;
2492 
2493     /* _argtypes_ is optional... */
2494     ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__argtypes_);
2495     if (ob) {
2496         converters = converters_from_argtypes(ob);
2497         if (!converters)
2498             return -1;
2499         Py_INCREF(ob);
2500         stgdict->argtypes = ob;
2501         stgdict->converters = converters;
2502     }
2503     else if (PyErr_Occurred()) {
2504         return -1;
2505     }
2506 
2507     ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__restype_);
2508     if (ob) {
2509         if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2510             PyErr_SetString(PyExc_TypeError,
2511                 "_restype_ must be a type, a callable, or None");
2512             return -1;
2513         }
2514         Py_INCREF(ob);
2515         stgdict->restype = ob;
2516         if (_PyObject_LookupAttrId(ob, &PyId__check_retval_,
2517                                    &stgdict->checker) < 0)
2518         {
2519             return -1;
2520         }
2521     }
2522     else if (PyErr_Occurred()) {
2523         return -1;
2524     }
2525 /* XXX later, maybe.
2526     ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__errcheck_);
2527     if (ob) {
2528         if (!PyCallable_Check(ob)) {
2529             PyErr_SetString(PyExc_TypeError,
2530                 "_errcheck_ must be callable");
2531             return -1;
2532         }
2533         Py_INCREF(ob);
2534         stgdict->errcheck = ob;
2535     }
2536     else if (PyErr_Occurred()) {
2537         return -1;
2538     }
2539 */
2540     return 0;
2541 }
2542 
2543 static PyCArgObject *
PyCFuncPtrType_paramfunc(CDataObject * self)2544 PyCFuncPtrType_paramfunc(CDataObject *self)
2545 {
2546     PyCArgObject *parg;
2547 
2548     parg = PyCArgObject_new();
2549     if (parg == NULL)
2550         return NULL;
2551 
2552     parg->tag = 'P';
2553     parg->pffi_type = &ffi_type_pointer;
2554     Py_INCREF(self);
2555     parg->obj = (PyObject *)self;
2556     parg->value.p = *(void **)self->b_ptr;
2557     return parg;
2558 }
2559 
2560 static PyObject *
PyCFuncPtrType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)2561 PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2562 {
2563     PyTypeObject *result;
2564     StgDictObject *stgdict;
2565 
2566     stgdict = (StgDictObject *)_PyObject_CallNoArg(
2567         (PyObject *)&PyCStgDict_Type);
2568     if (!stgdict)
2569         return NULL;
2570 
2571     stgdict->paramfunc = PyCFuncPtrType_paramfunc;
2572     /* We do NOT expose the function signature in the format string.  It
2573        is impossible, generally, because the only requirement for the
2574        argtypes items is that they have a .from_param method - we do not
2575        know the types of the arguments (although, in practice, most
2576        argtypes would be a ctypes type).
2577     */
2578     stgdict->format = _ctypes_alloc_format_string(NULL, "X{}");
2579     if (stgdict->format == NULL) {
2580         Py_DECREF((PyObject *)stgdict);
2581         return NULL;
2582     }
2583     stgdict->flags |= TYPEFLAG_ISPOINTER;
2584 
2585     /* create the new instance (which is a class,
2586        since we are a metatype!) */
2587     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2588     if (result == NULL) {
2589         Py_DECREF((PyObject *)stgdict);
2590         return NULL;
2591     }
2592 
2593     /* replace the class dict by our updated storage dict */
2594     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2595         Py_DECREF(result);
2596         Py_DECREF((PyObject *)stgdict);
2597         return NULL;
2598     }
2599     Py_SETREF(result->tp_dict, (PyObject *)stgdict);
2600 
2601     if (-1 == make_funcptrtype_dict(stgdict)) {
2602         Py_DECREF(result);
2603         return NULL;
2604     }
2605 
2606     return (PyObject *)result;
2607 }
2608 
2609 PyTypeObject PyCFuncPtrType_Type = {
2610     PyVarObject_HEAD_INIT(NULL, 0)
2611     "_ctypes.PyCFuncPtrType",                           /* tp_name */
2612     0,                                          /* tp_basicsize */
2613     0,                                          /* tp_itemsize */
2614     0,                                          /* tp_dealloc */
2615     0,                                          /* tp_vectorcall_offset */
2616     0,                                          /* tp_getattr */
2617     0,                                          /* tp_setattr */
2618     0,                                          /* tp_as_async */
2619     0,                                          /* tp_repr */
2620     0,                                          /* tp_as_number */
2621     &CDataType_as_sequence,                     /* tp_as_sequence */
2622     0,                                          /* tp_as_mapping */
2623     0,                                          /* tp_hash */
2624     0,                                          /* tp_call */
2625     0,                                          /* tp_str */
2626     0,                                          /* tp_getattro */
2627     0,                                          /* tp_setattro */
2628     0,                                          /* tp_as_buffer */
2629     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2630     "metatype for C function pointers",         /* tp_doc */
2631     (traverseproc)CDataType_traverse,           /* tp_traverse */
2632     (inquiry)CDataType_clear,                   /* tp_clear */
2633     0,                                          /* tp_richcompare */
2634     0,                                          /* tp_weaklistoffset */
2635     0,                                          /* tp_iter */
2636     0,                                          /* tp_iternext */
2637     CDataType_methods,                          /* tp_methods */
2638     0,                                          /* tp_members */
2639     0,                                          /* tp_getset */
2640     0,                                          /* tp_base */
2641     0,                                          /* tp_dict */
2642     0,                                          /* tp_descr_get */
2643     0,                                          /* tp_descr_set */
2644     0,                                          /* tp_dictoffset */
2645     0,                                          /* tp_init */
2646     0,                                          /* tp_alloc */
2647     PyCFuncPtrType_new,                         /* tp_new */
2648     0,                                          /* tp_free */
2649 };
2650 
2651 
2652 /*****************************************************************
2653  * Code to keep needed objects alive
2654  */
2655 
2656 static CDataObject *
PyCData_GetContainer(CDataObject * self)2657 PyCData_GetContainer(CDataObject *self)
2658 {
2659     while (self->b_base)
2660         self = self->b_base;
2661     if (self->b_objects == NULL) {
2662         if (self->b_length) {
2663             self->b_objects = PyDict_New();
2664             if (self->b_objects == NULL)
2665                 return NULL;
2666         } else {
2667             Py_INCREF(Py_None);
2668             self->b_objects = Py_None;
2669         }
2670     }
2671     return self;
2672 }
2673 
2674 static PyObject *
GetKeepedObjects(CDataObject * target)2675 GetKeepedObjects(CDataObject *target)
2676 {
2677     CDataObject *container;
2678     container = PyCData_GetContainer(target);
2679     if (container == NULL)
2680         return NULL;
2681     return container->b_objects;
2682 }
2683 
2684 static PyObject *
unique_key(CDataObject * target,Py_ssize_t index)2685 unique_key(CDataObject *target, Py_ssize_t index)
2686 {
2687     char string[256];
2688     char *cp = string;
2689     size_t bytes_left;
2690 
2691     Py_BUILD_ASSERT(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
2692     cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2693     while (target->b_base) {
2694         bytes_left = sizeof(string) - (cp - string) - 1;
2695         /* Hex format needs 2 characters per byte */
2696         if (bytes_left < sizeof(Py_ssize_t) * 2) {
2697             PyErr_SetString(PyExc_ValueError,
2698                             "ctypes object structure too deep");
2699             return NULL;
2700         }
2701         cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
2702         target = target->b_base;
2703     }
2704     return PyUnicode_FromStringAndSize(string, cp-string);
2705 }
2706 
2707 /*
2708  * Keep a reference to 'keep' in the 'target', at index 'index'.
2709  *
2710  * If 'keep' is None, do nothing.
2711  *
2712  * Otherwise create a dictionary (if it does not yet exist) id the root
2713  * objects 'b_objects' item, which will store the 'keep' object under a unique
2714  * key.
2715  *
2716  * The unique_key helper travels the target's b_base pointer down to the root,
2717  * building a string containing hex-formatted indexes found during traversal,
2718  * separated by colons.
2719  *
2720  * The index tuple is used as a key into the root object's b_objects dict.
2721  *
2722  * Note: This function steals a refcount of the third argument, even if it
2723  * fails!
2724  */
2725 static int
KeepRef(CDataObject * target,Py_ssize_t index,PyObject * keep)2726 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
2727 {
2728     int result;
2729     CDataObject *ob;
2730     PyObject *key;
2731 
2732 /* Optimization: no need to store None */
2733     if (keep == Py_None) {
2734         Py_DECREF(Py_None);
2735         return 0;
2736     }
2737     ob = PyCData_GetContainer(target);
2738     if (ob == NULL) {
2739         Py_DECREF(keep);
2740         return -1;
2741     }
2742     if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
2743         Py_XSETREF(ob->b_objects, keep); /* refcount consumed */
2744         return 0;
2745     }
2746     key = unique_key(target, index);
2747     if (key == NULL) {
2748         Py_DECREF(keep);
2749         return -1;
2750     }
2751     result = PyDict_SetItem(ob->b_objects, key, keep);
2752     Py_DECREF(key);
2753     Py_DECREF(keep);
2754     return result;
2755 }
2756 
2757 /******************************************************************/
2758 /*
2759   PyCData_Type
2760  */
2761 static int
PyCData_traverse(CDataObject * self,visitproc visit,void * arg)2762 PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
2763 {
2764     Py_VISIT(self->b_objects);
2765     Py_VISIT((PyObject *)self->b_base);
2766     return 0;
2767 }
2768 
2769 static int
PyCData_clear(CDataObject * self)2770 PyCData_clear(CDataObject *self)
2771 {
2772     Py_CLEAR(self->b_objects);
2773     if ((self->b_needsfree)
2774         && _CDataObject_HasExternalBuffer(self))
2775         PyMem_Free(self->b_ptr);
2776     self->b_ptr = NULL;
2777     Py_CLEAR(self->b_base);
2778     return 0;
2779 }
2780 
2781 static void
PyCData_dealloc(PyObject * self)2782 PyCData_dealloc(PyObject *self)
2783 {
2784     PyCData_clear((CDataObject *)self);
2785     Py_TYPE(self)->tp_free(self);
2786 }
2787 
2788 static PyMemberDef PyCData_members[] = {
2789     { "_b_base_", T_OBJECT,
2790       offsetof(CDataObject, b_base), READONLY,
2791       "the base object" },
2792     { "_b_needsfree_", T_INT,
2793       offsetof(CDataObject, b_needsfree), READONLY,
2794       "whether the object owns the memory or not" },
2795     { "_objects", T_OBJECT,
2796       offsetof(CDataObject, b_objects), READONLY,
2797       "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2798     { NULL },
2799 };
2800 
PyCData_NewGetBuffer(PyObject * myself,Py_buffer * view,int flags)2801 static int PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
2802 {
2803     CDataObject *self = (CDataObject *)myself;
2804     StgDictObject *dict = PyObject_stgdict(myself);
2805     Py_ssize_t i;
2806 
2807     if (view == NULL) return 0;
2808 
2809     view->buf = self->b_ptr;
2810     view->obj = myself;
2811     Py_INCREF(myself);
2812     view->len = self->b_size;
2813     view->readonly = 0;
2814     /* use default format character if not set */
2815     view->format = dict->format ? dict->format : "B";
2816     view->ndim = dict->ndim;
2817     view->shape = dict->shape;
2818     view->itemsize = self->b_size;
2819     if (view->itemsize) {
2820         for (i = 0; i < view->ndim; ++i) {
2821             view->itemsize /= dict->shape[i];
2822         }
2823     }
2824     view->strides = NULL;
2825     view->suboffsets = NULL;
2826     view->internal = NULL;
2827     return 0;
2828 }
2829 
2830 static PyBufferProcs PyCData_as_buffer = {
2831     PyCData_NewGetBuffer,
2832     NULL,
2833 };
2834 
2835 /*
2836  * CData objects are mutable, so they cannot be hashable!
2837  */
2838 static Py_hash_t
PyCData_nohash(PyObject * self)2839 PyCData_nohash(PyObject *self)
2840 {
2841     PyErr_SetString(PyExc_TypeError, "unhashable type");
2842     return -1;
2843 }
2844 
2845 static PyObject *
PyCData_reduce(PyObject * myself,PyObject * args)2846 PyCData_reduce(PyObject *myself, PyObject *args)
2847 {
2848     CDataObject *self = (CDataObject *)myself;
2849 
2850     if (PyObject_stgdict(myself)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
2851         PyErr_SetString(PyExc_ValueError,
2852                         "ctypes objects containing pointers cannot be pickled");
2853         return NULL;
2854     }
2855     PyObject *dict = PyObject_GetAttrString(myself, "__dict__");
2856     if (dict == NULL) {
2857         return NULL;
2858     }
2859     return Py_BuildValue("O(O(NN))", _unpickle, Py_TYPE(myself), dict,
2860                          PyBytes_FromStringAndSize(self->b_ptr, self->b_size));
2861 }
2862 
2863 static PyObject *
PyCData_setstate(PyObject * myself,PyObject * args)2864 PyCData_setstate(PyObject *myself, PyObject *args)
2865 {
2866     void *data;
2867     Py_ssize_t len;
2868     int res;
2869     PyObject *dict, *mydict;
2870     CDataObject *self = (CDataObject *)myself;
2871     if (!PyArg_ParseTuple(args, "O!s#",
2872                           &PyDict_Type, &dict, &data, &len))
2873     {
2874         return NULL;
2875     }
2876     if (len > self->b_size)
2877         len = self->b_size;
2878     memmove(self->b_ptr, data, len);
2879     mydict = PyObject_GetAttrString(myself, "__dict__");
2880     if (mydict == NULL) {
2881         return NULL;
2882     }
2883     if (!PyDict_Check(mydict)) {
2884         PyErr_Format(PyExc_TypeError,
2885                      "%.200s.__dict__ must be a dictionary, not %.200s",
2886                      Py_TYPE(myself)->tp_name, Py_TYPE(mydict)->tp_name);
2887         Py_DECREF(mydict);
2888         return NULL;
2889     }
2890     res = PyDict_Update(mydict, dict);
2891     Py_DECREF(mydict);
2892     if (res == -1)
2893         return NULL;
2894     Py_RETURN_NONE;
2895 }
2896 
2897 /*
2898  * default __ctypes_from_outparam__ method returns self.
2899  */
2900 static PyObject *
PyCData_from_outparam(PyObject * self,PyObject * args)2901 PyCData_from_outparam(PyObject *self, PyObject *args)
2902 {
2903     Py_INCREF(self);
2904     return self;
2905 }
2906 
2907 static PyMethodDef PyCData_methods[] = {
2908     { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
2909     { "__reduce__", PyCData_reduce, METH_NOARGS, },
2910     { "__setstate__", PyCData_setstate, METH_VARARGS, },
2911     { NULL, NULL },
2912 };
2913 
2914 PyTypeObject PyCData_Type = {
2915     PyVarObject_HEAD_INIT(NULL, 0)
2916     "_ctypes._CData",
2917     sizeof(CDataObject),                        /* tp_basicsize */
2918     0,                                          /* tp_itemsize */
2919     PyCData_dealloc,                                    /* tp_dealloc */
2920     0,                                          /* tp_vectorcall_offset */
2921     0,                                          /* tp_getattr */
2922     0,                                          /* tp_setattr */
2923     0,                                          /* tp_as_async */
2924     0,                                          /* tp_repr */
2925     0,                                          /* tp_as_number */
2926     0,                                          /* tp_as_sequence */
2927     0,                                          /* tp_as_mapping */
2928     PyCData_nohash,                             /* tp_hash */
2929     0,                                          /* tp_call */
2930     0,                                          /* tp_str */
2931     0,                                          /* tp_getattro */
2932     0,                                          /* tp_setattro */
2933     &PyCData_as_buffer,                         /* tp_as_buffer */
2934     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2935     "XXX to be provided",                       /* tp_doc */
2936     (traverseproc)PyCData_traverse,             /* tp_traverse */
2937     (inquiry)PyCData_clear,                     /* tp_clear */
2938     0,                                          /* tp_richcompare */
2939     0,                                          /* tp_weaklistoffset */
2940     0,                                          /* tp_iter */
2941     0,                                          /* tp_iternext */
2942     PyCData_methods,                                    /* tp_methods */
2943     PyCData_members,                                    /* tp_members */
2944     0,                                          /* tp_getset */
2945     0,                                          /* tp_base */
2946     0,                                          /* tp_dict */
2947     0,                                          /* tp_descr_get */
2948     0,                                          /* tp_descr_set */
2949     0,                                          /* tp_dictoffset */
2950     0,                                          /* tp_init */
2951     0,                                          /* tp_alloc */
2952     0,                                          /* tp_new */
2953     0,                                          /* tp_free */
2954 };
2955 
PyCData_MallocBuffer(CDataObject * obj,StgDictObject * dict)2956 static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
2957 {
2958     if ((size_t)dict->size <= sizeof(obj->b_value)) {
2959         /* No need to call malloc, can use the default buffer */
2960         obj->b_ptr = (char *)&obj->b_value;
2961         /* The b_needsfree flag does not mean that we actually did
2962            call PyMem_Malloc to allocate the memory block; instead it
2963            means we are the *owner* of the memory and are responsible
2964            for freeing resources associated with the memory.  This is
2965            also the reason that b_needsfree is exposed to Python.
2966          */
2967         obj->b_needsfree = 1;
2968     } else {
2969         /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2970            33% of the creation time for c_int().
2971         */
2972         obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2973         if (obj->b_ptr == NULL) {
2974             PyErr_NoMemory();
2975             return -1;
2976         }
2977         obj->b_needsfree = 1;
2978         memset(obj->b_ptr, 0, dict->size);
2979     }
2980     obj->b_size = dict->size;
2981     return 0;
2982 }
2983 
2984 PyObject *
PyCData_FromBaseObj(PyObject * type,PyObject * base,Py_ssize_t index,char * adr)2985 PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
2986 {
2987     CDataObject *cmem;
2988     StgDictObject *dict;
2989 
2990     assert(PyType_Check(type));
2991     dict = PyType_stgdict(type);
2992     if (!dict) {
2993         PyErr_SetString(PyExc_TypeError,
2994                         "abstract class");
2995         return NULL;
2996     }
2997     dict->flags |= DICTFLAG_FINAL;
2998     cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2999     if (cmem == NULL)
3000         return NULL;
3001     assert(CDataObject_Check(cmem));
3002 
3003     cmem->b_length = dict->length;
3004     cmem->b_size = dict->size;
3005     if (base) { /* use base's buffer */
3006         assert(CDataObject_Check(base));
3007         cmem->b_ptr = adr;
3008         cmem->b_needsfree = 0;
3009         Py_INCREF(base);
3010         cmem->b_base = (CDataObject *)base;
3011         cmem->b_index = index;
3012     } else { /* copy contents of adr */
3013         if (-1 == PyCData_MallocBuffer(cmem, dict)) {
3014             Py_DECREF(cmem);
3015             return NULL;
3016         }
3017         memcpy(cmem->b_ptr, adr, dict->size);
3018         cmem->b_index = index;
3019     }
3020     return (PyObject *)cmem;
3021 }
3022 
3023 /*
3024  Box a memory block into a CData instance.
3025 */
3026 PyObject *
PyCData_AtAddress(PyObject * type,void * buf)3027 PyCData_AtAddress(PyObject *type, void *buf)
3028 {
3029     CDataObject *pd;
3030     StgDictObject *dict;
3031 
3032     if (PySys_Audit("ctypes.cdata", "n", (Py_ssize_t)buf) < 0) {
3033         return NULL;
3034     }
3035 
3036     assert(PyType_Check(type));
3037     dict = PyType_stgdict(type);
3038     if (!dict) {
3039         PyErr_SetString(PyExc_TypeError,
3040                         "abstract class");
3041         return NULL;
3042     }
3043     dict->flags |= DICTFLAG_FINAL;
3044 
3045     pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
3046     if (!pd)
3047         return NULL;
3048     assert(CDataObject_Check(pd));
3049     pd->b_ptr = (char *)buf;
3050     pd->b_length = dict->length;
3051     pd->b_size = dict->size;
3052     return (PyObject *)pd;
3053 }
3054 
3055 /*
3056   This function returns TRUE for c_int, c_void_p, and these kind of
3057   classes.  FALSE otherwise FALSE also for subclasses of c_int and
3058   such.
3059 */
_ctypes_simple_instance(PyObject * obj)3060 int _ctypes_simple_instance(PyObject *obj)
3061 {
3062     PyTypeObject *type = (PyTypeObject *)obj;
3063 
3064     if (PyCSimpleTypeObject_Check(type))
3065         return type->tp_base != &Simple_Type;
3066     return 0;
3067 }
3068 
3069 PyObject *
PyCData_get(PyObject * type,GETFUNC getfunc,PyObject * src,Py_ssize_t index,Py_ssize_t size,char * adr)3070 PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
3071           Py_ssize_t index, Py_ssize_t size, char *adr)
3072 {
3073     StgDictObject *dict;
3074     if (getfunc)
3075         return getfunc(adr, size);
3076     assert(type);
3077     dict = PyType_stgdict(type);
3078     if (dict && dict->getfunc && !_ctypes_simple_instance(type))
3079         return dict->getfunc(adr, size);
3080     return PyCData_FromBaseObj(type, src, index, adr);
3081 }
3082 
3083 /*
3084   Helper function for PyCData_set below.
3085 */
3086 static PyObject *
_PyCData_set(CDataObject * dst,PyObject * type,SETFUNC setfunc,PyObject * value,Py_ssize_t size,char * ptr)3087 _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
3088            Py_ssize_t size, char *ptr)
3089 {
3090     CDataObject *src;
3091     int err;
3092 
3093     if (setfunc)
3094         return setfunc(ptr, value, size);
3095 
3096     if (!CDataObject_Check(value)) {
3097         StgDictObject *dict = PyType_stgdict(type);
3098         if (dict && dict->setfunc)
3099             return dict->setfunc(ptr, value, size);
3100         /*
3101            If value is a tuple, we try to call the type with the tuple
3102            and use the result!
3103         */
3104         assert(PyType_Check(type));
3105         if (PyTuple_Check(value)) {
3106             PyObject *ob;
3107             PyObject *result;
3108             ob = PyObject_CallObject(type, value);
3109             if (ob == NULL) {
3110                 _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
3111                                   ((PyTypeObject *)type)->tp_name);
3112                 return NULL;
3113             }
3114             result = _PyCData_set(dst, type, setfunc, ob,
3115                                 size, ptr);
3116             Py_DECREF(ob);
3117             return result;
3118         } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
3119             *(void **)ptr = NULL;
3120             Py_RETURN_NONE;
3121         } else {
3122             PyErr_Format(PyExc_TypeError,
3123                          "expected %s instance, got %s",
3124                          ((PyTypeObject *)type)->tp_name,
3125                          Py_TYPE(value)->tp_name);
3126             return NULL;
3127         }
3128     }
3129     src = (CDataObject *)value;
3130 
3131     err = PyObject_IsInstance(value, type);
3132     if (err == -1)
3133         return NULL;
3134     if (err) {
3135         memcpy(ptr,
3136                src->b_ptr,
3137                size);
3138 
3139         if (PyCPointerTypeObject_Check(type)) {
3140             /* XXX */
3141         }
3142 
3143         value = GetKeepedObjects(src);
3144         if (value == NULL)
3145             return NULL;
3146 
3147         Py_INCREF(value);
3148         return value;
3149     }
3150 
3151     if (PyCPointerTypeObject_Check(type)
3152         && ArrayObject_Check(value)) {
3153         StgDictObject *p1, *p2;
3154         PyObject *keep;
3155         p1 = PyObject_stgdict(value);
3156         assert(p1); /* Cannot be NULL for array instances */
3157         p2 = PyType_stgdict(type);
3158         assert(p2); /* Cannot be NULL for pointer types */
3159 
3160         if (p1->proto != p2->proto) {
3161             PyErr_Format(PyExc_TypeError,
3162                          "incompatible types, %s instance instead of %s instance",
3163                          Py_TYPE(value)->tp_name,
3164                          ((PyTypeObject *)type)->tp_name);
3165             return NULL;
3166         }
3167         *(void **)ptr = src->b_ptr;
3168 
3169         keep = GetKeepedObjects(src);
3170         if (keep == NULL)
3171             return NULL;
3172 
3173         /*
3174           We are assigning an array object to a field which represents
3175           a pointer. This has the same effect as converting an array
3176           into a pointer. So, again, we have to keep the whole object
3177           pointed to (which is the array in this case) alive, and not
3178           only it's object list.  So we create a tuple, containing
3179           b_objects list PLUS the array itself, and return that!
3180         */
3181         return PyTuple_Pack(2, keep, value);
3182     }
3183     PyErr_Format(PyExc_TypeError,
3184                  "incompatible types, %s instance instead of %s instance",
3185                  Py_TYPE(value)->tp_name,
3186                  ((PyTypeObject *)type)->tp_name);
3187     return NULL;
3188 }
3189 
3190 /*
3191  * Set a slice in object 'dst', which has the type 'type',
3192  * to the value 'value'.
3193  */
3194 int
PyCData_set(PyObject * dst,PyObject * type,SETFUNC setfunc,PyObject * value,Py_ssize_t index,Py_ssize_t size,char * ptr)3195 PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
3196           Py_ssize_t index, Py_ssize_t size, char *ptr)
3197 {
3198     CDataObject *mem = (CDataObject *)dst;
3199     PyObject *result;
3200 
3201     if (!CDataObject_Check(dst)) {
3202         PyErr_SetString(PyExc_TypeError,
3203                         "not a ctype instance");
3204         return -1;
3205     }
3206 
3207     result = _PyCData_set(mem, type, setfunc, value,
3208                         size, ptr);
3209     if (result == NULL)
3210         return -1;
3211 
3212     /* KeepRef steals a refcount from it's last argument */
3213     /* If KeepRef fails, we are stumped.  The dst memory block has already
3214        been changed */
3215     return KeepRef(mem, index, result);
3216 }
3217 
3218 
3219 /******************************************************************/
3220 static PyObject *
GenericPyCData_new(PyTypeObject * type,PyObject * args,PyObject * kwds)3221 GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3222 {
3223     CDataObject *obj;
3224     StgDictObject *dict;
3225 
3226     dict = PyType_stgdict((PyObject *)type);
3227     if (!dict) {
3228         PyErr_SetString(PyExc_TypeError,
3229                         "abstract class");
3230         return NULL;
3231     }
3232     dict->flags |= DICTFLAG_FINAL;
3233 
3234     obj = (CDataObject *)type->tp_alloc(type, 0);
3235     if (!obj)
3236         return NULL;
3237 
3238     obj->b_base = NULL;
3239     obj->b_index = 0;
3240     obj->b_objects = NULL;
3241     obj->b_length = dict->length;
3242 
3243     if (-1 == PyCData_MallocBuffer(obj, dict)) {
3244         Py_DECREF(obj);
3245         return NULL;
3246     }
3247     return (PyObject *)obj;
3248 }
3249 /*****************************************************************/
3250 /*
3251   PyCFuncPtr_Type
3252 */
3253 
3254 static int
PyCFuncPtr_set_errcheck(PyCFuncPtrObject * self,PyObject * ob,void * Py_UNUSED (ignored))3255 PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
3256 {
3257     if (ob && !PyCallable_Check(ob)) {
3258         PyErr_SetString(PyExc_TypeError,
3259                         "the errcheck attribute must be callable");
3260         return -1;
3261     }
3262     Py_XINCREF(ob);
3263     Py_XSETREF(self->errcheck, ob);
3264     return 0;
3265 }
3266 
3267 static PyObject *
PyCFuncPtr_get_errcheck(PyCFuncPtrObject * self,void * Py_UNUSED (ignored))3268 PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
3269 {
3270     if (self->errcheck) {
3271         Py_INCREF(self->errcheck);
3272         return self->errcheck;
3273     }
3274     Py_RETURN_NONE;
3275 }
3276 
3277 static int
PyCFuncPtr_set_restype(PyCFuncPtrObject * self,PyObject * ob,void * Py_UNUSED (ignored))3278 PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
3279 {
3280     _Py_IDENTIFIER(_check_retval_);
3281     PyObject *checker, *oldchecker;
3282     if (ob == NULL) {
3283         oldchecker = self->checker;
3284         self->checker = NULL;
3285         Py_CLEAR(self->restype);
3286         Py_XDECREF(oldchecker);
3287         return 0;
3288     }
3289     if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
3290         PyErr_SetString(PyExc_TypeError,
3291                         "restype must be a type, a callable, or None");
3292         return -1;
3293     }
3294     if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, &checker) < 0) {
3295         return -1;
3296     }
3297     oldchecker = self->checker;
3298     self->checker = checker;
3299     Py_INCREF(ob);
3300     Py_XSETREF(self->restype, ob);
3301     Py_XDECREF(oldchecker);
3302     return 0;
3303 }
3304 
3305 static PyObject *
PyCFuncPtr_get_restype(PyCFuncPtrObject * self,void * Py_UNUSED (ignored))3306 PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
3307 {
3308     StgDictObject *dict;
3309     if (self->restype) {
3310         Py_INCREF(self->restype);
3311         return self->restype;
3312     }
3313     dict = PyObject_stgdict((PyObject *)self);
3314     assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3315     if (dict->restype) {
3316         Py_INCREF(dict->restype);
3317         return dict->restype;
3318     } else {
3319         Py_RETURN_NONE;
3320     }
3321 }
3322 
3323 static int
PyCFuncPtr_set_argtypes(PyCFuncPtrObject * self,PyObject * ob,void * Py_UNUSED (ignored))3324 PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
3325 {
3326     PyObject *converters;
3327 
3328     if (ob == NULL || ob == Py_None) {
3329         Py_CLEAR(self->converters);
3330         Py_CLEAR(self->argtypes);
3331     } else {
3332         converters = converters_from_argtypes(ob);
3333         if (!converters)
3334             return -1;
3335         Py_XSETREF(self->converters, converters);
3336         Py_INCREF(ob);
3337         Py_XSETREF(self->argtypes, ob);
3338     }
3339     return 0;
3340 }
3341 
3342 static PyObject *
PyCFuncPtr_get_argtypes(PyCFuncPtrObject * self,void * Py_UNUSED (ignored))3343 PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
3344 {
3345     StgDictObject *dict;
3346     if (self->argtypes) {
3347         Py_INCREF(self->argtypes);
3348         return self->argtypes;
3349     }
3350     dict = PyObject_stgdict((PyObject *)self);
3351     assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3352     if (dict->argtypes) {
3353         Py_INCREF(dict->argtypes);
3354         return dict->argtypes;
3355     } else {
3356         Py_RETURN_NONE;
3357     }
3358 }
3359 
3360 static PyGetSetDef PyCFuncPtr_getsets[] = {
3361     { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
3362       "a function to check for errors", NULL },
3363     { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
3364       "specify the result type", NULL },
3365     { "argtypes", (getter)PyCFuncPtr_get_argtypes,
3366       (setter)PyCFuncPtr_set_argtypes,
3367       "specify the argument types", NULL },
3368     { NULL, NULL }
3369 };
3370 
3371 #ifdef MS_WIN32
FindAddress(void * handle,const char * name,PyObject * type)3372 static PPROC FindAddress(void *handle, const char *name, PyObject *type)
3373 {
3374     PPROC address;
3375 #ifdef MS_WIN64
3376     /* win64 has no stdcall calling conv, so it should
3377        also not have the name mangling of it.
3378     */
3379     Py_BEGIN_ALLOW_THREADS
3380     address = (PPROC)GetProcAddress(handle, name);
3381     Py_END_ALLOW_THREADS
3382     return address;
3383 #else
3384     char *mangled_name;
3385     int i;
3386     StgDictObject *dict;
3387 
3388     Py_BEGIN_ALLOW_THREADS
3389     address = (PPROC)GetProcAddress(handle, name);
3390     Py_END_ALLOW_THREADS
3391     if (address)
3392         return address;
3393     if (((size_t)name & ~0xFFFF) == 0) {
3394         return NULL;
3395     }
3396 
3397     dict = PyType_stgdict((PyObject *)type);
3398     /* It should not happen that dict is NULL, but better be safe */
3399     if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
3400         return address;
3401 
3402     /* for stdcall, try mangled names:
3403        funcname -> _funcname@<n>
3404        where n is 0, 4, 8, 12, ..., 128
3405      */
3406     mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
3407     if (!mangled_name)
3408         return NULL;
3409     for (i = 0; i < 32; ++i) {
3410         sprintf(mangled_name, "_%s@%d", name, i*4);
3411         Py_BEGIN_ALLOW_THREADS
3412         address = (PPROC)GetProcAddress(handle, mangled_name);
3413         Py_END_ALLOW_THREADS
3414         if (address)
3415             return address;
3416     }
3417     return NULL;
3418 #endif
3419 }
3420 #endif
3421 
3422 /* Return 1 if usable, 0 else and exception set. */
3423 static int
_check_outarg_type(PyObject * arg,Py_ssize_t index)3424 _check_outarg_type(PyObject *arg, Py_ssize_t index)
3425 {
3426     StgDictObject *dict;
3427 
3428     if (PyCPointerTypeObject_Check(arg))
3429         return 1;
3430 
3431     if (PyCArrayTypeObject_Check(arg))
3432         return 1;
3433 
3434     dict = PyType_stgdict(arg);
3435     if (dict
3436         /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
3437         && PyUnicode_Check(dict->proto)
3438 /* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
3439         && (strchr("PzZ", PyUnicode_AsUTF8(dict->proto)[0]))) {
3440         return 1;
3441     }
3442 
3443     PyErr_Format(PyExc_TypeError,
3444                  "'out' parameter %d must be a pointer type, not %s",
3445                  Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
3446                  PyType_Check(arg) ?
3447                  ((PyTypeObject *)arg)->tp_name :
3448              Py_TYPE(arg)->tp_name);
3449     return 0;
3450 }
3451 
3452 /* Returns 1 on success, 0 on error */
3453 static int
_validate_paramflags(PyTypeObject * type,PyObject * paramflags)3454 _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
3455 {
3456     Py_ssize_t i, len;
3457     StgDictObject *dict;
3458     PyObject *argtypes;
3459 
3460     dict = PyType_stgdict((PyObject *)type);
3461     if (!dict) {
3462         PyErr_SetString(PyExc_TypeError,
3463                         "abstract class");
3464         return 0;
3465     }
3466     argtypes = dict->argtypes;
3467 
3468     if (paramflags == NULL || dict->argtypes == NULL)
3469         return 1;
3470 
3471     if (!PyTuple_Check(paramflags)) {
3472         PyErr_SetString(PyExc_TypeError,
3473                         "paramflags must be a tuple or None");
3474         return 0;
3475     }
3476 
3477     len = PyTuple_GET_SIZE(paramflags);
3478     if (len != PyTuple_GET_SIZE(dict->argtypes)) {
3479         PyErr_SetString(PyExc_ValueError,
3480                         "paramflags must have the same length as argtypes");
3481         return 0;
3482     }
3483 
3484     for (i = 0; i < len; ++i) {
3485         PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3486         int flag;
3487         char *name;
3488         PyObject *defval;
3489         PyObject *typ;
3490         if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) {
3491             PyErr_SetString(PyExc_TypeError,
3492                    "paramflags must be a sequence of (int [,string [,value]]) tuples");
3493             return 0;
3494         }
3495         typ = PyTuple_GET_ITEM(argtypes, i);
3496         switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3497         case 0:
3498         case PARAMFLAG_FIN:
3499         case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3500         case PARAMFLAG_FIN | PARAMFLAG_FOUT:
3501             break;
3502         case PARAMFLAG_FOUT:
3503             if (!_check_outarg_type(typ, i+1))
3504                 return 0;
3505             break;
3506         default:
3507             PyErr_Format(PyExc_TypeError,
3508                          "paramflag value %d not supported",
3509                          flag);
3510             return 0;
3511         }
3512     }
3513     return 1;
3514 }
3515 
3516 static int
_get_name(PyObject * obj,const char ** pname)3517 _get_name(PyObject *obj, const char **pname)
3518 {
3519 #ifdef MS_WIN32
3520     if (PyLong_Check(obj)) {
3521         /* We have to use MAKEINTRESOURCEA for Windows CE.
3522            Works on Windows as well, of course.
3523         */
3524         *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF);
3525         return 1;
3526     }
3527 #endif
3528     if (PyBytes_Check(obj)) {
3529         *pname = PyBytes_AS_STRING(obj);
3530         return *pname ? 1 : 0;
3531     }
3532     if (PyUnicode_Check(obj)) {
3533         *pname = PyUnicode_AsUTF8(obj);
3534         return *pname ? 1 : 0;
3535     }
3536     PyErr_SetString(PyExc_TypeError,
3537                     "function name must be string, bytes object or integer");
3538     return 0;
3539 }
3540 
3541 
3542 static PyObject *
PyCFuncPtr_FromDll(PyTypeObject * type,PyObject * args,PyObject * kwds)3543 PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
3544 {
3545     const char *name;
3546     int (* address)(void);
3547     PyObject *ftuple;
3548     PyObject *dll;
3549     PyObject *obj;
3550     PyCFuncPtrObject *self;
3551     void *handle;
3552     PyObject *paramflags = NULL;
3553 
3554     if (!PyArg_ParseTuple(args, "O|O", &ftuple, &paramflags))
3555         return NULL;
3556     if (paramflags == Py_None)
3557         paramflags = NULL;
3558 
3559     ftuple = PySequence_Tuple(ftuple);
3560     if (!ftuple)
3561         /* Here ftuple is a borrowed reference */
3562         return NULL;
3563 
3564     if (!PyArg_ParseTuple(ftuple, "O&O;illegal func_spec argument",
3565                           _get_name, &name, &dll))
3566     {
3567         Py_DECREF(ftuple);
3568         return NULL;
3569     }
3570 
3571 #ifdef MS_WIN32
3572     if (PySys_Audit("ctypes.dlsym",
3573                     ((uintptr_t)name & ~0xFFFF) ? "Os" : "On",
3574                     dll, name) < 0) {
3575         Py_DECREF(ftuple);
3576         return NULL;
3577     }
3578 #else
3579     if (PySys_Audit("ctypes.dlsym", "Os", dll, name) < 0) {
3580         Py_DECREF(ftuple);
3581         return NULL;
3582     }
3583 #endif
3584 
3585     obj = PyObject_GetAttrString(dll, "_handle");
3586     if (!obj) {
3587         Py_DECREF(ftuple);
3588         return NULL;
3589     }
3590     if (!PyLong_Check(obj)) {
3591         PyErr_SetString(PyExc_TypeError,
3592                         "the _handle attribute of the second argument must be an integer");
3593         Py_DECREF(ftuple);
3594         Py_DECREF(obj);
3595         return NULL;
3596     }
3597     handle = (void *)PyLong_AsVoidPtr(obj);
3598     Py_DECREF(obj);
3599     if (PyErr_Occurred()) {
3600         PyErr_SetString(PyExc_ValueError,
3601                         "could not convert the _handle attribute to a pointer");
3602         Py_DECREF(ftuple);
3603         return NULL;
3604     }
3605 
3606 #ifdef MS_WIN32
3607     address = FindAddress(handle, name, (PyObject *)type);
3608     if (!address) {
3609         if (!IS_INTRESOURCE(name))
3610             PyErr_Format(PyExc_AttributeError,
3611                          "function '%s' not found",
3612                          name);
3613         else
3614             PyErr_Format(PyExc_AttributeError,
3615                          "function ordinal %d not found",
3616                          (WORD)(size_t)name);
3617         Py_DECREF(ftuple);
3618         return NULL;
3619     }
3620 #else
3621     address = (PPROC)ctypes_dlsym(handle, name);
3622     if (!address) {
3623 #ifdef __CYGWIN__
3624 /* dlerror() isn't very helpful on cygwin */
3625         PyErr_Format(PyExc_AttributeError,
3626                      "function '%s' not found",
3627                      name);
3628 #else
3629         PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
3630 #endif
3631         Py_DECREF(ftuple);
3632         return NULL;
3633     }
3634 #endif
3635     if (!_validate_paramflags(type, paramflags)) {
3636         Py_DECREF(ftuple);
3637         return NULL;
3638     }
3639 
3640     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3641     if (!self) {
3642         Py_DECREF(ftuple);
3643         return NULL;
3644     }
3645 
3646     Py_XINCREF(paramflags);
3647     self->paramflags = paramflags;
3648 
3649     *(void **)self->b_ptr = address;
3650     Py_INCREF(dll);
3651     Py_DECREF(ftuple);
3652     if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
3653         Py_DECREF((PyObject *)self);
3654         return NULL;
3655     }
3656 
3657     Py_INCREF(self);
3658     self->callable = (PyObject *)self;
3659     return (PyObject *)self;
3660 }
3661 
3662 #ifdef MS_WIN32
3663 static PyObject *
PyCFuncPtr_FromVtblIndex(PyTypeObject * type,PyObject * args,PyObject * kwds)3664 PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
3665 {
3666     PyCFuncPtrObject *self;
3667     int index;
3668     char *name = NULL;
3669     PyObject *paramflags = NULL;
3670     GUID *iid = NULL;
3671     Py_ssize_t iid_len = 0;
3672 
3673     if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
3674         return NULL;
3675     if (paramflags == Py_None)
3676         paramflags = NULL;
3677 
3678     if (!_validate_paramflags(type, paramflags))
3679         return NULL;
3680 
3681     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3682     self->index = index + 0x1000;
3683     Py_XINCREF(paramflags);
3684     self->paramflags = paramflags;
3685     if (iid_len == sizeof(GUID))
3686         self->iid = iid;
3687     return (PyObject *)self;
3688 }
3689 #endif
3690 
3691 /*
3692   PyCFuncPtr_new accepts different argument lists in addition to the standard
3693   _basespec_ keyword arg:
3694 
3695   one argument form
3696   "i" - function address
3697   "O" - must be a callable, creates a C callable function
3698 
3699   two or more argument forms (the third argument is a paramflags tuple)
3700   "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
3701   "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
3702   "is|..." - vtable index, method name, creates callable calling COM vtbl
3703 */
3704 static PyObject *
PyCFuncPtr_new(PyTypeObject * type,PyObject * args,PyObject * kwds)3705 PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3706 {
3707     PyCFuncPtrObject *self;
3708     PyObject *callable;
3709     StgDictObject *dict;
3710     CThunkObject *thunk;
3711 
3712     if (PyTuple_GET_SIZE(args) == 0)
3713         return GenericPyCData_new(type, args, kwds);
3714 
3715     if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
3716         return PyCFuncPtr_FromDll(type, args, kwds);
3717 
3718 #ifdef MS_WIN32
3719     if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0)))
3720         return PyCFuncPtr_FromVtblIndex(type, args, kwds);
3721 #endif
3722 
3723     if (1 == PyTuple_GET_SIZE(args)
3724         && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
3725         CDataObject *ob;
3726         void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
3727         if (ptr == NULL && PyErr_Occurred())
3728             return NULL;
3729         ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
3730         if (ob == NULL)
3731             return NULL;
3732         *(void **)ob->b_ptr = ptr;
3733         return (PyObject *)ob;
3734     }
3735 
3736     if (!PyArg_ParseTuple(args, "O", &callable))
3737         return NULL;
3738     if (!PyCallable_Check(callable)) {
3739         PyErr_SetString(PyExc_TypeError,
3740                         "argument must be callable or integer function address");
3741         return NULL;
3742     }
3743 
3744     /* XXX XXX This would allow passing additional options.  For COM
3745        method *implementations*, we would probably want different
3746        behaviour than in 'normal' callback functions: return a HRESULT if
3747        an exception occurs in the callback, and print the traceback not
3748        only on the console, but also to OutputDebugString() or something
3749        like that.
3750     */
3751 /*
3752     if (kwds && _PyDict_GetItemIdWithError(kwds, &PyId_options)) {
3753         ...
3754     }
3755     else if (PyErr_Occurred()) {
3756         return NULL;
3757     }
3758 */
3759 
3760     dict = PyType_stgdict((PyObject *)type);
3761     /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
3762     if (!dict || !dict->argtypes) {
3763         PyErr_SetString(PyExc_TypeError,
3764                "cannot construct instance of this class:"
3765             " no argtypes");
3766         return NULL;
3767     }
3768 
3769     thunk = _ctypes_alloc_callback(callable,
3770                                   dict->argtypes,
3771                                   dict->restype,
3772                                   dict->flags);
3773     if (!thunk)
3774         return NULL;
3775 
3776     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3777     if (self == NULL) {
3778         Py_DECREF(thunk);
3779         return NULL;
3780     }
3781 
3782     Py_INCREF(callable);
3783     self->callable = callable;
3784 
3785     self->thunk = thunk;
3786     *(void **)self->b_ptr = (void *)thunk->pcl_exec;
3787 
3788     Py_INCREF((PyObject *)thunk); /* for KeepRef */
3789     if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3790         Py_DECREF((PyObject *)self);
3791         return NULL;
3792     }
3793     return (PyObject *)self;
3794 }
3795 
3796 
3797 /*
3798   _byref consumes a refcount to its argument
3799 */
3800 static PyObject *
_byref(PyObject * obj)3801 _byref(PyObject *obj)
3802 {
3803     PyCArgObject *parg;
3804     if (!CDataObject_Check(obj)) {
3805         PyErr_SetString(PyExc_TypeError,
3806                         "expected CData instance");
3807         return NULL;
3808     }
3809 
3810     parg = PyCArgObject_new();
3811     if (parg == NULL) {
3812         Py_DECREF(obj);
3813         return NULL;
3814     }
3815 
3816     parg->tag = 'P';
3817     parg->pffi_type = &ffi_type_pointer;
3818     parg->obj = obj;
3819     parg->value.p = ((CDataObject *)obj)->b_ptr;
3820     return (PyObject *)parg;
3821 }
3822 
3823 static PyObject *
_get_arg(int * pindex,PyObject * name,PyObject * defval,PyObject * inargs,PyObject * kwds)3824 _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
3825 {
3826     PyObject *v;
3827 
3828     if (*pindex < PyTuple_GET_SIZE(inargs)) {
3829         v = PyTuple_GET_ITEM(inargs, *pindex);
3830         ++*pindex;
3831         Py_INCREF(v);
3832         return v;
3833     }
3834     if (kwds && name) {
3835         v = PyDict_GetItemWithError(kwds, name);
3836         if (v) {
3837             ++*pindex;
3838             Py_INCREF(v);
3839             return v;
3840         }
3841         else if (PyErr_Occurred()) {
3842             return NULL;
3843         }
3844     }
3845     if (defval) {
3846         Py_INCREF(defval);
3847         return defval;
3848     }
3849     /* we can't currently emit a better error message */
3850     if (name)
3851         PyErr_Format(PyExc_TypeError,
3852                      "required argument '%S' missing", name);
3853     else
3854         PyErr_Format(PyExc_TypeError,
3855                      "not enough arguments");
3856     return NULL;
3857 }
3858 
3859 /*
3860  This function implements higher level functionality plus the ability to call
3861  functions with keyword arguments by looking at parameter flags.  parameter
3862  flags is a tuple of 1, 2 or 3-tuples.  The first entry in each is an integer
3863  specifying the direction of the data transfer for this parameter - 'in',
3864  'out' or 'inout' (zero means the same as 'in').  The second entry is the
3865  parameter name, and the third is the default value if the parameter is
3866  missing in the function call.
3867 
3868  This function builds and returns a new tuple 'callargs' which contains the
3869  parameters to use in the call.  Items on this tuple are copied from the
3870  'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
3871  'argtypes' tuple for 'out' parameters.  It also calculates numretvals which
3872  is the number of return values for the function, outmask/inoutmask are
3873  bitmasks containing indexes into the callargs tuple specifying which
3874  parameters have to be returned.  _build_result builds the return value of the
3875  function.
3876 */
3877 static PyObject *
_build_callargs(PyCFuncPtrObject * self,PyObject * argtypes,PyObject * inargs,PyObject * kwds,int * poutmask,int * pinoutmask,unsigned int * pnumretvals)3878 _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
3879                 PyObject *inargs, PyObject *kwds,
3880                 int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
3881 {
3882     PyObject *paramflags = self->paramflags;
3883     PyObject *callargs;
3884     StgDictObject *dict;
3885     Py_ssize_t i, len;
3886     int inargs_index = 0;
3887     /* It's a little bit difficult to determine how many arguments the
3888     function call requires/accepts.  For simplicity, we count the consumed
3889     args and compare this to the number of supplied args. */
3890     Py_ssize_t actual_args;
3891 
3892     *poutmask = 0;
3893     *pinoutmask = 0;
3894     *pnumretvals = 0;
3895 
3896     /* Trivial cases, where we either return inargs itself, or a slice of it. */
3897     if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
3898 #ifdef MS_WIN32
3899         if (self->index)
3900             return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
3901 #endif
3902         Py_INCREF(inargs);
3903         return inargs;
3904     }
3905 
3906     len = PyTuple_GET_SIZE(argtypes);
3907     callargs = PyTuple_New(len); /* the argument tuple we build */
3908     if (callargs == NULL)
3909         return NULL;
3910 
3911 #ifdef MS_WIN32
3912     /* For a COM method, skip the first arg */
3913     if (self->index) {
3914         inargs_index = 1;
3915     }
3916 #endif
3917     for (i = 0; i < len; ++i) {
3918         PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3919         PyObject *ob;
3920         unsigned int flag;
3921         PyObject *name = NULL;
3922         PyObject *defval = NULL;
3923 
3924         /* This way seems to be ~2 us faster than the PyArg_ParseTuple
3925            calls below. */
3926         /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
3927         Py_ssize_t tsize = PyTuple_GET_SIZE(item);
3928         flag = PyLong_AsUnsignedLongMask(PyTuple_GET_ITEM(item, 0));
3929         name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
3930         defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
3931 
3932         switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3933         case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3934             /* ['in', 'lcid'] parameter.  Always taken from defval,
3935              if given, else the integer 0. */
3936             if (defval == NULL)
3937                 defval = _PyLong_Zero;
3938             Py_INCREF(defval);
3939             PyTuple_SET_ITEM(callargs, i, defval);
3940             break;
3941         case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
3942             *pinoutmask |= (1 << i); /* mark as inout arg */
3943             (*pnumretvals)++;
3944             /* fall through */
3945         case 0:
3946         case PARAMFLAG_FIN:
3947             /* 'in' parameter.  Copy it from inargs. */
3948             ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
3949             if (ob == NULL)
3950                 goto error;
3951             PyTuple_SET_ITEM(callargs, i, ob);
3952             break;
3953         case PARAMFLAG_FOUT:
3954             /* XXX Refactor this code into a separate function. */
3955             /* 'out' parameter.
3956                argtypes[i] must be a POINTER to a c type.
3957 
3958                Cannot by supplied in inargs, but a defval will be used
3959                if available.  XXX Should we support getting it from kwds?
3960             */
3961             if (defval) {
3962                 /* XXX Using mutable objects as defval will
3963                    make the function non-threadsafe, unless we
3964                    copy the object in each invocation */
3965                 Py_INCREF(defval);
3966                 PyTuple_SET_ITEM(callargs, i, defval);
3967                 *poutmask |= (1 << i); /* mark as out arg */
3968                 (*pnumretvals)++;
3969                 break;
3970             }
3971             ob = PyTuple_GET_ITEM(argtypes, i);
3972             dict = PyType_stgdict(ob);
3973             if (dict == NULL) {
3974                 /* Cannot happen: _validate_paramflags()
3975                   would not accept such an object */
3976                 PyErr_Format(PyExc_RuntimeError,
3977                              "NULL stgdict unexpected");
3978                 goto error;
3979             }
3980             if (PyUnicode_Check(dict->proto)) {
3981                 PyErr_Format(
3982                     PyExc_TypeError,
3983                     "%s 'out' parameter must be passed as default value",
3984                     ((PyTypeObject *)ob)->tp_name);
3985                 goto error;
3986             }
3987             if (PyCArrayTypeObject_Check(ob))
3988                 ob = _PyObject_CallNoArg(ob);
3989             else
3990                 /* Create an instance of the pointed-to type */
3991                 ob = _PyObject_CallNoArg(dict->proto);
3992             /*
3993                XXX Is the following correct any longer?
3994                We must not pass a byref() to the array then but
3995                the array instance itself. Then, we cannot retrieve
3996                the result from the PyCArgObject.
3997             */
3998             if (ob == NULL)
3999                 goto error;
4000             /* The .from_param call that will occur later will pass this
4001                as a byref parameter. */
4002             PyTuple_SET_ITEM(callargs, i, ob);
4003             *poutmask |= (1 << i); /* mark as out arg */
4004             (*pnumretvals)++;
4005             break;
4006         default:
4007             PyErr_Format(PyExc_ValueError,
4008                          "paramflag %u not yet implemented", flag);
4009             goto error;
4010             break;
4011         }
4012     }
4013 
4014     /* We have counted the arguments we have consumed in 'inargs_index'.  This
4015        must be the same as len(inargs) + len(kwds), otherwise we have
4016        either too much or not enough arguments. */
4017 
4018     actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_GET_SIZE(kwds) : 0);
4019     if (actual_args != inargs_index) {
4020         /* When we have default values or named parameters, this error
4021            message is misleading.  See unittests/test_paramflags.py
4022          */
4023         PyErr_Format(PyExc_TypeError,
4024                      "call takes exactly %d arguments (%zd given)",
4025                      inargs_index, actual_args);
4026         goto error;
4027     }
4028 
4029     /* outmask is a bitmask containing indexes into callargs.  Items at
4030        these indexes contain values to return.
4031      */
4032     return callargs;
4033   error:
4034     Py_DECREF(callargs);
4035     return NULL;
4036 }
4037 
4038 /* See also:
4039    http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
4040 */
4041 /*
4042   Build return value of a function.
4043 
4044   Consumes the refcount on result and callargs.
4045 */
4046 static PyObject *
_build_result(PyObject * result,PyObject * callargs,int outmask,int inoutmask,unsigned int numretvals)4047 _build_result(PyObject *result, PyObject *callargs,
4048               int outmask, int inoutmask, unsigned int numretvals)
4049 {
4050     unsigned int i, index;
4051     int bit;
4052     PyObject *tup = NULL;
4053 
4054     if (callargs == NULL)
4055         return result;
4056     if (result == NULL || numretvals == 0) {
4057         Py_DECREF(callargs);
4058         return result;
4059     }
4060     Py_DECREF(result);
4061 
4062     /* tup will not be allocated if numretvals == 1 */
4063     /* allocate tuple to hold the result */
4064     if (numretvals > 1) {
4065         tup = PyTuple_New(numretvals);
4066         if (tup == NULL) {
4067             Py_DECREF(callargs);
4068             return NULL;
4069         }
4070     }
4071 
4072     index = 0;
4073     for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
4074         PyObject *v;
4075         if (bit & inoutmask) {
4076             v = PyTuple_GET_ITEM(callargs, i);
4077             Py_INCREF(v);
4078             if (numretvals == 1) {
4079                 Py_DECREF(callargs);
4080                 return v;
4081             }
4082             PyTuple_SET_ITEM(tup, index, v);
4083             index++;
4084         } else if (bit & outmask) {
4085             _Py_IDENTIFIER(__ctypes_from_outparam__);
4086 
4087             v = PyTuple_GET_ITEM(callargs, i);
4088             v = _PyObject_CallMethodIdNoArgs(v, &PyId___ctypes_from_outparam__);
4089             if (v == NULL || numretvals == 1) {
4090                 Py_DECREF(callargs);
4091                 return v;
4092             }
4093             PyTuple_SET_ITEM(tup, index, v);
4094             index++;
4095         }
4096         if (index == numretvals)
4097             break;
4098     }
4099 
4100     Py_DECREF(callargs);
4101     return tup;
4102 }
4103 
4104 static PyObject *
PyCFuncPtr_call(PyCFuncPtrObject * self,PyObject * inargs,PyObject * kwds)4105 PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
4106 {
4107     PyObject *restype;
4108     PyObject *converters;
4109     PyObject *checker;
4110     PyObject *argtypes;
4111     StgDictObject *dict = PyObject_stgdict((PyObject *)self);
4112     PyObject *result;
4113     PyObject *callargs;
4114     PyObject *errcheck;
4115 #ifdef MS_WIN32
4116     IUnknown *piunk = NULL;
4117 #endif
4118     void *pProc = NULL;
4119 
4120     int inoutmask;
4121     int outmask;
4122     unsigned int numretvals;
4123 
4124     assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
4125     restype = self->restype ? self->restype : dict->restype;
4126     converters = self->converters ? self->converters : dict->converters;
4127     checker = self->checker ? self->checker : dict->checker;
4128     argtypes = self->argtypes ? self->argtypes : dict->argtypes;
4129 /* later, we probably want to have an errcheck field in stgdict */
4130     errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
4131 
4132 
4133     pProc = *(void **)self->b_ptr;
4134 #ifdef MS_WIN32
4135     if (self->index) {
4136         /* It's a COM method */
4137         CDataObject *this;
4138         this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
4139         if (!this) {
4140             PyErr_SetString(PyExc_ValueError,
4141                             "native com method call without 'this' parameter");
4142             return NULL;
4143         }
4144         if (!CDataObject_Check(this)) {
4145             PyErr_SetString(PyExc_TypeError,
4146                             "Expected a COM this pointer as first argument");
4147             return NULL;
4148         }
4149         /* there should be more checks? No, in Python */
4150         /* First arg is a pointer to an interface instance */
4151         if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
4152             PyErr_SetString(PyExc_ValueError,
4153                             "NULL COM pointer access");
4154             return NULL;
4155         }
4156         piunk = *(IUnknown **)this->b_ptr;
4157         if (NULL == piunk->lpVtbl) {
4158             PyErr_SetString(PyExc_ValueError,
4159                             "COM method call without VTable");
4160             return NULL;
4161         }
4162         pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
4163     }
4164 #endif
4165     callargs = _build_callargs(self, argtypes,
4166                                inargs, kwds,
4167                                &outmask, &inoutmask, &numretvals);
4168     if (callargs == NULL)
4169         return NULL;
4170 
4171     if (converters) {
4172         int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
4173                                         Py_ssize_t, int);
4174         int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
4175                                       Py_ssize_t, int);
4176 
4177         if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
4178             /* For cdecl functions, we allow more actual arguments
4179                than the length of the argtypes tuple.
4180             */
4181             if (required > actual) {
4182                 Py_DECREF(callargs);
4183                 PyErr_Format(PyExc_TypeError,
4184               "this function takes at least %d argument%s (%d given)",
4185                                  required,
4186                                  required == 1 ? "" : "s",
4187                                  actual);
4188                 return NULL;
4189             }
4190         } else if (required != actual) {
4191             Py_DECREF(callargs);
4192             PyErr_Format(PyExc_TypeError,
4193                  "this function takes %d argument%s (%d given)",
4194                      required,
4195                      required == 1 ? "" : "s",
4196                      actual);
4197             return NULL;
4198         }
4199     }
4200 
4201     result = _ctypes_callproc(pProc,
4202                        callargs,
4203 #ifdef MS_WIN32
4204                        piunk,
4205                        self->iid,
4206 #endif
4207                        dict->flags,
4208                        converters,
4209                        restype,
4210                        checker);
4211 /* The 'errcheck' protocol */
4212     if (result != NULL && errcheck) {
4213         PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
4214                                                    result,
4215                                                    self,
4216                                                    callargs,
4217                                                    NULL);
4218         /* If the errcheck function failed, return NULL.
4219            If the errcheck function returned callargs unchanged,
4220            continue normal processing.
4221            If the errcheck function returned something else,
4222            use that as result.
4223         */
4224         if (v == NULL || v != callargs) {
4225             Py_DECREF(result);
4226             Py_DECREF(callargs);
4227             return v;
4228         }
4229         Py_DECREF(v);
4230     }
4231 
4232     return _build_result(result, callargs,
4233                          outmask, inoutmask, numretvals);
4234 }
4235 
4236 static int
PyCFuncPtr_traverse(PyCFuncPtrObject * self,visitproc visit,void * arg)4237 PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
4238 {
4239     Py_VISIT(self->callable);
4240     Py_VISIT(self->restype);
4241     Py_VISIT(self->checker);
4242     Py_VISIT(self->errcheck);
4243     Py_VISIT(self->argtypes);
4244     Py_VISIT(self->converters);
4245     Py_VISIT(self->paramflags);
4246     Py_VISIT(self->thunk);
4247     return PyCData_traverse((CDataObject *)self, visit, arg);
4248 }
4249 
4250 static int
PyCFuncPtr_clear(PyCFuncPtrObject * self)4251 PyCFuncPtr_clear(PyCFuncPtrObject *self)
4252 {
4253     Py_CLEAR(self->callable);
4254     Py_CLEAR(self->restype);
4255     Py_CLEAR(self->checker);
4256     Py_CLEAR(self->errcheck);
4257     Py_CLEAR(self->argtypes);
4258     Py_CLEAR(self->converters);
4259     Py_CLEAR(self->paramflags);
4260     Py_CLEAR(self->thunk);
4261     return PyCData_clear((CDataObject *)self);
4262 }
4263 
4264 static void
PyCFuncPtr_dealloc(PyCFuncPtrObject * self)4265 PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
4266 {
4267     PyCFuncPtr_clear(self);
4268     Py_TYPE(self)->tp_free((PyObject *)self);
4269 }
4270 
4271 static PyObject *
PyCFuncPtr_repr(PyCFuncPtrObject * self)4272 PyCFuncPtr_repr(PyCFuncPtrObject *self)
4273 {
4274 #ifdef MS_WIN32
4275     if (self->index)
4276         return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
4277                                    self->index - 0x1000,
4278                                    Py_TYPE(self)->tp_name,
4279                                    self);
4280 #endif
4281     return PyUnicode_FromFormat("<%s object at %p>",
4282                                Py_TYPE(self)->tp_name,
4283                                self);
4284 }
4285 
4286 static int
PyCFuncPtr_bool(PyCFuncPtrObject * self)4287 PyCFuncPtr_bool(PyCFuncPtrObject *self)
4288 {
4289     return ((*(void **)self->b_ptr != NULL)
4290 #ifdef MS_WIN32
4291         || (self->index != 0)
4292 #endif
4293         );
4294 }
4295 
4296 static PyNumberMethods PyCFuncPtr_as_number = {
4297     0, /* nb_add */
4298     0, /* nb_subtract */
4299     0, /* nb_multiply */
4300     0, /* nb_remainder */
4301     0, /* nb_divmod */
4302     0, /* nb_power */
4303     0, /* nb_negative */
4304     0, /* nb_positive */
4305     0, /* nb_absolute */
4306     (inquiry)PyCFuncPtr_bool, /* nb_bool */
4307 };
4308 
4309 PyTypeObject PyCFuncPtr_Type = {
4310     PyVarObject_HEAD_INIT(NULL, 0)
4311     "_ctypes.PyCFuncPtr",
4312     sizeof(PyCFuncPtrObject),                           /* tp_basicsize */
4313     0,                                          /* tp_itemsize */
4314     (destructor)PyCFuncPtr_dealloc,             /* tp_dealloc */
4315     0,                                          /* tp_vectorcall_offset */
4316     0,                                          /* tp_getattr */
4317     0,                                          /* tp_setattr */
4318     0,                                          /* tp_as_async */
4319     (reprfunc)PyCFuncPtr_repr,                  /* tp_repr */
4320     &PyCFuncPtr_as_number,                      /* tp_as_number */
4321     0,                                          /* tp_as_sequence */
4322     0,                                          /* tp_as_mapping */
4323     0,                                          /* tp_hash */
4324     (ternaryfunc)PyCFuncPtr_call,               /* tp_call */
4325     0,                                          /* tp_str */
4326     0,                                          /* tp_getattro */
4327     0,                                          /* tp_setattro */
4328     &PyCData_as_buffer,                         /* tp_as_buffer */
4329     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4330     "Function Pointer",                         /* tp_doc */
4331     (traverseproc)PyCFuncPtr_traverse,          /* tp_traverse */
4332     (inquiry)PyCFuncPtr_clear,                  /* tp_clear */
4333     0,                                          /* tp_richcompare */
4334     0,                                          /* tp_weaklistoffset */
4335     0,                                          /* tp_iter */
4336     0,                                          /* tp_iternext */
4337     0,                                          /* tp_methods */
4338     0,                                          /* tp_members */
4339     PyCFuncPtr_getsets,                         /* tp_getset */
4340     0,                                          /* tp_base */
4341     0,                                          /* tp_dict */
4342     0,                                          /* tp_descr_get */
4343     0,                                          /* tp_descr_set */
4344     0,                                          /* tp_dictoffset */
4345     0,                                          /* tp_init */
4346     0,                                          /* tp_alloc */
4347     PyCFuncPtr_new,                             /* tp_new */
4348     0,                                          /* tp_free */
4349 };
4350 
4351 /*****************************************************************/
4352 /*
4353   Struct_Type
4354 */
4355 /*
4356   This function is called to initialize a Structure or Union with positional
4357   arguments. It calls itself recursively for all Structure or Union base
4358   classes, then retrieves the _fields_ member to associate the argument
4359   position with the correct field name.
4360 
4361   Returns -1 on error, or the index of next argument on success.
4362  */
4363 static Py_ssize_t
_init_pos_args(PyObject * self,PyTypeObject * type,PyObject * args,PyObject * kwds,Py_ssize_t index)4364 _init_pos_args(PyObject *self, PyTypeObject *type,
4365                PyObject *args, PyObject *kwds,
4366                Py_ssize_t index)
4367 {
4368     StgDictObject *dict;
4369     PyObject *fields;
4370     Py_ssize_t i;
4371     _Py_IDENTIFIER(_fields_);
4372 
4373     if (PyType_stgdict((PyObject *)type->tp_base)) {
4374         index = _init_pos_args(self, type->tp_base,
4375                                args, kwds,
4376                                index);
4377         if (index == -1)
4378             return -1;
4379     }
4380 
4381     dict = PyType_stgdict((PyObject *)type);
4382     fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_);
4383     if (fields == NULL) {
4384         if (PyErr_Occurred()) {
4385             return -1;
4386         }
4387         return index;
4388     }
4389 
4390     for (i = 0;
4391          i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
4392          ++i) {
4393         PyObject *pair = PySequence_GetItem(fields, i);
4394         PyObject *name, *val;
4395         int res;
4396         if (!pair)
4397             return -1;
4398         name = PySequence_GetItem(pair, 0);
4399         if (!name) {
4400             Py_DECREF(pair);
4401             return -1;
4402         }
4403         val = PyTuple_GET_ITEM(args, i + index);
4404         if (kwds) {
4405             if (PyDict_GetItemWithError(kwds, name)) {
4406                 PyErr_Format(PyExc_TypeError,
4407                             "duplicate values for field %R",
4408                             name);
4409                 Py_DECREF(pair);
4410                 Py_DECREF(name);
4411                 return -1;
4412             }
4413             else if (PyErr_Occurred()) {
4414                 Py_DECREF(pair);
4415                 Py_DECREF(name);
4416                 return -1;
4417             }
4418         }
4419 
4420         res = PyObject_SetAttr(self, name, val);
4421         Py_DECREF(pair);
4422         Py_DECREF(name);
4423         if (res == -1)
4424             return -1;
4425     }
4426     return index + dict->length;
4427 }
4428 
4429 static int
Struct_init(PyObject * self,PyObject * args,PyObject * kwds)4430 Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
4431 {
4432 /* Optimization possible: Store the attribute names _fields_[x][0]
4433  * in C accessible fields somewhere ?
4434  */
4435     if (!PyTuple_Check(args)) {
4436         PyErr_SetString(PyExc_TypeError,
4437                         "args not a tuple?");
4438         return -1;
4439     }
4440     if (PyTuple_GET_SIZE(args)) {
4441         Py_ssize_t res = _init_pos_args(self, Py_TYPE(self),
4442                                         args, kwds, 0);
4443         if (res == -1)
4444             return -1;
4445         if (res < PyTuple_GET_SIZE(args)) {
4446             PyErr_SetString(PyExc_TypeError,
4447                             "too many initializers");
4448             return -1;
4449         }
4450     }
4451 
4452     if (kwds) {
4453         PyObject *key, *value;
4454         Py_ssize_t pos = 0;
4455         while(PyDict_Next(kwds, &pos, &key, &value)) {
4456             if (-1 == PyObject_SetAttr(self, key, value))
4457                 return -1;
4458         }
4459     }
4460     return 0;
4461 }
4462 
4463 static PyTypeObject Struct_Type = {
4464     PyVarObject_HEAD_INIT(NULL, 0)
4465     "_ctypes.Structure",
4466     sizeof(CDataObject),                        /* tp_basicsize */
4467     0,                                          /* tp_itemsize */
4468     0,                                          /* tp_dealloc */
4469     0,                                          /* tp_vectorcall_offset */
4470     0,                                          /* tp_getattr */
4471     0,                                          /* tp_setattr */
4472     0,                                          /* tp_as_async */
4473     0,                                          /* tp_repr */
4474     0,                                          /* tp_as_number */
4475     0,                                          /* tp_as_sequence */
4476     0,                                          /* tp_as_mapping */
4477     0,                                          /* tp_hash */
4478     0,                                          /* tp_call */
4479     0,                                          /* tp_str */
4480     0,                                          /* tp_getattro */
4481     0,                                          /* tp_setattro */
4482     &PyCData_as_buffer,                         /* tp_as_buffer */
4483     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4484     "Structure base class",                     /* tp_doc */
4485     (traverseproc)PyCData_traverse,             /* tp_traverse */
4486     (inquiry)PyCData_clear,                     /* tp_clear */
4487     0,                                          /* tp_richcompare */
4488     0,                                          /* tp_weaklistoffset */
4489     0,                                          /* tp_iter */
4490     0,                                          /* tp_iternext */
4491     0,                                          /* tp_methods */
4492     0,                                          /* tp_members */
4493     0,                                          /* tp_getset */
4494     0,                                          /* tp_base */
4495     0,                                          /* tp_dict */
4496     0,                                          /* tp_descr_get */
4497     0,                                          /* tp_descr_set */
4498     0,                                          /* tp_dictoffset */
4499     Struct_init,                                /* tp_init */
4500     0,                                          /* tp_alloc */
4501     GenericPyCData_new,                         /* tp_new */
4502     0,                                          /* tp_free */
4503 };
4504 
4505 static PyTypeObject Union_Type = {
4506     PyVarObject_HEAD_INIT(NULL, 0)
4507     "_ctypes.Union",
4508     sizeof(CDataObject),                        /* tp_basicsize */
4509     0,                                          /* tp_itemsize */
4510     0,                                          /* tp_dealloc */
4511     0,                                          /* tp_vectorcall_offset */
4512     0,                                          /* tp_getattr */
4513     0,                                          /* tp_setattr */
4514     0,                                          /* tp_as_async */
4515     0,                                          /* tp_repr */
4516     0,                                          /* tp_as_number */
4517     0,                                          /* tp_as_sequence */
4518     0,                                          /* tp_as_mapping */
4519     0,                                          /* tp_hash */
4520     0,                                          /* tp_call */
4521     0,                                          /* tp_str */
4522     0,                                          /* tp_getattro */
4523     0,                                          /* tp_setattro */
4524     &PyCData_as_buffer,                         /* tp_as_buffer */
4525     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4526     "Union base class",                         /* tp_doc */
4527     (traverseproc)PyCData_traverse,             /* tp_traverse */
4528     (inquiry)PyCData_clear,                     /* tp_clear */
4529     0,                                          /* tp_richcompare */
4530     0,                                          /* tp_weaklistoffset */
4531     0,                                          /* tp_iter */
4532     0,                                          /* tp_iternext */
4533     0,                                          /* tp_methods */
4534     0,                                          /* tp_members */
4535     0,                                          /* tp_getset */
4536     0,                                          /* tp_base */
4537     0,                                          /* tp_dict */
4538     0,                                          /* tp_descr_get */
4539     0,                                          /* tp_descr_set */
4540     0,                                          /* tp_dictoffset */
4541     Struct_init,                                /* tp_init */
4542     0,                                          /* tp_alloc */
4543     GenericPyCData_new,                         /* tp_new */
4544     0,                                          /* tp_free */
4545 };
4546 
4547 
4548 /******************************************************************/
4549 /*
4550   PyCArray_Type
4551 */
4552 static int
Array_init(CDataObject * self,PyObject * args,PyObject * kw)4553 Array_init(CDataObject *self, PyObject *args, PyObject *kw)
4554 {
4555     Py_ssize_t i;
4556     Py_ssize_t n;
4557 
4558     if (!PyTuple_Check(args)) {
4559         PyErr_SetString(PyExc_TypeError,
4560                         "args not a tuple?");
4561         return -1;
4562     }
4563     n = PyTuple_GET_SIZE(args);
4564     for (i = 0; i < n; ++i) {
4565         PyObject *v;
4566         v = PyTuple_GET_ITEM(args, i);
4567         if (-1 == PySequence_SetItem((PyObject *)self, i, v))
4568             return -1;
4569     }
4570     return 0;
4571 }
4572 
4573 static PyObject *
Array_item(PyObject * myself,Py_ssize_t index)4574 Array_item(PyObject *myself, Py_ssize_t index)
4575 {
4576     CDataObject *self = (CDataObject *)myself;
4577     Py_ssize_t offset, size;
4578     StgDictObject *stgdict;
4579 
4580 
4581     if (index < 0 || index >= self->b_length) {
4582         PyErr_SetString(PyExc_IndexError,
4583                         "invalid index");
4584         return NULL;
4585     }
4586 
4587     stgdict = PyObject_stgdict((PyObject *)self);
4588     assert(stgdict); /* Cannot be NULL for array instances */
4589     /* Would it be clearer if we got the item size from
4590        stgdict->proto's stgdict?
4591     */
4592     size = stgdict->size / stgdict->length;
4593     offset = index * size;
4594 
4595     return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
4596                      index, size, self->b_ptr + offset);
4597 }
4598 
4599 static PyObject *
Array_subscript(PyObject * myself,PyObject * item)4600 Array_subscript(PyObject *myself, PyObject *item)
4601 {
4602     CDataObject *self = (CDataObject *)myself;
4603 
4604     if (PyIndex_Check(item)) {
4605         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4606 
4607         if (i == -1 && PyErr_Occurred())
4608             return NULL;
4609         if (i < 0)
4610             i += self->b_length;
4611         return Array_item(myself, i);
4612     }
4613     else if (PySlice_Check(item)) {
4614         StgDictObject *stgdict, *itemdict;
4615         PyObject *proto;
4616         PyObject *np;
4617         Py_ssize_t start, stop, step, slicelen, i;
4618         size_t cur;
4619 
4620         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
4621             return NULL;
4622         }
4623         slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step);
4624 
4625         stgdict = PyObject_stgdict((PyObject *)self);
4626         assert(stgdict); /* Cannot be NULL for array object instances */
4627         proto = stgdict->proto;
4628         itemdict = PyType_stgdict(proto);
4629         assert(itemdict); /* proto is the item type of the array, a
4630                              ctypes type, so this cannot be NULL */
4631 
4632         if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4633             char *ptr = (char *)self->b_ptr;
4634             char *dest;
4635 
4636             if (slicelen <= 0)
4637                 return PyBytes_FromStringAndSize("", 0);
4638             if (step == 1) {
4639                 return PyBytes_FromStringAndSize(ptr + start,
4640                                                  slicelen);
4641             }
4642             dest = (char *)PyMem_Malloc(slicelen);
4643 
4644             if (dest == NULL)
4645                 return PyErr_NoMemory();
4646 
4647             for (cur = start, i = 0; i < slicelen;
4648                  cur += step, i++) {
4649                 dest[i] = ptr[cur];
4650             }
4651 
4652             np = PyBytes_FromStringAndSize(dest, slicelen);
4653             PyMem_Free(dest);
4654             return np;
4655         }
4656 #ifdef CTYPES_UNICODE
4657         if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4658             wchar_t *ptr = (wchar_t *)self->b_ptr;
4659             wchar_t *dest;
4660 
4661             if (slicelen <= 0)
4662                 return PyUnicode_New(0, 0);
4663             if (step == 1) {
4664                 return PyUnicode_FromWideChar(ptr + start,
4665                                               slicelen);
4666             }
4667 
4668             dest = PyMem_New(wchar_t, slicelen);
4669             if (dest == NULL) {
4670                 PyErr_NoMemory();
4671                 return NULL;
4672             }
4673 
4674             for (cur = start, i = 0; i < slicelen;
4675                  cur += step, i++) {
4676                 dest[i] = ptr[cur];
4677             }
4678 
4679             np = PyUnicode_FromWideChar(dest, slicelen);
4680             PyMem_Free(dest);
4681             return np;
4682         }
4683 #endif
4684 
4685         np = PyList_New(slicelen);
4686         if (np == NULL)
4687             return NULL;
4688 
4689         for (cur = start, i = 0; i < slicelen;
4690              cur += step, i++) {
4691             PyObject *v = Array_item(myself, cur);
4692             if (v == NULL) {
4693                 Py_DECREF(np);
4694                 return NULL;
4695             }
4696             PyList_SET_ITEM(np, i, v);
4697         }
4698         return np;
4699     }
4700     else {
4701         PyErr_SetString(PyExc_TypeError,
4702                         "indices must be integers");
4703         return NULL;
4704     }
4705 
4706 }
4707 
4708 static int
Array_ass_item(PyObject * myself,Py_ssize_t index,PyObject * value)4709 Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
4710 {
4711     CDataObject *self = (CDataObject *)myself;
4712     Py_ssize_t size, offset;
4713     StgDictObject *stgdict;
4714     char *ptr;
4715 
4716     if (value == NULL) {
4717         PyErr_SetString(PyExc_TypeError,
4718                         "Array does not support item deletion");
4719         return -1;
4720     }
4721 
4722     stgdict = PyObject_stgdict((PyObject *)self);
4723     assert(stgdict); /* Cannot be NULL for array object instances */
4724     if (index < 0 || index >= stgdict->length) {
4725         PyErr_SetString(PyExc_IndexError,
4726                         "invalid index");
4727         return -1;
4728     }
4729     size = stgdict->size / stgdict->length;
4730     offset = index * size;
4731     ptr = self->b_ptr + offset;
4732 
4733     return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
4734                      index, size, ptr);
4735 }
4736 
4737 static int
Array_ass_subscript(PyObject * myself,PyObject * item,PyObject * value)4738 Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value)
4739 {
4740     CDataObject *self = (CDataObject *)myself;
4741 
4742     if (value == NULL) {
4743         PyErr_SetString(PyExc_TypeError,
4744                         "Array does not support item deletion");
4745         return -1;
4746     }
4747 
4748     if (PyIndex_Check(item)) {
4749         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4750 
4751         if (i == -1 && PyErr_Occurred())
4752             return -1;
4753         if (i < 0)
4754             i += self->b_length;
4755         return Array_ass_item(myself, i, value);
4756     }
4757     else if (PySlice_Check(item)) {
4758         Py_ssize_t start, stop, step, slicelen, otherlen, i;
4759         size_t cur;
4760 
4761         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
4762             return -1;
4763         }
4764         slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step);
4765         if ((step < 0 && start < stop) ||
4766             (step > 0 && start > stop))
4767             stop = start;
4768 
4769         otherlen = PySequence_Length(value);
4770         if (otherlen != slicelen) {
4771             PyErr_SetString(PyExc_ValueError,
4772                 "Can only assign sequence of same size");
4773             return -1;
4774         }
4775         for (cur = start, i = 0; i < otherlen; cur += step, i++) {
4776             PyObject *item = PySequence_GetItem(value, i);
4777             int result;
4778             if (item == NULL)
4779                 return -1;
4780             result = Array_ass_item(myself, cur, item);
4781             Py_DECREF(item);
4782             if (result == -1)
4783                 return -1;
4784         }
4785         return 0;
4786     }
4787     else {
4788         PyErr_SetString(PyExc_TypeError,
4789                         "indices must be integer");
4790         return -1;
4791     }
4792 }
4793 
4794 static Py_ssize_t
Array_length(PyObject * myself)4795 Array_length(PyObject *myself)
4796 {
4797     CDataObject *self = (CDataObject *)myself;
4798     return self->b_length;
4799 }
4800 
4801 static PyMethodDef Array_methods[] = {
4802     {"__class_getitem__",    (PyCFunction)Py_GenericAlias,
4803     METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
4804     { NULL, NULL }
4805 };
4806 
4807 static PySequenceMethods Array_as_sequence = {
4808     Array_length,                               /* sq_length; */
4809     0,                                          /* sq_concat; */
4810     0,                                          /* sq_repeat; */
4811     Array_item,                                 /* sq_item; */
4812     0,                                          /* sq_slice; */
4813     Array_ass_item,                             /* sq_ass_item; */
4814     0,                                          /* sq_ass_slice; */
4815     0,                                          /* sq_contains; */
4816 
4817     0,                                          /* sq_inplace_concat; */
4818     0,                                          /* sq_inplace_repeat; */
4819 };
4820 
4821 static PyMappingMethods Array_as_mapping = {
4822     Array_length,
4823     Array_subscript,
4824     Array_ass_subscript,
4825 };
4826 
4827 PyTypeObject PyCArray_Type = {
4828     PyVarObject_HEAD_INIT(NULL, 0)
4829     "_ctypes.Array",
4830     sizeof(CDataObject),                        /* tp_basicsize */
4831     0,                                          /* tp_itemsize */
4832     0,                                          /* tp_dealloc */
4833     0,                                          /* tp_vectorcall_offset */
4834     0,                                          /* tp_getattr */
4835     0,                                          /* tp_setattr */
4836     0,                                          /* tp_as_async */
4837     0,                                          /* tp_repr */
4838     0,                                          /* tp_as_number */
4839     &Array_as_sequence,                         /* tp_as_sequence */
4840     &Array_as_mapping,                          /* tp_as_mapping */
4841     0,                                          /* tp_hash */
4842     0,                                          /* tp_call */
4843     0,                                          /* tp_str */
4844     0,                                          /* tp_getattro */
4845     0,                                          /* tp_setattro */
4846     &PyCData_as_buffer,                         /* tp_as_buffer */
4847     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4848     "XXX to be provided",                       /* tp_doc */
4849     (traverseproc)PyCData_traverse,             /* tp_traverse */
4850     (inquiry)PyCData_clear,                     /* tp_clear */
4851     0,                                          /* tp_richcompare */
4852     0,                                          /* tp_weaklistoffset */
4853     0,                                          /* tp_iter */
4854     0,                                          /* tp_iternext */
4855     Array_methods,                              /* tp_methods */
4856     0,                                          /* tp_members */
4857     0,                                          /* tp_getset */
4858     0,                                          /* tp_base */
4859     0,                                          /* tp_dict */
4860     0,                                          /* tp_descr_get */
4861     0,                                          /* tp_descr_set */
4862     0,                                          /* tp_dictoffset */
4863     (initproc)Array_init,                       /* tp_init */
4864     0,                                          /* tp_alloc */
4865     GenericPyCData_new,                         /* tp_new */
4866     0,                                          /* tp_free */
4867 };
4868 
4869 PyObject *
PyCArrayType_from_ctype(PyObject * itemtype,Py_ssize_t length)4870 PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
4871 {
4872     static PyObject *cache;
4873     PyObject *key;
4874     PyObject *result;
4875     char name[256];
4876     PyObject *len;
4877 
4878     if (cache == NULL) {
4879         cache = PyDict_New();
4880         if (cache == NULL)
4881             return NULL;
4882     }
4883     len = PyLong_FromSsize_t(length);
4884     if (len == NULL)
4885         return NULL;
4886     key = PyTuple_Pack(2, itemtype, len);
4887     Py_DECREF(len);
4888     if (!key)
4889         return NULL;
4890     result = PyDict_GetItemProxy(cache, key);
4891     if (result) {
4892         Py_INCREF(result);
4893         Py_DECREF(key);
4894         return result;
4895     }
4896     else if (PyErr_Occurred()) {
4897         Py_DECREF(key);
4898         return NULL;
4899     }
4900 
4901     if (!PyType_Check(itemtype)) {
4902         PyErr_SetString(PyExc_TypeError,
4903                         "Expected a type object");
4904         Py_DECREF(key);
4905         return NULL;
4906     }
4907 #ifdef MS_WIN64
4908     sprintf(name, "%.200s_Array_%Id",
4909         ((PyTypeObject *)itemtype)->tp_name, length);
4910 #else
4911     sprintf(name, "%.200s_Array_%ld",
4912         ((PyTypeObject *)itemtype)->tp_name, (long)length);
4913 #endif
4914 
4915     result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type,
4916                                    "s(O){s:n,s:O}",
4917                                    name,
4918                                    &PyCArray_Type,
4919                                    "_length_",
4920                                    length,
4921                                    "_type_",
4922                                    itemtype
4923         );
4924     if (result == NULL) {
4925         Py_DECREF(key);
4926         return NULL;
4927     }
4928     if (-1 == PyDict_SetItemProxy(cache, key, result)) {
4929         Py_DECREF(key);
4930         Py_DECREF(result);
4931         return NULL;
4932     }
4933     Py_DECREF(key);
4934     return result;
4935 }
4936 
4937 
4938 /******************************************************************/
4939 /*
4940   Simple_Type
4941 */
4942 
4943 static int
Simple_set_value(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))4944 Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
4945 {
4946     PyObject *result;
4947     StgDictObject *dict = PyObject_stgdict((PyObject *)self);
4948 
4949     if (value == NULL) {
4950         PyErr_SetString(PyExc_TypeError,
4951                         "can't delete attribute");
4952         return -1;
4953     }
4954     assert(dict); /* Cannot be NULL for CDataObject instances */
4955     assert(dict->setfunc);
4956     result = dict->setfunc(self->b_ptr, value, dict->size);
4957     if (!result)
4958         return -1;
4959 
4960     /* consumes the refcount the setfunc returns */
4961     return KeepRef(self, 0, result);
4962 }
4963 
4964 static int
Simple_init(CDataObject * self,PyObject * args,PyObject * kw)4965 Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
4966 {
4967     PyObject *value = NULL;
4968     if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
4969         return -1;
4970     if (value)
4971         return Simple_set_value(self, value, NULL);
4972     return 0;
4973 }
4974 
4975 static PyObject *
Simple_get_value(CDataObject * self,void * Py_UNUSED (ignored))4976 Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored))
4977 {
4978     StgDictObject *dict;
4979     dict = PyObject_stgdict((PyObject *)self);
4980     assert(dict); /* Cannot be NULL for CDataObject instances */
4981     assert(dict->getfunc);
4982     return dict->getfunc(self->b_ptr, self->b_size);
4983 }
4984 
4985 static PyGetSetDef Simple_getsets[] = {
4986     { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4987       "current value", NULL },
4988     { NULL, NULL }
4989 };
4990 
4991 static PyObject *
Simple_from_outparm(PyObject * self,PyObject * args)4992 Simple_from_outparm(PyObject *self, PyObject *args)
4993 {
4994     if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) {
4995         Py_INCREF(self);
4996         return self;
4997     }
4998     /* call stgdict->getfunc */
4999     return Simple_get_value((CDataObject *)self, NULL);
5000 }
5001 
5002 static PyMethodDef Simple_methods[] = {
5003     { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
5004     { NULL, NULL },
5005 };
5006 
Simple_bool(CDataObject * self)5007 static int Simple_bool(CDataObject *self)
5008 {
5009     return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
5010 }
5011 
5012 static PyNumberMethods Simple_as_number = {
5013     0, /* nb_add */
5014     0, /* nb_subtract */
5015     0, /* nb_multiply */
5016     0, /* nb_remainder */
5017     0, /* nb_divmod */
5018     0, /* nb_power */
5019     0, /* nb_negative */
5020     0, /* nb_positive */
5021     0, /* nb_absolute */
5022     (inquiry)Simple_bool, /* nb_bool */
5023 };
5024 
5025 /* "%s(%s)" % (self.__class__.__name__, self.value) */
5026 static PyObject *
Simple_repr(CDataObject * self)5027 Simple_repr(CDataObject *self)
5028 {
5029     PyObject *val, *result;
5030 
5031     if (Py_TYPE(self)->tp_base != &Simple_Type) {
5032         return PyUnicode_FromFormat("<%s object at %p>",
5033                                    Py_TYPE(self)->tp_name, self);
5034     }
5035 
5036     val = Simple_get_value(self, NULL);
5037     if (val == NULL)
5038         return NULL;
5039 
5040     result = PyUnicode_FromFormat("%s(%R)",
5041                                   Py_TYPE(self)->tp_name, val);
5042     Py_DECREF(val);
5043     return result;
5044 }
5045 
5046 static PyTypeObject Simple_Type = {
5047     PyVarObject_HEAD_INIT(NULL, 0)
5048     "_ctypes._SimpleCData",
5049     sizeof(CDataObject),                        /* tp_basicsize */
5050     0,                                          /* tp_itemsize */
5051     0,                                          /* tp_dealloc */
5052     0,                                          /* tp_vectorcall_offset */
5053     0,                                          /* tp_getattr */
5054     0,                                          /* tp_setattr */
5055     0,                                          /* tp_as_async */
5056     (reprfunc)&Simple_repr,                     /* tp_repr */
5057     &Simple_as_number,                          /* tp_as_number */
5058     0,                                          /* tp_as_sequence */
5059     0,                                          /* tp_as_mapping */
5060     0,                                          /* tp_hash */
5061     0,                                          /* tp_call */
5062     0,                                          /* tp_str */
5063     0,                                          /* tp_getattro */
5064     0,                                          /* tp_setattro */
5065     &PyCData_as_buffer,                         /* tp_as_buffer */
5066     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5067     "XXX to be provided",                       /* tp_doc */
5068     (traverseproc)PyCData_traverse,             /* tp_traverse */
5069     (inquiry)PyCData_clear,                     /* tp_clear */
5070     0,                                          /* tp_richcompare */
5071     0,                                          /* tp_weaklistoffset */
5072     0,                                          /* tp_iter */
5073     0,                                          /* tp_iternext */
5074     Simple_methods,                             /* tp_methods */
5075     0,                                          /* tp_members */
5076     Simple_getsets,                             /* tp_getset */
5077     0,                                          /* tp_base */
5078     0,                                          /* tp_dict */
5079     0,                                          /* tp_descr_get */
5080     0,                                          /* tp_descr_set */
5081     0,                                          /* tp_dictoffset */
5082     (initproc)Simple_init,                      /* tp_init */
5083     0,                                          /* tp_alloc */
5084     GenericPyCData_new,                         /* tp_new */
5085     0,                                          /* tp_free */
5086 };
5087 
5088 /******************************************************************/
5089 /*
5090   PyCPointer_Type
5091 */
5092 static PyObject *
Pointer_item(PyObject * myself,Py_ssize_t index)5093 Pointer_item(PyObject *myself, Py_ssize_t index)
5094 {
5095     CDataObject *self = (CDataObject *)myself;
5096     Py_ssize_t size;
5097     Py_ssize_t offset;
5098     StgDictObject *stgdict, *itemdict;
5099     PyObject *proto;
5100 
5101     if (*(void **)self->b_ptr == NULL) {
5102         PyErr_SetString(PyExc_ValueError,
5103                         "NULL pointer access");
5104         return NULL;
5105     }
5106 
5107     stgdict = PyObject_stgdict((PyObject *)self);
5108     assert(stgdict); /* Cannot be NULL for pointer object instances */
5109 
5110     proto = stgdict->proto;
5111     assert(proto);
5112     itemdict = PyType_stgdict(proto);
5113     assert(itemdict); /* proto is the item type of the pointer, a ctypes
5114                          type, so this cannot be NULL */
5115 
5116     size = itemdict->size;
5117     offset = index * itemdict->size;
5118 
5119     return PyCData_get(proto, stgdict->getfunc, (PyObject *)self,
5120                      index, size, (*(char **)self->b_ptr) + offset);
5121 }
5122 
5123 static int
Pointer_ass_item(PyObject * myself,Py_ssize_t index,PyObject * value)5124 Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
5125 {
5126     CDataObject *self = (CDataObject *)myself;
5127     Py_ssize_t size;
5128     Py_ssize_t offset;
5129     StgDictObject *stgdict, *itemdict;
5130     PyObject *proto;
5131 
5132     if (value == NULL) {
5133         PyErr_SetString(PyExc_TypeError,
5134                         "Pointer does not support item deletion");
5135         return -1;
5136     }
5137 
5138     if (*(void **)self->b_ptr == NULL) {
5139         PyErr_SetString(PyExc_ValueError,
5140                         "NULL pointer access");
5141         return -1;
5142     }
5143 
5144     stgdict = PyObject_stgdict((PyObject *)self);
5145     assert(stgdict); /* Cannot be NULL for pointer instances */
5146 
5147     proto = stgdict->proto;
5148     assert(proto);
5149 
5150     itemdict = PyType_stgdict(proto);
5151     assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
5152                          is always a ctypes type */
5153 
5154     size = itemdict->size;
5155     offset = index * itemdict->size;
5156 
5157     return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value,
5158                      index, size, (*(char **)self->b_ptr) + offset);
5159 }
5160 
5161 static PyObject *
Pointer_get_contents(CDataObject * self,void * closure)5162 Pointer_get_contents(CDataObject *self, void *closure)
5163 {
5164     StgDictObject *stgdict;
5165 
5166     if (*(void **)self->b_ptr == NULL) {
5167         PyErr_SetString(PyExc_ValueError,
5168                         "NULL pointer access");
5169         return NULL;
5170     }
5171 
5172     stgdict = PyObject_stgdict((PyObject *)self);
5173     assert(stgdict); /* Cannot be NULL for pointer instances */
5174     return PyCData_FromBaseObj(stgdict->proto,
5175                              (PyObject *)self, 0,
5176                              *(void **)self->b_ptr);
5177 }
5178 
5179 static int
Pointer_set_contents(CDataObject * self,PyObject * value,void * closure)5180 Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
5181 {
5182     StgDictObject *stgdict;
5183     CDataObject *dst;
5184     PyObject *keep;
5185 
5186     if (value == NULL) {
5187         PyErr_SetString(PyExc_TypeError,
5188                         "Pointer does not support item deletion");
5189         return -1;
5190     }
5191     stgdict = PyObject_stgdict((PyObject *)self);
5192     assert(stgdict); /* Cannot be NULL for pointer instances */
5193     assert(stgdict->proto);
5194     if (!CDataObject_Check(value)) {
5195         int res = PyObject_IsInstance(value, stgdict->proto);
5196         if (res == -1)
5197             return -1;
5198         if (!res) {
5199             PyErr_Format(PyExc_TypeError,
5200                          "expected %s instead of %s",
5201                          ((PyTypeObject *)(stgdict->proto))->tp_name,
5202                          Py_TYPE(value)->tp_name);
5203             return -1;
5204         }
5205     }
5206 
5207     dst = (CDataObject *)value;
5208     *(void **)self->b_ptr = dst->b_ptr;
5209 
5210     /*
5211        A Pointer instance must keep the value it points to alive.  So, a
5212        pointer instance has b_length set to 2 instead of 1, and we set
5213        'value' itself as the second item of the b_objects list, additionally.
5214     */
5215     Py_INCREF(value);
5216     if (-1 == KeepRef(self, 1, value))
5217         return -1;
5218 
5219     keep = GetKeepedObjects(dst);
5220     if (keep == NULL)
5221         return -1;
5222 
5223     Py_INCREF(keep);
5224     return KeepRef(self, 0, keep);
5225 }
5226 
5227 static PyGetSetDef Pointer_getsets[] = {
5228     { "contents", (getter)Pointer_get_contents,
5229       (setter)Pointer_set_contents,
5230       "the object this pointer points to (read-write)", NULL },
5231     { NULL, NULL }
5232 };
5233 
5234 static int
Pointer_init(CDataObject * self,PyObject * args,PyObject * kw)5235 Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
5236 {
5237     PyObject *value = NULL;
5238 
5239     if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
5240         return -1;
5241     if (value == NULL)
5242         return 0;
5243     return Pointer_set_contents(self, value, NULL);
5244 }
5245 
5246 static PyObject *
Pointer_new(PyTypeObject * type,PyObject * args,PyObject * kw)5247 Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
5248 {
5249     StgDictObject *dict = PyType_stgdict((PyObject *)type);
5250     if (!dict || !dict->proto) {
5251         PyErr_SetString(PyExc_TypeError,
5252                         "Cannot create instance: has no _type_");
5253         return NULL;
5254     }
5255     return GenericPyCData_new(type, args, kw);
5256 }
5257 
5258 static PyObject *
Pointer_subscript(PyObject * myself,PyObject * item)5259 Pointer_subscript(PyObject *myself, PyObject *item)
5260 {
5261     CDataObject *self = (CDataObject *)myself;
5262     if (PyIndex_Check(item)) {
5263         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
5264         if (i == -1 && PyErr_Occurred())
5265             return NULL;
5266         return Pointer_item(myself, i);
5267     }
5268     else if (PySlice_Check(item)) {
5269         PySliceObject *slice = (PySliceObject *)item;
5270         Py_ssize_t start, stop, step;
5271         PyObject *np;
5272         StgDictObject *stgdict, *itemdict;
5273         PyObject *proto;
5274         Py_ssize_t i, len;
5275         size_t cur;
5276 
5277         /* Since pointers have no length, and we want to apply
5278            different semantics to negative indices than normal
5279            slicing, we have to dissect the slice object ourselves.*/
5280         if (slice->step == Py_None) {
5281             step = 1;
5282         }
5283         else {
5284             step = PyNumber_AsSsize_t(slice->step,
5285                                       PyExc_ValueError);
5286             if (step == -1 && PyErr_Occurred())
5287                 return NULL;
5288             if (step == 0) {
5289                 PyErr_SetString(PyExc_ValueError,
5290                                 "slice step cannot be zero");
5291                 return NULL;
5292             }
5293         }
5294         if (slice->start == Py_None) {
5295             if (step < 0) {
5296                 PyErr_SetString(PyExc_ValueError,
5297                                 "slice start is required "
5298                                 "for step < 0");
5299                 return NULL;
5300             }
5301             start = 0;
5302         }
5303         else {
5304             start = PyNumber_AsSsize_t(slice->start,
5305                                        PyExc_ValueError);
5306             if (start == -1 && PyErr_Occurred())
5307                 return NULL;
5308         }
5309         if (slice->stop == Py_None) {
5310             PyErr_SetString(PyExc_ValueError,
5311                             "slice stop is required");
5312             return NULL;
5313         }
5314         stop = PyNumber_AsSsize_t(slice->stop,
5315                                   PyExc_ValueError);
5316         if (stop == -1 && PyErr_Occurred())
5317             return NULL;
5318         if ((step > 0 && start > stop) ||
5319             (step < 0 && start < stop))
5320             len = 0;
5321         else if (step > 0)
5322             len = (stop - start - 1) / step + 1;
5323         else
5324             len = (stop - start + 1) / step + 1;
5325 
5326         stgdict = PyObject_stgdict((PyObject *)self);
5327         assert(stgdict); /* Cannot be NULL for pointer instances */
5328         proto = stgdict->proto;
5329         assert(proto);
5330         itemdict = PyType_stgdict(proto);
5331         assert(itemdict);
5332         if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
5333             char *ptr = *(char **)self->b_ptr;
5334             char *dest;
5335 
5336             if (len <= 0)
5337                 return PyBytes_FromStringAndSize("", 0);
5338             if (step == 1) {
5339                 return PyBytes_FromStringAndSize(ptr + start,
5340                                                  len);
5341             }
5342             dest = (char *)PyMem_Malloc(len);
5343             if (dest == NULL)
5344                 return PyErr_NoMemory();
5345             for (cur = start, i = 0; i < len; cur += step, i++) {
5346                 dest[i] = ptr[cur];
5347             }
5348             np = PyBytes_FromStringAndSize(dest, len);
5349             PyMem_Free(dest);
5350             return np;
5351         }
5352 #ifdef CTYPES_UNICODE
5353         if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
5354             wchar_t *ptr = *(wchar_t **)self->b_ptr;
5355             wchar_t *dest;
5356 
5357             if (len <= 0)
5358                 return PyUnicode_New(0, 0);
5359             if (step == 1) {
5360                 return PyUnicode_FromWideChar(ptr + start,
5361                                               len);
5362             }
5363             dest = PyMem_New(wchar_t, len);
5364             if (dest == NULL)
5365                 return PyErr_NoMemory();
5366             for (cur = start, i = 0; i < len; cur += step, i++) {
5367                 dest[i] = ptr[cur];
5368             }
5369             np = PyUnicode_FromWideChar(dest, len);
5370             PyMem_Free(dest);
5371             return np;
5372         }
5373 #endif
5374 
5375         np = PyList_New(len);
5376         if (np == NULL)
5377             return NULL;
5378 
5379         for (cur = start, i = 0; i < len; cur += step, i++) {
5380             PyObject *v = Pointer_item(myself, cur);
5381             PyList_SET_ITEM(np, i, v);
5382         }
5383         return np;
5384     }
5385     else {
5386         PyErr_SetString(PyExc_TypeError,
5387                         "Pointer indices must be integer");
5388         return NULL;
5389     }
5390 }
5391 
5392 static PySequenceMethods Pointer_as_sequence = {
5393     0,                                          /* inquiry sq_length; */
5394     0,                                          /* binaryfunc sq_concat; */
5395     0,                                          /* intargfunc sq_repeat; */
5396     Pointer_item,                               /* intargfunc sq_item; */
5397     0,                                          /* intintargfunc sq_slice; */
5398     Pointer_ass_item,                           /* intobjargproc sq_ass_item; */
5399     0,                                          /* intintobjargproc sq_ass_slice; */
5400     0,                                          /* objobjproc sq_contains; */
5401     /* Added in release 2.0 */
5402     0,                                          /* binaryfunc sq_inplace_concat; */
5403     0,                                          /* intargfunc sq_inplace_repeat; */
5404 };
5405 
5406 static PyMappingMethods Pointer_as_mapping = {
5407     0,
5408     Pointer_subscript,
5409 };
5410 
5411 static int
Pointer_bool(CDataObject * self)5412 Pointer_bool(CDataObject *self)
5413 {
5414     return (*(void **)self->b_ptr != NULL);
5415 }
5416 
5417 static PyNumberMethods Pointer_as_number = {
5418     0, /* nb_add */
5419     0, /* nb_subtract */
5420     0, /* nb_multiply */
5421     0, /* nb_remainder */
5422     0, /* nb_divmod */
5423     0, /* nb_power */
5424     0, /* nb_negative */
5425     0, /* nb_positive */
5426     0, /* nb_absolute */
5427     (inquiry)Pointer_bool, /* nb_bool */
5428 };
5429 
5430 PyTypeObject PyCPointer_Type = {
5431     PyVarObject_HEAD_INIT(NULL, 0)
5432     "_ctypes._Pointer",
5433     sizeof(CDataObject),                        /* tp_basicsize */
5434     0,                                          /* tp_itemsize */
5435     0,                                          /* tp_dealloc */
5436     0,                                          /* tp_vectorcall_offset */
5437     0,                                          /* tp_getattr */
5438     0,                                          /* tp_setattr */
5439     0,                                          /* tp_as_async */
5440     0,                                          /* tp_repr */
5441     &Pointer_as_number,                         /* tp_as_number */
5442     &Pointer_as_sequence,                       /* tp_as_sequence */
5443     &Pointer_as_mapping,                        /* tp_as_mapping */
5444     0,                                          /* tp_hash */
5445     0,                                          /* tp_call */
5446     0,                                          /* tp_str */
5447     0,                                          /* tp_getattro */
5448     0,                                          /* tp_setattro */
5449     &PyCData_as_buffer,                         /* tp_as_buffer */
5450     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5451     "XXX to be provided",                       /* tp_doc */
5452     (traverseproc)PyCData_traverse,             /* tp_traverse */
5453     (inquiry)PyCData_clear,                     /* tp_clear */
5454     0,                                          /* tp_richcompare */
5455     0,                                          /* tp_weaklistoffset */
5456     0,                                          /* tp_iter */
5457     0,                                          /* tp_iternext */
5458     0,                                          /* tp_methods */
5459     0,                                          /* tp_members */
5460     Pointer_getsets,                            /* tp_getset */
5461     0,                                          /* tp_base */
5462     0,                                          /* tp_dict */
5463     0,                                          /* tp_descr_get */
5464     0,                                          /* tp_descr_set */
5465     0,                                          /* tp_dictoffset */
5466     (initproc)Pointer_init,                     /* tp_init */
5467     0,                                          /* tp_alloc */
5468     Pointer_new,                                /* tp_new */
5469     0,                                          /* tp_free */
5470 };
5471 
5472 
5473 /******************************************************************/
5474 /*
5475  *  Module initialization.
5476  */
5477 
5478 static const char module_docs[] =
5479 "Create and manipulate C compatible data types in Python.";
5480 
5481 #ifdef MS_WIN32
5482 
5483 static const char comerror_doc[] = "Raised when a COM method call failed.";
5484 
5485 int
comerror_init(PyObject * self,PyObject * args,PyObject * kwds)5486 comerror_init(PyObject *self, PyObject *args, PyObject *kwds)
5487 {
5488     PyObject *hresult, *text, *details;
5489     PyObject *a;
5490     int status;
5491 
5492     if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
5493         return -1;
5494 
5495     if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details))
5496         return -1;
5497 
5498     a = PySequence_GetSlice(args, 1, PyTuple_GET_SIZE(args));
5499     if (!a)
5500         return -1;
5501     status = PyObject_SetAttrString(self, "args", a);
5502     Py_DECREF(a);
5503     if (status < 0)
5504         return -1;
5505 
5506     if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
5507         return -1;
5508 
5509     if (PyObject_SetAttrString(self, "text", text) < 0)
5510         return -1;
5511 
5512     if (PyObject_SetAttrString(self, "details", details) < 0)
5513         return -1;
5514 
5515     Py_INCREF(args);
5516     Py_SETREF(((PyBaseExceptionObject *)self)->args, args);
5517 
5518     return 0;
5519 }
5520 
5521 static PyTypeObject PyComError_Type = {
5522     PyVarObject_HEAD_INIT(NULL, 0)
5523     "_ctypes.COMError",         /* tp_name */
5524     sizeof(PyBaseExceptionObject), /* tp_basicsize */
5525     0,                          /* tp_itemsize */
5526     0,                          /* tp_dealloc */
5527     0,                          /* tp_vectorcall_offset */
5528     0,                          /* tp_getattr */
5529     0,                          /* tp_setattr */
5530     0,                          /* tp_as_async */
5531     0,                          /* tp_repr */
5532     0,                          /* tp_as_number */
5533     0,                          /* tp_as_sequence */
5534     0,                          /* tp_as_mapping */
5535     0,                          /* tp_hash */
5536     0,                          /* tp_call */
5537     0,                          /* tp_str */
5538     0,                          /* tp_getattro */
5539     0,                          /* tp_setattro */
5540     0,                          /* tp_as_buffer */
5541     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
5542     PyDoc_STR(comerror_doc),    /* tp_doc */
5543     0,                          /* tp_traverse */
5544     0,                          /* tp_clear */
5545     0,                          /* tp_richcompare */
5546     0,                          /* tp_weaklistoffset */
5547     0,                          /* tp_iter */
5548     0,                          /* tp_iternext */
5549     0,                          /* tp_methods */
5550     0,                          /* tp_members */
5551     0,                          /* tp_getset */
5552     0,                          /* tp_base */
5553     0,                          /* tp_dict */
5554     0,                          /* tp_descr_get */
5555     0,                          /* tp_descr_set */
5556     0,                          /* tp_dictoffset */
5557     (initproc)comerror_init,    /* tp_init */
5558     0,                          /* tp_alloc */
5559     0,                          /* tp_new */
5560 };
5561 
5562 
5563 static int
create_comerror(void)5564 create_comerror(void)
5565 {
5566     PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception;
5567     if (PyType_Ready(&PyComError_Type) < 0)
5568         return -1;
5569     Py_INCREF(&PyComError_Type);
5570     ComError = (PyObject*)&PyComError_Type;
5571     return 0;
5572 }
5573 
5574 #endif
5575 
5576 static PyObject *
string_at(const char * ptr,int size)5577 string_at(const char *ptr, int size)
5578 {
5579     if (PySys_Audit("ctypes.string_at", "ni", (Py_ssize_t)ptr, size) < 0) {
5580         return NULL;
5581     }
5582     if (size == -1)
5583         return PyBytes_FromStringAndSize(ptr, strlen(ptr));
5584     return PyBytes_FromStringAndSize(ptr, size);
5585 }
5586 
5587 static int
cast_check_pointertype(PyObject * arg)5588 cast_check_pointertype(PyObject *arg)
5589 {
5590     StgDictObject *dict;
5591 
5592     if (PyCPointerTypeObject_Check(arg))
5593         return 1;
5594     if (PyCFuncPtrTypeObject_Check(arg))
5595         return 1;
5596     dict = PyType_stgdict(arg);
5597     if (dict != NULL && dict->proto != NULL) {
5598         if (PyUnicode_Check(dict->proto)
5599             && (strchr("sPzUZXO", PyUnicode_AsUTF8(dict->proto)[0]))) {
5600             /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
5601             return 1;
5602         }
5603     }
5604     PyErr_Format(PyExc_TypeError,
5605                  "cast() argument 2 must be a pointer type, not %s",
5606                  PyType_Check(arg)
5607                  ? ((PyTypeObject *)arg)->tp_name
5608                  : Py_TYPE(arg)->tp_name);
5609     return 0;
5610 }
5611 
5612 static PyObject *
cast(void * ptr,PyObject * src,PyObject * ctype)5613 cast(void *ptr, PyObject *src, PyObject *ctype)
5614 {
5615     CDataObject *result;
5616     if (0 == cast_check_pointertype(ctype))
5617         return NULL;
5618     result = (CDataObject *)_PyObject_CallNoArg(ctype);
5619     if (result == NULL)
5620         return NULL;
5621 
5622     /*
5623       The casted objects '_objects' member:
5624 
5625       It must certainly contain the source objects one.
5626       It must contain the source object itself.
5627      */
5628     if (CDataObject_Check(src)) {
5629         CDataObject *obj = (CDataObject *)src;
5630         CDataObject *container;
5631 
5632         /* PyCData_GetContainer will initialize src.b_objects, we need
5633            this so it can be shared */
5634         container = PyCData_GetContainer(obj);
5635         if (container == NULL)
5636             goto failed;
5637 
5638         /* But we need a dictionary! */
5639         if (obj->b_objects == Py_None) {
5640             Py_DECREF(Py_None);
5641             obj->b_objects = PyDict_New();
5642             if (obj->b_objects == NULL)
5643                 goto failed;
5644         }
5645         Py_XINCREF(obj->b_objects);
5646         result->b_objects = obj->b_objects;
5647         if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
5648             PyObject *index;
5649             int rc;
5650             index = PyLong_FromVoidPtr((void *)src);
5651             if (index == NULL)
5652                 goto failed;
5653             rc = PyDict_SetItem(result->b_objects, index, src);
5654             Py_DECREF(index);
5655             if (rc == -1)
5656                 goto failed;
5657         }
5658     }
5659     /* Should we assert that result is a pointer type? */
5660     memcpy(result->b_ptr, &ptr, sizeof(void *));
5661     return (PyObject *)result;
5662 
5663   failed:
5664     Py_DECREF(result);
5665     return NULL;
5666 }
5667 
5668 #ifdef CTYPES_UNICODE
5669 static PyObject *
wstring_at(const wchar_t * ptr,int size)5670 wstring_at(const wchar_t *ptr, int size)
5671 {
5672     Py_ssize_t ssize = size;
5673     if (PySys_Audit("ctypes.wstring_at", "nn", (Py_ssize_t)ptr, ssize) < 0) {
5674         return NULL;
5675     }
5676     if (ssize == -1)
5677         ssize = wcslen(ptr);
5678     return PyUnicode_FromWideChar(ptr, ssize);
5679 }
5680 #endif
5681 
5682 
5683 static struct PyModuleDef _ctypesmodule = {
5684     PyModuleDef_HEAD_INIT,
5685     "_ctypes",
5686     module_docs,
5687     -1,
5688     _ctypes_module_methods,
5689     NULL,
5690     NULL,
5691     NULL,
5692     NULL
5693 };
5694 
5695 PyMODINIT_FUNC
PyInit__ctypes(void)5696 PyInit__ctypes(void)
5697 {
5698     PyObject *m;
5699 
5700 /* Note:
5701    ob_type is the metatype (the 'type'), defaults to PyType_Type,
5702    tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
5703 */
5704     m = PyModule_Create(&_ctypesmodule);
5705     if (!m)
5706         return NULL;
5707 
5708     _ctypes_ptrtype_cache = PyDict_New();
5709     if (_ctypes_ptrtype_cache == NULL)
5710         return NULL;
5711 
5712     PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache);
5713 
5714     _unpickle = PyObject_GetAttrString(m, "_unpickle");
5715     if (_unpickle == NULL)
5716         return NULL;
5717 
5718     if (PyType_Ready(&PyCArg_Type) < 0)
5719         return NULL;
5720 
5721     if (PyType_Ready(&PyCThunk_Type) < 0)
5722         return NULL;
5723 
5724     /* StgDict is derived from PyDict_Type */
5725     PyCStgDict_Type.tp_base = &PyDict_Type;
5726     if (PyType_Ready(&PyCStgDict_Type) < 0)
5727         return NULL;
5728 
5729     /*************************************************
5730      *
5731      * Metaclasses
5732      */
5733 
5734     PyCStructType_Type.tp_base = &PyType_Type;
5735     if (PyType_Ready(&PyCStructType_Type) < 0)
5736         return NULL;
5737 
5738     UnionType_Type.tp_base = &PyType_Type;
5739     if (PyType_Ready(&UnionType_Type) < 0)
5740         return NULL;
5741 
5742     PyCPointerType_Type.tp_base = &PyType_Type;
5743     if (PyType_Ready(&PyCPointerType_Type) < 0)
5744         return NULL;
5745 
5746     PyCArrayType_Type.tp_base = &PyType_Type;
5747     if (PyType_Ready(&PyCArrayType_Type) < 0)
5748         return NULL;
5749 
5750     PyCSimpleType_Type.tp_base = &PyType_Type;
5751     if (PyType_Ready(&PyCSimpleType_Type) < 0)
5752         return NULL;
5753 
5754     PyCFuncPtrType_Type.tp_base = &PyType_Type;
5755     if (PyType_Ready(&PyCFuncPtrType_Type) < 0)
5756         return NULL;
5757 
5758     /*************************************************
5759      *
5760      * Classes using a custom metaclass
5761      */
5762 
5763     if (PyType_Ready(&PyCData_Type) < 0)
5764         return NULL;
5765 
5766     Py_SET_TYPE(&Struct_Type, &PyCStructType_Type);
5767     Struct_Type.tp_base = &PyCData_Type;
5768     if (PyType_Ready(&Struct_Type) < 0)
5769         return NULL;
5770     Py_INCREF(&Struct_Type);
5771     PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
5772 
5773     Py_SET_TYPE(&Union_Type, &UnionType_Type);
5774     Union_Type.tp_base = &PyCData_Type;
5775     if (PyType_Ready(&Union_Type) < 0)
5776         return NULL;
5777     Py_INCREF(&Union_Type);
5778     PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
5779 
5780     Py_SET_TYPE(&PyCPointer_Type, &PyCPointerType_Type);
5781     PyCPointer_Type.tp_base = &PyCData_Type;
5782     if (PyType_Ready(&PyCPointer_Type) < 0)
5783         return NULL;
5784     Py_INCREF(&PyCPointer_Type);
5785     PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);
5786 
5787     Py_SET_TYPE(&PyCArray_Type, &PyCArrayType_Type);
5788     PyCArray_Type.tp_base = &PyCData_Type;
5789     if (PyType_Ready(&PyCArray_Type) < 0)
5790         return NULL;
5791     Py_INCREF(&PyCArray_Type);
5792     PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);
5793 
5794     Py_SET_TYPE(&Simple_Type, &PyCSimpleType_Type);
5795     Simple_Type.tp_base = &PyCData_Type;
5796     if (PyType_Ready(&Simple_Type) < 0)
5797         return NULL;
5798     Py_INCREF(&Simple_Type);
5799     PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
5800 
5801     Py_SET_TYPE(&PyCFuncPtr_Type, &PyCFuncPtrType_Type);
5802     PyCFuncPtr_Type.tp_base = &PyCData_Type;
5803     if (PyType_Ready(&PyCFuncPtr_Type) < 0)
5804         return NULL;
5805     Py_INCREF(&PyCFuncPtr_Type);
5806     PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);
5807 
5808     /*************************************************
5809      *
5810      * Simple classes
5811      */
5812 
5813     /* PyCField_Type is derived from PyBaseObject_Type */
5814     if (PyType_Ready(&PyCField_Type) < 0)
5815         return NULL;
5816 
5817     /*************************************************
5818      *
5819      * Other stuff
5820      */
5821 
5822     DictRemover_Type.tp_new = PyType_GenericNew;
5823     if (PyType_Ready(&DictRemover_Type) < 0)
5824         return NULL;
5825 
5826     if (PyType_Ready(&StructParam_Type) < 0) {
5827         return NULL;
5828     }
5829 
5830 #ifdef MS_WIN32
5831     if (create_comerror() < 0)
5832         return NULL;
5833     PyModule_AddObject(m, "COMError", ComError);
5834 
5835     PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
5836     PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
5837 #endif
5838     PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL));
5839     PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
5840     PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
5841     PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
5842     PyModule_AddStringConstant(m, "__version__", "1.1.0");
5843 
5844     PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
5845     PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
5846     PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
5847     PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
5848 #ifdef CTYPES_UNICODE
5849     PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
5850 #endif
5851 
5852 /* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
5853 #if !HAVE_DECL_RTLD_LOCAL
5854 #define RTLD_LOCAL 0
5855 #endif
5856 
5857 /* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
5858    RTLD_LOCAL.
5859 */
5860 #if !HAVE_DECL_RTLD_GLOBAL
5861 #define RTLD_GLOBAL RTLD_LOCAL
5862 #endif
5863 
5864     PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL));
5865     PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL));
5866 
5867     PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5868     if (PyExc_ArgError) {
5869         Py_INCREF(PyExc_ArgError);
5870         PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
5871     }
5872     return m;
5873 }
5874 
5875 /*
5876  Local Variables:
5877  compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
5878  End:
5879 */
5880