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