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 #ifndef Py_BUILD_CORE_BUILTIN
102 # define Py_BUILD_CORE_MODULE 1
103 #endif
104 #define NEEDS_PY_IDENTIFIER
105
106 #define PY_SSIZE_T_CLEAN
107
108 #include "Python.h"
109 // windows.h must be included before pycore internal headers
110 #ifdef MS_WIN32
111 # include <windows.h>
112 #endif
113
114 #include "pycore_call.h" // _PyObject_CallNoArgs()
115 #include "pycore_ceval.h" // _Py_EnterRecursiveCall()
116 #include "structmember.h" // PyMemberDef
117
118 #include <ffi.h>
119 #ifdef MS_WIN32
120 #include <malloc.h>
121 #ifndef IS_INTRESOURCE
122 #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
123 #endif
124 #else
125 #include "ctypes_dlfcn.h"
126 #endif
127 #include "ctypes.h"
128
129 #include "pycore_long.h" // _PyLong_GetZero()
130
131 PyObject *PyExc_ArgError = NULL;
132
133 /* This dict maps ctypes types to POINTER types */
134 PyObject *_ctypes_ptrtype_cache = NULL;
135
136 static PyTypeObject Simple_Type;
137
138 /* a callable object used for unpickling:
139 strong reference to _ctypes._unpickle() function */
140 static PyObject *_unpickle;
141
142 #ifdef MS_WIN32
143 PyObject *ComError; // Borrowed reference to: &PyComError_Type
144 #endif
145
146
147 /****************************************************************/
148
149 typedef struct {
150 PyObject_HEAD
151 PyObject *key;
152 PyObject *dict;
153 } DictRemoverObject;
154
155 static void
_DictRemover_dealloc(PyObject * myself)156 _DictRemover_dealloc(PyObject *myself)
157 {
158 DictRemoverObject *self = (DictRemoverObject *)myself;
159 Py_XDECREF(self->key);
160 Py_XDECREF(self->dict);
161 Py_TYPE(self)->tp_free(myself);
162 }
163
164 static PyObject *
_DictRemover_call(PyObject * myself,PyObject * args,PyObject * kw)165 _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw)
166 {
167 DictRemoverObject *self = (DictRemoverObject *)myself;
168 if (self->key && self->dict) {
169 if (-1 == PyDict_DelItem(self->dict, self->key)) {
170 _PyErr_WriteUnraisableMsg("on calling _ctypes.DictRemover", NULL);
171 }
172 Py_CLEAR(self->key);
173 Py_CLEAR(self->dict);
174 }
175 Py_RETURN_NONE;
176 }
177
178 static PyTypeObject DictRemover_Type = {
179 PyVarObject_HEAD_INIT(NULL, 0)
180 "_ctypes.DictRemover", /* tp_name */
181 sizeof(DictRemoverObject), /* tp_basicsize */
182 0, /* tp_itemsize */
183 _DictRemover_dealloc, /* tp_dealloc */
184 0, /* tp_vectorcall_offset */
185 0, /* tp_getattr */
186 0, /* tp_setattr */
187 0, /* tp_as_async */
188 0, /* tp_repr */
189 0, /* tp_as_number */
190 0, /* tp_as_sequence */
191 0, /* tp_as_mapping */
192 0, /* tp_hash */
193 _DictRemover_call, /* tp_call */
194 0, /* tp_str */
195 0, /* tp_getattro */
196 0, /* tp_setattro */
197 0, /* tp_as_buffer */
198 /* XXX should participate in GC? */
199 Py_TPFLAGS_DEFAULT, /* tp_flags */
200 PyDoc_STR("deletes a key from a dictionary"), /* tp_doc */
201 0, /* tp_traverse */
202 0, /* tp_clear */
203 0, /* tp_richcompare */
204 0, /* tp_weaklistoffset */
205 0, /* tp_iter */
206 0, /* tp_iternext */
207 0, /* tp_methods */
208 0, /* tp_members */
209 0, /* tp_getset */
210 0, /* tp_base */
211 0, /* tp_dict */
212 0, /* tp_descr_get */
213 0, /* tp_descr_set */
214 0, /* tp_dictoffset */
215 0, /* tp_init */
216 0, /* tp_alloc */
217 0, /* tp_new */
218 0, /* tp_free */
219 };
220
221 int
PyDict_SetItemProxy(PyObject * dict,PyObject * key,PyObject * item)222 PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item)
223 {
224 PyObject *obj;
225 DictRemoverObject *remover;
226 PyObject *proxy;
227 int result;
228
229 obj = _PyObject_CallNoArgs((PyObject *)&DictRemover_Type);
230 if (obj == NULL)
231 return -1;
232
233 remover = (DictRemoverObject *)obj;
234 assert(remover->key == NULL);
235 assert(remover->dict == NULL);
236 Py_INCREF(key);
237 remover->key = key;
238 Py_INCREF(dict);
239 remover->dict = dict;
240
241 proxy = PyWeakref_NewProxy(item, obj);
242 Py_DECREF(obj);
243 if (proxy == NULL)
244 return -1;
245
246 result = PyDict_SetItem(dict, key, proxy);
247 Py_DECREF(proxy);
248 return result;
249 }
250
251 PyObject *
PyDict_GetItemProxy(PyObject * dict,PyObject * key)252 PyDict_GetItemProxy(PyObject *dict, PyObject *key)
253 {
254 PyObject *result;
255 PyObject *item = PyDict_GetItemWithError(dict, key);
256
257 if (item == NULL)
258 return NULL;
259 if (!PyWeakref_CheckProxy(item))
260 return item;
261 result = PyWeakref_GET_OBJECT(item);
262 if (result == Py_None)
263 return NULL;
264 return result;
265 }
266
267 /******************************************************************/
268
269 /*
270 Allocate a memory block for a pep3118 format string, filled with
271 a suitable PEP 3118 type code corresponding to the given ctypes
272 type. Returns NULL on failure, with the error indicator set.
273
274 This produces type codes in the standard size mode (cf. struct module),
275 since the endianness may need to be swapped to a non-native one
276 later on.
277 */
278 static char *
_ctypes_alloc_format_string_for_type(char code,int big_endian)279 _ctypes_alloc_format_string_for_type(char code, int big_endian)
280 {
281 char *result;
282 char pep_code = '\0';
283
284 switch (code) {
285 #if SIZEOF_INT == 2
286 case 'i': pep_code = 'h'; break;
287 case 'I': pep_code = 'H'; break;
288 #elif SIZEOF_INT == 4
289 case 'i': pep_code = 'i'; break;
290 case 'I': pep_code = 'I'; break;
291 #elif SIZEOF_INT == 8
292 case 'i': pep_code = 'q'; break;
293 case 'I': pep_code = 'Q'; break;
294 #else
295 # error SIZEOF_INT has an unexpected value
296 #endif /* SIZEOF_INT */
297 #if SIZEOF_LONG == 4
298 case 'l': pep_code = 'l'; break;
299 case 'L': pep_code = 'L'; break;
300 #elif SIZEOF_LONG == 8
301 case 'l': pep_code = 'q'; break;
302 case 'L': pep_code = 'Q'; break;
303 #else
304 # error SIZEOF_LONG has an unexpected value
305 #endif /* SIZEOF_LONG */
306 #if SIZEOF__BOOL == 1
307 case '?': pep_code = '?'; break;
308 #elif SIZEOF__BOOL == 2
309 case '?': pep_code = 'H'; break;
310 #elif SIZEOF__BOOL == 4
311 case '?': pep_code = 'L'; break;
312 #elif SIZEOF__BOOL == 8
313 case '?': pep_code = 'Q'; break;
314 #else
315 # error SIZEOF__BOOL has an unexpected value
316 #endif /* SIZEOF__BOOL */
317 default:
318 /* The standard-size code is the same as the ctypes one */
319 pep_code = code;
320 break;
321 }
322
323 result = PyMem_Malloc(3);
324 if (result == NULL) {
325 PyErr_NoMemory();
326 return NULL;
327 }
328
329 result[0] = big_endian ? '>' : '<';
330 result[1] = pep_code;
331 result[2] = '\0';
332 return result;
333 }
334
335 /*
336 Allocate a memory block for a pep3118 format string, copy prefix (if
337 non-null) and suffix into it. Returns NULL on failure, with the error
338 indicator set. If called with a suffix of NULL the error indicator must
339 already be set.
340 */
341 char *
_ctypes_alloc_format_string(const char * prefix,const char * suffix)342 _ctypes_alloc_format_string(const char *prefix, const char *suffix)
343 {
344 size_t len;
345 char *result;
346
347 if (suffix == NULL) {
348 assert(PyErr_Occurred());
349 return NULL;
350 }
351 len = strlen(suffix);
352 if (prefix)
353 len += strlen(prefix);
354 result = PyMem_Malloc(len + 1);
355 if (result == NULL) {
356 PyErr_NoMemory();
357 return NULL;
358 }
359 if (prefix)
360 strcpy(result, prefix);
361 else
362 result[0] = '\0';
363 strcat(result, suffix);
364 return result;
365 }
366
367 /*
368 Allocate a memory block for a pep3118 format string, adding
369 the given prefix (if non-null), an additional shape prefix, and a suffix.
370 Returns NULL on failure, with the error indicator set. If called with
371 a suffix of NULL the error indicator must already be set.
372 */
373 char *
_ctypes_alloc_format_string_with_shape(int ndim,const Py_ssize_t * shape,const char * prefix,const char * suffix)374 _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
375 const char *prefix, const char *suffix)
376 {
377 char *new_prefix;
378 char *result;
379 char buf[32];
380 Py_ssize_t prefix_len;
381 int k;
382
383 prefix_len = 32 * ndim + 3;
384 if (prefix)
385 prefix_len += strlen(prefix);
386 new_prefix = PyMem_Malloc(prefix_len);
387 if (new_prefix == NULL) {
388 PyErr_NoMemory();
389 return NULL;
390 }
391 new_prefix[0] = '\0';
392 if (prefix)
393 strcpy(new_prefix, prefix);
394 if (ndim > 0) {
395 /* Add the prefix "(shape[0],shape[1],...,shape[ndim-1])" */
396 strcat(new_prefix, "(");
397 for (k = 0; k < ndim; ++k) {
398 if (k < ndim-1) {
399 sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]);
400 } else {
401 sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]);
402 }
403 strcat(new_prefix, buf);
404 }
405 }
406 result = _ctypes_alloc_format_string(new_prefix, suffix);
407 PyMem_Free(new_prefix);
408 return result;
409 }
410
411 /* StructParamObject and StructParam_Type are used in _ctypes_callproc()
412 for argument.keep to call PyMem_Free(ptr) on Py_DECREF(argument).
413
414 StructUnionType_paramfunc() creates such object when a ctypes Structure is
415 passed by copy to a C function. */
416 typedef struct {
417 PyObject_HEAD
418 void *ptr;
419 PyObject *keep; // If set, a reference to the original CDataObject.
420 } StructParamObject;
421
422
423 static void
StructParam_dealloc(PyObject * myself)424 StructParam_dealloc(PyObject *myself)
425 {
426 StructParamObject *self = (StructParamObject *)myself;
427 Py_XDECREF(self->keep);
428 PyMem_Free(self->ptr);
429 Py_TYPE(self)->tp_free(myself);
430 }
431
432
433 static PyTypeObject StructParam_Type = {
434 PyVarObject_HEAD_INIT(NULL, 0)
435 .tp_name = "_ctypes.StructParam_Type",
436 .tp_basicsize = sizeof(StructParamObject),
437 .tp_dealloc = StructParam_dealloc,
438 .tp_flags = Py_TPFLAGS_DEFAULT,
439 };
440
441
442 /*
443 PyCStructType_Type - a meta type/class. Creating a new class using this one as
444 __metaclass__ will call the constructor StructUnionType_new. It replaces the
445 tp_dict member with a new instance of StgDict, and initializes the C
446 accessible fields somehow.
447 */
448
449 static PyCArgObject *
StructUnionType_paramfunc(CDataObject * self)450 StructUnionType_paramfunc(CDataObject *self)
451 {
452 PyCArgObject *parg;
453 PyObject *obj;
454 StgDictObject *stgdict;
455 void *ptr;
456
457 if ((size_t)self->b_size > sizeof(void*)) {
458 ptr = PyMem_Malloc(self->b_size);
459 if (ptr == NULL) {
460 return NULL;
461 }
462 memcpy(ptr, self->b_ptr, self->b_size);
463
464 /* Create a Python object which calls PyMem_Free(ptr) in
465 its deallocator. The object will be destroyed
466 at _ctypes_callproc() cleanup. */
467 obj = (&StructParam_Type)->tp_alloc(&StructParam_Type, 0);
468 if (obj == NULL) {
469 PyMem_Free(ptr);
470 return NULL;
471 }
472
473 StructParamObject *struct_param = (StructParamObject *)obj;
474 struct_param->ptr = ptr;
475 struct_param->keep = Py_NewRef(self);
476 } else {
477 ptr = self->b_ptr;
478 obj = (PyObject *)self;
479 Py_INCREF(obj);
480 }
481
482 parg = PyCArgObject_new();
483 if (parg == NULL) {
484 Py_DECREF(obj);
485 return NULL;
486 }
487
488 parg->tag = 'V';
489 stgdict = PyObject_stgdict((PyObject *)self);
490 assert(stgdict); /* Cannot be NULL for structure/union instances */
491 parg->pffi_type = &stgdict->ffi_type_pointer;
492 parg->value.p = ptr;
493 parg->size = self->b_size;
494 parg->obj = obj;
495 return parg;
496 }
497
498 static PyObject *
StructUnionType_new(PyTypeObject * type,PyObject * args,PyObject * kwds,int isStruct)499 StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
500 {
501 PyTypeObject *result;
502 PyObject *fields;
503 StgDictObject *dict;
504 _Py_IDENTIFIER(_abstract_);
505 _Py_IDENTIFIER(_fields_);
506
507 /* create the new instance (which is a class,
508 since we are a metatype!) */
509 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
510 if (!result)
511 return NULL;
512
513 /* keep this for bw compatibility */
514 int r = _PyDict_ContainsId(result->tp_dict, &PyId__abstract_);
515 if (r > 0)
516 return (PyObject *)result;
517 if (r < 0) {
518 Py_DECREF(result);
519 return NULL;
520 }
521
522 dict = (StgDictObject *)_PyObject_CallNoArgs((PyObject *)&PyCStgDict_Type);
523 if (!dict) {
524 Py_DECREF(result);
525 return NULL;
526 }
527 if (!isStruct) {
528 dict->flags |= TYPEFLAG_HASUNION;
529 }
530 /* replace the class dict by our updated stgdict, which holds info
531 about storage requirements of the instances */
532 if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
533 Py_DECREF(result);
534 Py_DECREF((PyObject *)dict);
535 return NULL;
536 }
537 Py_SETREF(result->tp_dict, (PyObject *)dict);
538 dict->format = _ctypes_alloc_format_string(NULL, "B");
539 if (dict->format == NULL) {
540 Py_DECREF(result);
541 return NULL;
542 }
543
544 dict->paramfunc = StructUnionType_paramfunc;
545
546 fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_);
547 if (fields) {
548 if (_PyObject_SetAttrId((PyObject *)result, &PyId__fields_, fields) < 0) {
549 Py_DECREF(result);
550 return NULL;
551 }
552 return (PyObject *)result;
553 }
554 else if (PyErr_Occurred()) {
555 Py_DECREF(result);
556 return NULL;
557 }
558 else {
559 StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
560
561 if (basedict == NULL)
562 return (PyObject *)result;
563 /* copy base dict */
564 if (-1 == PyCStgDict_clone(dict, basedict)) {
565 Py_DECREF(result);
566 return NULL;
567 }
568 dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
569 basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
570 return (PyObject *)result;
571 }
572 }
573
574 static PyObject *
PyCStructType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)575 PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
576 {
577 return StructUnionType_new(type, args, kwds, 1);
578 }
579
580 static PyObject *
UnionType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)581 UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
582 {
583 return StructUnionType_new(type, args, kwds, 0);
584 }
585
586 PyDoc_STRVAR(from_address_doc,
587 "C.from_address(integer) -> C instance\naccess a C instance at the specified address");
588
589 static PyObject *
CDataType_from_address(PyObject * type,PyObject * value)590 CDataType_from_address(PyObject *type, PyObject *value)
591 {
592 void *buf;
593 if (!PyLong_Check(value)) {
594 PyErr_SetString(PyExc_TypeError,
595 "integer expected");
596 return NULL;
597 }
598 buf = (void *)PyLong_AsVoidPtr(value);
599 if (PyErr_Occurred())
600 return NULL;
601 return PyCData_AtAddress(type, buf);
602 }
603
604 PyDoc_STRVAR(from_buffer_doc,
605 "C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer");
606
607 static int
608 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);
609
610 static PyObject *
CDataType_from_buffer(PyObject * type,PyObject * args)611 CDataType_from_buffer(PyObject *type, PyObject *args)
612 {
613 PyObject *obj;
614 PyObject *mv;
615 PyObject *result;
616 Py_buffer *buffer;
617 Py_ssize_t offset = 0;
618
619 StgDictObject *dict = PyType_stgdict(type);
620 if (!dict) {
621 PyErr_SetString(PyExc_TypeError, "abstract class");
622 return NULL;
623 }
624
625 if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset))
626 return NULL;
627
628 mv = PyMemoryView_FromObject(obj);
629 if (mv == NULL)
630 return NULL;
631
632 buffer = PyMemoryView_GET_BUFFER(mv);
633
634 if (buffer->readonly) {
635 PyErr_SetString(PyExc_TypeError,
636 "underlying buffer is not writable");
637 Py_DECREF(mv);
638 return NULL;
639 }
640
641 if (!PyBuffer_IsContiguous(buffer, 'C')) {
642 PyErr_SetString(PyExc_TypeError,
643 "underlying buffer is not C contiguous");
644 Py_DECREF(mv);
645 return NULL;
646 }
647
648 if (offset < 0) {
649 PyErr_SetString(PyExc_ValueError,
650 "offset cannot be negative");
651 Py_DECREF(mv);
652 return NULL;
653 }
654
655 if (dict->size > buffer->len - offset) {
656 PyErr_Format(PyExc_ValueError,
657 "Buffer size too small "
658 "(%zd instead of at least %zd bytes)",
659 buffer->len, dict->size + offset);
660 Py_DECREF(mv);
661 return NULL;
662 }
663
664 if (PySys_Audit("ctypes.cdata/buffer", "nnn",
665 (Py_ssize_t)buffer->buf, buffer->len, offset) < 0) {
666 Py_DECREF(mv);
667 return NULL;
668 }
669
670 result = PyCData_AtAddress(type, (char *)buffer->buf + offset);
671 if (result == NULL) {
672 Py_DECREF(mv);
673 return NULL;
674 }
675
676 if (-1 == KeepRef((CDataObject *)result, -1, mv)) {
677 Py_DECREF(result);
678 return NULL;
679 }
680
681 return result;
682 }
683
684 PyDoc_STRVAR(from_buffer_copy_doc,
685 "C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer");
686
687 static PyObject *
688 GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
689
690 static PyObject *
CDataType_from_buffer_copy(PyObject * type,PyObject * args)691 CDataType_from_buffer_copy(PyObject *type, PyObject *args)
692 {
693 Py_buffer buffer;
694 Py_ssize_t offset = 0;
695 PyObject *result;
696 StgDictObject *dict = PyType_stgdict(type);
697 if (!dict) {
698 PyErr_SetString(PyExc_TypeError, "abstract class");
699 return NULL;
700 }
701
702 if (!PyArg_ParseTuple(args, "y*|n:from_buffer_copy", &buffer, &offset))
703 return NULL;
704
705 if (offset < 0) {
706 PyErr_SetString(PyExc_ValueError,
707 "offset cannot be negative");
708 PyBuffer_Release(&buffer);
709 return NULL;
710 }
711
712 if (dict->size > buffer.len - offset) {
713 PyErr_Format(PyExc_ValueError,
714 "Buffer size too small (%zd instead of at least %zd bytes)",
715 buffer.len, dict->size + offset);
716 PyBuffer_Release(&buffer);
717 return NULL;
718 }
719
720 if (PySys_Audit("ctypes.cdata/buffer", "nnn",
721 (Py_ssize_t)buffer.buf, buffer.len, offset) < 0) {
722 PyBuffer_Release(&buffer);
723 return NULL;
724 }
725
726 result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL);
727 if (result != NULL) {
728 memcpy(((CDataObject *)result)->b_ptr,
729 (char *)buffer.buf + offset, dict->size);
730 }
731 PyBuffer_Release(&buffer);
732 return result;
733 }
734
735 PyDoc_STRVAR(in_dll_doc,
736 "C.in_dll(dll, name) -> C instance\naccess a C instance in a dll");
737
738 static PyObject *
CDataType_in_dll(PyObject * type,PyObject * args)739 CDataType_in_dll(PyObject *type, PyObject *args)
740 {
741 PyObject *dll;
742 char *name;
743 PyObject *obj;
744 void *handle;
745 void *address;
746
747 if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
748 return NULL;
749 if (PySys_Audit("ctypes.dlsym", "O", args) < 0) {
750 return NULL;
751 }
752
753 obj = PyObject_GetAttrString(dll, "_handle");
754 if (!obj)
755 return NULL;
756 if (!PyLong_Check(obj)) {
757 PyErr_SetString(PyExc_TypeError,
758 "the _handle attribute of the second argument must be an integer");
759 Py_DECREF(obj);
760 return NULL;
761 }
762 handle = (void *)PyLong_AsVoidPtr(obj);
763 Py_DECREF(obj);
764 if (PyErr_Occurred()) {
765 PyErr_SetString(PyExc_ValueError,
766 "could not convert the _handle attribute to a pointer");
767 return NULL;
768 }
769
770 #ifdef MS_WIN32
771 Py_BEGIN_ALLOW_THREADS
772 address = (void *)GetProcAddress(handle, name);
773 Py_END_ALLOW_THREADS
774 if (!address) {
775 PyErr_Format(PyExc_ValueError,
776 "symbol '%s' not found",
777 name);
778 return NULL;
779 }
780 #else
781 address = (void *)ctypes_dlsym(handle, name);
782 if (!address) {
783 #ifdef __CYGWIN__
784 /* dlerror() isn't very helpful on cygwin */
785 PyErr_Format(PyExc_ValueError,
786 "symbol '%s' not found",
787 name);
788 #else
789 PyErr_SetString(PyExc_ValueError, ctypes_dlerror());
790 #endif
791 return NULL;
792 }
793 #endif
794 return PyCData_AtAddress(type, address);
795 }
796
797 PyDoc_STRVAR(from_param_doc,
798 "Convert a Python object into a function call parameter.");
799
800 static PyObject *
CDataType_from_param(PyObject * type,PyObject * value)801 CDataType_from_param(PyObject *type, PyObject *value)
802 {
803 _Py_IDENTIFIER(_as_parameter_);
804 PyObject *as_parameter;
805 int res = PyObject_IsInstance(value, type);
806 if (res == -1)
807 return NULL;
808 if (res) {
809 Py_INCREF(value);
810 return value;
811 }
812 if (PyCArg_CheckExact(value)) {
813 PyCArgObject *p = (PyCArgObject *)value;
814 PyObject *ob = p->obj;
815 const char *ob_name;
816 StgDictObject *dict;
817 dict = PyType_stgdict(type);
818
819 /* If we got a PyCArgObject, we must check if the object packed in it
820 is an instance of the type's dict->proto */
821 if(dict && ob) {
822 res = PyObject_IsInstance(ob, dict->proto);
823 if (res == -1)
824 return NULL;
825 if (res) {
826 Py_INCREF(value);
827 return value;
828 }
829 }
830 ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
831 PyErr_Format(PyExc_TypeError,
832 "expected %s instance instead of pointer to %s",
833 ((PyTypeObject *)type)->tp_name, ob_name);
834 return NULL;
835 }
836
837 if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
838 return NULL;
839 }
840 if (as_parameter) {
841 value = CDataType_from_param(type, as_parameter);
842 Py_DECREF(as_parameter);
843 return value;
844 }
845 PyErr_Format(PyExc_TypeError,
846 "expected %s instance instead of %s",
847 ((PyTypeObject *)type)->tp_name,
848 Py_TYPE(value)->tp_name);
849 return NULL;
850 }
851
852 static PyMethodDef CDataType_methods[] = {
853 { "from_param", CDataType_from_param, METH_O, from_param_doc },
854 { "from_address", CDataType_from_address, METH_O, from_address_doc },
855 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
856 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
857 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
858 { NULL, NULL },
859 };
860
861 static PyObject *
CDataType_repeat(PyObject * self,Py_ssize_t length)862 CDataType_repeat(PyObject *self, Py_ssize_t length)
863 {
864 if (length < 0)
865 return PyErr_Format(PyExc_ValueError,
866 "Array length must be >= 0, not %zd",
867 length);
868 return PyCArrayType_from_ctype(self, length);
869 }
870
871 static PySequenceMethods CDataType_as_sequence = {
872 0, /* inquiry sq_length; */
873 0, /* binaryfunc sq_concat; */
874 CDataType_repeat, /* intargfunc sq_repeat; */
875 0, /* intargfunc sq_item; */
876 0, /* intintargfunc sq_slice; */
877 0, /* intobjargproc sq_ass_item; */
878 0, /* intintobjargproc sq_ass_slice; */
879 0, /* objobjproc sq_contains; */
880
881 0, /* binaryfunc sq_inplace_concat; */
882 0, /* intargfunc sq_inplace_repeat; */
883 };
884
885 static int
CDataType_clear(PyTypeObject * self)886 CDataType_clear(PyTypeObject *self)
887 {
888 StgDictObject *dict = PyType_stgdict((PyObject *)self);
889 if (dict)
890 Py_CLEAR(dict->proto);
891 return PyType_Type.tp_clear((PyObject *)self);
892 }
893
894 static int
CDataType_traverse(PyTypeObject * self,visitproc visit,void * arg)895 CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
896 {
897 StgDictObject *dict = PyType_stgdict((PyObject *)self);
898 if (dict)
899 Py_VISIT(dict->proto);
900 return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
901 }
902
903 static int
PyCStructType_setattro(PyObject * self,PyObject * key,PyObject * value)904 PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
905 {
906 /* XXX Should we disallow deleting _fields_? */
907 if (-1 == PyType_Type.tp_setattro(self, key, value))
908 return -1;
909
910 if (value && PyUnicode_Check(key) &&
911 _PyUnicode_EqualToASCIIString(key, "_fields_"))
912 return PyCStructUnionType_update_stgdict(self, value, 1);
913 return 0;
914 }
915
916
917 static int
UnionType_setattro(PyObject * self,PyObject * key,PyObject * value)918 UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
919 {
920 /* XXX Should we disallow deleting _fields_? */
921 if (-1 == PyObject_GenericSetAttr(self, key, value))
922 return -1;
923
924 if (PyUnicode_Check(key) &&
925 _PyUnicode_EqualToASCIIString(key, "_fields_"))
926 return PyCStructUnionType_update_stgdict(self, value, 0);
927 return 0;
928 }
929
930
931 PyTypeObject PyCStructType_Type = {
932 PyVarObject_HEAD_INIT(NULL, 0)
933 "_ctypes.PyCStructType", /* tp_name */
934 0, /* tp_basicsize */
935 0, /* tp_itemsize */
936 0, /* tp_dealloc */
937 0, /* tp_vectorcall_offset */
938 0, /* tp_getattr */
939 0, /* tp_setattr */
940 0, /* tp_as_async */
941 0, /* tp_repr */
942 0, /* tp_as_number */
943 &CDataType_as_sequence, /* tp_as_sequence */
944 0, /* tp_as_mapping */
945 0, /* tp_hash */
946 0, /* tp_call */
947 0, /* tp_str */
948 0, /* tp_getattro */
949 PyCStructType_setattro, /* tp_setattro */
950 0, /* tp_as_buffer */
951 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
952 PyDoc_STR("metatype for the CData Objects"), /* tp_doc */
953 (traverseproc)CDataType_traverse, /* tp_traverse */
954 (inquiry)CDataType_clear, /* tp_clear */
955 0, /* tp_richcompare */
956 0, /* tp_weaklistoffset */
957 0, /* tp_iter */
958 0, /* tp_iternext */
959 CDataType_methods, /* tp_methods */
960 0, /* tp_members */
961 0, /* tp_getset */
962 0, /* tp_base */
963 0, /* tp_dict */
964 0, /* tp_descr_get */
965 0, /* tp_descr_set */
966 0, /* tp_dictoffset */
967 0, /* tp_init */
968 0, /* tp_alloc */
969 PyCStructType_new, /* tp_new */
970 0, /* tp_free */
971 };
972
973 static PyTypeObject UnionType_Type = {
974 PyVarObject_HEAD_INIT(NULL, 0)
975 "_ctypes.UnionType", /* tp_name */
976 0, /* tp_basicsize */
977 0, /* tp_itemsize */
978 0, /* tp_dealloc */
979 0, /* tp_vectorcall_offset */
980 0, /* tp_getattr */
981 0, /* tp_setattr */
982 0, /* tp_as_async */
983 0, /* tp_repr */
984 0, /* tp_as_number */
985 &CDataType_as_sequence, /* tp_as_sequence */
986 0, /* tp_as_mapping */
987 0, /* tp_hash */
988 0, /* tp_call */
989 0, /* tp_str */
990 0, /* tp_getattro */
991 UnionType_setattro, /* tp_setattro */
992 0, /* tp_as_buffer */
993 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
994 PyDoc_STR("metatype for the CData Objects"), /* tp_doc */
995 (traverseproc)CDataType_traverse, /* tp_traverse */
996 (inquiry)CDataType_clear, /* tp_clear */
997 0, /* tp_richcompare */
998 0, /* tp_weaklistoffset */
999 0, /* tp_iter */
1000 0, /* tp_iternext */
1001 CDataType_methods, /* tp_methods */
1002 0, /* tp_members */
1003 0, /* tp_getset */
1004 0, /* tp_base */
1005 0, /* tp_dict */
1006 0, /* tp_descr_get */
1007 0, /* tp_descr_set */
1008 0, /* tp_dictoffset */
1009 0, /* tp_init */
1010 0, /* tp_alloc */
1011 UnionType_new, /* tp_new */
1012 0, /* tp_free */
1013 };
1014
1015
1016 /******************************************************************/
1017
1018 /*
1019
1020 The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be
1021 created. It must check for a _type_ attribute in the class. Since are no
1022 runtime created properties, a CField is probably *not* needed ?
1023
1024 class IntPointer(Pointer):
1025 _type_ = "i"
1026
1027 The PyCPointer_Type provides the functionality: a contents method/property, a
1028 size property/method, and the sequence protocol.
1029
1030 */
1031
1032 static int
PyCPointerType_SetProto(StgDictObject * stgdict,PyObject * proto)1033 PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
1034 {
1035 if (!proto || !PyType_Check(proto)) {
1036 PyErr_SetString(PyExc_TypeError,
1037 "_type_ must be a type");
1038 return -1;
1039 }
1040 if (!PyType_stgdict(proto)) {
1041 PyErr_SetString(PyExc_TypeError,
1042 "_type_ must have storage info");
1043 return -1;
1044 }
1045 Py_INCREF(proto);
1046 Py_XSETREF(stgdict->proto, proto);
1047 return 0;
1048 }
1049
1050 static PyCArgObject *
PyCPointerType_paramfunc(CDataObject * self)1051 PyCPointerType_paramfunc(CDataObject *self)
1052 {
1053 PyCArgObject *parg;
1054
1055 parg = PyCArgObject_new();
1056 if (parg == NULL)
1057 return NULL;
1058
1059 parg->tag = 'P';
1060 parg->pffi_type = &ffi_type_pointer;
1061 Py_INCREF(self);
1062 parg->obj = (PyObject *)self;
1063 parg->value.p = *(void **)self->b_ptr;
1064 return parg;
1065 }
1066
1067 static PyObject *
PyCPointerType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1068 PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1069 {
1070 PyTypeObject *result;
1071 StgDictObject *stgdict;
1072 PyObject *proto;
1073 PyObject *typedict;
1074 _Py_IDENTIFIER(_type_);
1075
1076 typedict = PyTuple_GetItem(args, 2);
1077 if (!typedict)
1078 return NULL;
1079 /*
1080 stgdict items size, align, length contain info about pointers itself,
1081 stgdict->proto has info about the pointed to type!
1082 */
1083 stgdict = (StgDictObject *)_PyObject_CallNoArgs(
1084 (PyObject *)&PyCStgDict_Type);
1085 if (!stgdict)
1086 return NULL;
1087 stgdict->size = sizeof(void *);
1088 stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
1089 stgdict->length = 1;
1090 stgdict->ffi_type_pointer = ffi_type_pointer;
1091 stgdict->paramfunc = PyCPointerType_paramfunc;
1092 stgdict->flags |= TYPEFLAG_ISPOINTER;
1093
1094 proto = _PyDict_GetItemIdWithError(typedict, &PyId__type_); /* Borrowed ref */
1095 if (proto) {
1096 StgDictObject *itemdict;
1097 const char *current_format;
1098 if (-1 == PyCPointerType_SetProto(stgdict, proto)) {
1099 Py_DECREF((PyObject *)stgdict);
1100 return NULL;
1101 }
1102 itemdict = PyType_stgdict(proto);
1103 /* PyCPointerType_SetProto has verified proto has a stgdict. */
1104 assert(itemdict);
1105 /* If itemdict->format is NULL, then this is a pointer to an
1106 incomplete type. We create a generic format string
1107 'pointer to bytes' in this case. XXX Better would be to
1108 fix the format string later...
1109 */
1110 current_format = itemdict->format ? itemdict->format : "B";
1111 if (itemdict->shape != NULL) {
1112 /* pointer to an array: the shape needs to be prefixed */
1113 stgdict->format = _ctypes_alloc_format_string_with_shape(
1114 itemdict->ndim, itemdict->shape, "&", current_format);
1115 } else {
1116 stgdict->format = _ctypes_alloc_format_string("&", current_format);
1117 }
1118 if (stgdict->format == NULL) {
1119 Py_DECREF((PyObject *)stgdict);
1120 return NULL;
1121 }
1122 }
1123 else if (PyErr_Occurred()) {
1124 Py_DECREF((PyObject *)stgdict);
1125 return NULL;
1126 }
1127
1128 /* create the new instance (which is a class,
1129 since we are a metatype!) */
1130 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1131 if (result == NULL) {
1132 Py_DECREF((PyObject *)stgdict);
1133 return NULL;
1134 }
1135
1136 /* replace the class dict by our updated spam dict */
1137 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1138 Py_DECREF(result);
1139 Py_DECREF((PyObject *)stgdict);
1140 return NULL;
1141 }
1142 Py_SETREF(result->tp_dict, (PyObject *)stgdict);
1143
1144 return (PyObject *)result;
1145 }
1146
1147
1148 static PyObject *
PyCPointerType_set_type(PyTypeObject * self,PyObject * type)1149 PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
1150 {
1151 StgDictObject *dict;
1152 _Py_IDENTIFIER(_type_);
1153
1154 dict = PyType_stgdict((PyObject *)self);
1155 if (!dict) {
1156 PyErr_SetString(PyExc_TypeError,
1157 "abstract class");
1158 return NULL;
1159 }
1160
1161 if (-1 == PyCPointerType_SetProto(dict, type))
1162 return NULL;
1163
1164 if (-1 == _PyDict_SetItemId((PyObject *)dict, &PyId__type_, type))
1165 return NULL;
1166
1167 Py_RETURN_NONE;
1168 }
1169
1170 static PyObject *_byref(PyObject *);
1171
1172 static PyObject *
PyCPointerType_from_param(PyObject * type,PyObject * value)1173 PyCPointerType_from_param(PyObject *type, PyObject *value)
1174 {
1175 StgDictObject *typedict;
1176
1177 if (value == Py_None) {
1178 /* ConvParam will convert to a NULL pointer later */
1179 Py_INCREF(value);
1180 return value;
1181 }
1182
1183 typedict = PyType_stgdict(type);
1184 if (!typedict) {
1185 PyErr_SetString(PyExc_TypeError,
1186 "abstract class");
1187 return NULL;
1188 }
1189
1190 /* If we expect POINTER(<type>), but receive a <type> instance, accept
1191 it by calling byref(<type>).
1192 */
1193 switch (PyObject_IsInstance(value, typedict->proto)) {
1194 case 1:
1195 Py_INCREF(value); /* _byref steals a refcount */
1196 return _byref(value);
1197 case -1:
1198 return NULL;
1199 default:
1200 break;
1201 }
1202
1203 if (PointerObject_Check(value) || ArrayObject_Check(value)) {
1204 /* Array instances are also pointers when
1205 the item types are the same.
1206 */
1207 StgDictObject *v = PyObject_stgdict(value);
1208 assert(v); /* Cannot be NULL for pointer or array objects */
1209 int ret = PyObject_IsSubclass(v->proto, typedict->proto);
1210 if (ret < 0) {
1211 return NULL;
1212 }
1213 if (ret) {
1214 Py_INCREF(value);
1215 return value;
1216 }
1217 }
1218 return CDataType_from_param(type, value);
1219 }
1220
1221 static PyMethodDef PyCPointerType_methods[] = {
1222 { "from_address", CDataType_from_address, METH_O, from_address_doc },
1223 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
1224 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
1225 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
1226 { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc},
1227 { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O },
1228 { NULL, NULL },
1229 };
1230
1231 PyTypeObject PyCPointerType_Type = {
1232 PyVarObject_HEAD_INIT(NULL, 0)
1233 "_ctypes.PyCPointerType", /* tp_name */
1234 0, /* tp_basicsize */
1235 0, /* tp_itemsize */
1236 0, /* tp_dealloc */
1237 0, /* tp_vectorcall_offset */
1238 0, /* tp_getattr */
1239 0, /* tp_setattr */
1240 0, /* tp_as_async */
1241 0, /* tp_repr */
1242 0, /* tp_as_number */
1243 &CDataType_as_sequence, /* tp_as_sequence */
1244 0, /* tp_as_mapping */
1245 0, /* tp_hash */
1246 0, /* tp_call */
1247 0, /* tp_str */
1248 0, /* tp_getattro */
1249 0, /* tp_setattro */
1250 0, /* tp_as_buffer */
1251 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1252 PyDoc_STR("metatype for the Pointer Objects"), /* tp_doc */
1253 (traverseproc)CDataType_traverse, /* tp_traverse */
1254 (inquiry)CDataType_clear, /* tp_clear */
1255 0, /* tp_richcompare */
1256 0, /* tp_weaklistoffset */
1257 0, /* tp_iter */
1258 0, /* tp_iternext */
1259 PyCPointerType_methods, /* tp_methods */
1260 0, /* tp_members */
1261 0, /* tp_getset */
1262 0, /* tp_base */
1263 0, /* tp_dict */
1264 0, /* tp_descr_get */
1265 0, /* tp_descr_set */
1266 0, /* tp_dictoffset */
1267 0, /* tp_init */
1268 0, /* tp_alloc */
1269 PyCPointerType_new, /* tp_new */
1270 0, /* tp_free */
1271 };
1272
1273
1274 /******************************************************************/
1275 /*
1276 PyCArrayType_Type
1277 */
1278 /*
1279 PyCArrayType_new ensures that the new Array subclass created has a _length_
1280 attribute, and a _type_ attribute.
1281 */
1282
1283 static int
CharArray_set_raw(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))1284 CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
1285 {
1286 char *ptr;
1287 Py_ssize_t size;
1288 Py_buffer view;
1289
1290 if (value == NULL) {
1291 PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
1292 return -1;
1293 }
1294 if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
1295 return -1;
1296 size = view.len;
1297 ptr = view.buf;
1298 if (size > self->b_size) {
1299 PyErr_SetString(PyExc_ValueError,
1300 "byte string too long");
1301 goto fail;
1302 }
1303
1304 memcpy(self->b_ptr, ptr, size);
1305
1306 PyBuffer_Release(&view);
1307 return 0;
1308 fail:
1309 PyBuffer_Release(&view);
1310 return -1;
1311 }
1312
1313 static PyObject *
CharArray_get_raw(CDataObject * self,void * Py_UNUSED (ignored))1314 CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored))
1315 {
1316 return PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
1317 }
1318
1319 static PyObject *
CharArray_get_value(CDataObject * self,void * Py_UNUSED (ignored))1320 CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
1321 {
1322 Py_ssize_t i;
1323 char *ptr = self->b_ptr;
1324 for (i = 0; i < self->b_size; ++i)
1325 if (*ptr++ == '\0')
1326 break;
1327 return PyBytes_FromStringAndSize(self->b_ptr, i);
1328 }
1329
1330 static int
CharArray_set_value(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))1331 CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
1332 {
1333 const char *ptr;
1334 Py_ssize_t size;
1335
1336 if (value == NULL) {
1337 PyErr_SetString(PyExc_TypeError,
1338 "can't delete attribute");
1339 return -1;
1340 }
1341
1342 if (!PyBytes_Check(value)) {
1343 PyErr_Format(PyExc_TypeError,
1344 "bytes expected instead of %s instance",
1345 Py_TYPE(value)->tp_name);
1346 return -1;
1347 } else
1348 Py_INCREF(value);
1349 size = PyBytes_GET_SIZE(value);
1350 if (size > self->b_size) {
1351 PyErr_SetString(PyExc_ValueError,
1352 "byte string too long");
1353 Py_DECREF(value);
1354 return -1;
1355 }
1356
1357 ptr = PyBytes_AS_STRING(value);
1358 memcpy(self->b_ptr, ptr, size);
1359 if (size < self->b_size)
1360 self->b_ptr[size] = '\0';
1361 Py_DECREF(value);
1362
1363 return 0;
1364 }
1365
1366 static PyGetSetDef CharArray_getsets[] = {
1367 { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
1368 "value", NULL },
1369 { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
1370 "string value"},
1371 { NULL, NULL }
1372 };
1373
1374 static PyObject *
WCharArray_get_value(CDataObject * self,void * Py_UNUSED (ignored))1375 WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
1376 {
1377 Py_ssize_t i;
1378 wchar_t *ptr = (wchar_t *)self->b_ptr;
1379 for (i = 0; i < self->b_size/(Py_ssize_t)sizeof(wchar_t); ++i)
1380 if (*ptr++ == (wchar_t)0)
1381 break;
1382 return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
1383 }
1384
1385 static int
WCharArray_set_value(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))1386 WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
1387 {
1388 if (value == NULL) {
1389 PyErr_SetString(PyExc_TypeError,
1390 "can't delete attribute");
1391 return -1;
1392 }
1393 if (!PyUnicode_Check(value)) {
1394 PyErr_Format(PyExc_TypeError,
1395 "unicode string expected instead of %s instance",
1396 Py_TYPE(value)->tp_name);
1397 return -1;
1398 }
1399
1400 Py_ssize_t size = self->b_size / sizeof(wchar_t);
1401 Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0);
1402 if (len < 0) {
1403 return -1;
1404 }
1405 // PyUnicode_AsWideChar() returns number of wchars including trailing null byte,
1406 // when it is called with NULL.
1407 assert(len > 0);
1408 if (len - 1 > size) {
1409 PyErr_SetString(PyExc_ValueError, "string too long");
1410 return -1;
1411 }
1412 if (PyUnicode_AsWideChar(value, (wchar_t *)self->b_ptr, size) < 0) {
1413 return -1;
1414 }
1415 return 0;
1416 }
1417
1418 static PyGetSetDef WCharArray_getsets[] = {
1419 { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
1420 "string value"},
1421 { NULL, NULL }
1422 };
1423
1424 /*
1425 The next function is copied from Python's typeobject.c.
1426
1427 It is used to attach getsets to a type *after* it
1428 has been created: Arrays of characters have additional getsets to treat them
1429 as strings.
1430 */
1431
1432 static int
add_getset(PyTypeObject * type,PyGetSetDef * gsp)1433 add_getset(PyTypeObject *type, PyGetSetDef *gsp)
1434 {
1435 PyObject *dict = type->tp_dict;
1436 for (; gsp->name != NULL; gsp++) {
1437 PyObject *descr;
1438 descr = PyDescr_NewGetSet(type, gsp);
1439 if (descr == NULL)
1440 return -1;
1441 if (PyDict_SetItemString(dict, gsp->name, descr) < 0) {
1442 Py_DECREF(descr);
1443 return -1;
1444 }
1445 Py_DECREF(descr);
1446 }
1447 return 0;
1448 }
1449
1450 static PyCArgObject *
PyCArrayType_paramfunc(CDataObject * self)1451 PyCArrayType_paramfunc(CDataObject *self)
1452 {
1453 PyCArgObject *p = PyCArgObject_new();
1454 if (p == NULL)
1455 return NULL;
1456 p->tag = 'P';
1457 p->pffi_type = &ffi_type_pointer;
1458 p->value.p = (char *)self->b_ptr;
1459 Py_INCREF(self);
1460 p->obj = (PyObject *)self;
1461 return p;
1462 }
1463
1464 static PyObject *
PyCArrayType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)1465 PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1466 {
1467 _Py_IDENTIFIER(_length_);
1468 _Py_IDENTIFIER(_type_);
1469 PyTypeObject *result;
1470 StgDictObject *stgdict;
1471 StgDictObject *itemdict;
1472 PyObject *length_attr, *type_attr;
1473 Py_ssize_t length;
1474 Py_ssize_t itemsize, itemalign;
1475
1476 /* create the new instance (which is a class,
1477 since we are a metatype!) */
1478 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1479 if (result == NULL)
1480 return NULL;
1481
1482 /* Initialize these variables to NULL so that we can simplify error
1483 handling by using Py_XDECREF. */
1484 stgdict = NULL;
1485 type_attr = NULL;
1486
1487 if (_PyObject_LookupAttrId((PyObject *)result, &PyId__length_, &length_attr) < 0) {
1488 goto error;
1489 }
1490 if (!length_attr) {
1491 PyErr_SetString(PyExc_AttributeError,
1492 "class must define a '_length_' attribute");
1493 goto error;
1494 }
1495
1496 if (!PyLong_Check(length_attr)) {
1497 Py_DECREF(length_attr);
1498 PyErr_SetString(PyExc_TypeError,
1499 "The '_length_' attribute must be an integer");
1500 goto error;
1501 }
1502
1503 if (_PyLong_Sign(length_attr) == -1) {
1504 Py_DECREF(length_attr);
1505 PyErr_SetString(PyExc_ValueError,
1506 "The '_length_' attribute must not be negative");
1507 goto error;
1508 }
1509
1510 length = PyLong_AsSsize_t(length_attr);
1511 Py_DECREF(length_attr);
1512 if (length == -1 && PyErr_Occurred()) {
1513 if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1514 PyErr_SetString(PyExc_OverflowError,
1515 "The '_length_' attribute is too large");
1516 }
1517 goto error;
1518 }
1519
1520 if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &type_attr) < 0) {
1521 goto error;
1522 }
1523 if (!type_attr) {
1524 PyErr_SetString(PyExc_AttributeError,
1525 "class must define a '_type_' attribute");
1526 goto error;
1527 }
1528
1529 stgdict = (StgDictObject *)_PyObject_CallNoArgs(
1530 (PyObject *)&PyCStgDict_Type);
1531 if (!stgdict)
1532 goto error;
1533
1534 itemdict = PyType_stgdict(type_attr);
1535 if (!itemdict) {
1536 PyErr_SetString(PyExc_TypeError,
1537 "_type_ must have storage info");
1538 goto error;
1539 }
1540
1541 assert(itemdict->format);
1542 stgdict->format = _ctypes_alloc_format_string(NULL, itemdict->format);
1543 if (stgdict->format == NULL)
1544 goto error;
1545 stgdict->ndim = itemdict->ndim + 1;
1546 stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t) * stgdict->ndim);
1547 if (stgdict->shape == NULL) {
1548 PyErr_NoMemory();
1549 goto error;
1550 }
1551 stgdict->shape[0] = length;
1552 if (stgdict->ndim > 1) {
1553 memmove(&stgdict->shape[1], itemdict->shape,
1554 sizeof(Py_ssize_t) * (stgdict->ndim - 1));
1555 }
1556
1557 itemsize = itemdict->size;
1558 if (itemsize != 0 && length > PY_SSIZE_T_MAX / itemsize) {
1559 PyErr_SetString(PyExc_OverflowError,
1560 "array too large");
1561 goto error;
1562 }
1563
1564 itemalign = itemdict->align;
1565
1566 if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
1567 stgdict->flags |= TYPEFLAG_HASPOINTER;
1568
1569 stgdict->size = itemsize * length;
1570 stgdict->align = itemalign;
1571 stgdict->length = length;
1572 stgdict->proto = type_attr;
1573 type_attr = NULL;
1574
1575 stgdict->paramfunc = &PyCArrayType_paramfunc;
1576
1577 /* Arrays are passed as pointers to function calls. */
1578 stgdict->ffi_type_pointer = ffi_type_pointer;
1579
1580 /* replace the class dict by our updated spam dict */
1581 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict))
1582 goto error;
1583 Py_SETREF(result->tp_dict, (PyObject *)stgdict); /* steal the reference */
1584 stgdict = NULL;
1585
1586 /* Special case for character arrays.
1587 A permanent annoyance: char arrays are also strings!
1588 */
1589 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
1590 if (-1 == add_getset(result, CharArray_getsets))
1591 goto error;
1592 }
1593 else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
1594 if (-1 == add_getset(result, WCharArray_getsets))
1595 goto error;
1596 }
1597
1598 return (PyObject *)result;
1599 error:
1600 Py_XDECREF((PyObject*)stgdict);
1601 Py_XDECREF(type_attr);
1602 Py_DECREF(result);
1603 return NULL;
1604 }
1605
1606 PyTypeObject PyCArrayType_Type = {
1607 PyVarObject_HEAD_INIT(NULL, 0)
1608 "_ctypes.PyCArrayType", /* tp_name */
1609 0, /* tp_basicsize */
1610 0, /* tp_itemsize */
1611 0, /* tp_dealloc */
1612 0, /* tp_vectorcall_offset */
1613 0, /* tp_getattr */
1614 0, /* tp_setattr */
1615 0, /* tp_as_async */
1616 0, /* tp_repr */
1617 0, /* tp_as_number */
1618 &CDataType_as_sequence, /* tp_as_sequence */
1619 0, /* tp_as_mapping */
1620 0, /* tp_hash */
1621 0, /* tp_call */
1622 0, /* tp_str */
1623 0, /* tp_getattro */
1624 0, /* tp_setattro */
1625 0, /* tp_as_buffer */
1626 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1627 PyDoc_STR("metatype for the Array Objects"), /* tp_doc */
1628 0, /* tp_traverse */
1629 0, /* tp_clear */
1630 0, /* tp_richcompare */
1631 0, /* tp_weaklistoffset */
1632 0, /* tp_iter */
1633 0, /* tp_iternext */
1634 CDataType_methods, /* tp_methods */
1635 0, /* tp_members */
1636 0, /* tp_getset */
1637 0, /* tp_base */
1638 0, /* tp_dict */
1639 0, /* tp_descr_get */
1640 0, /* tp_descr_set */
1641 0, /* tp_dictoffset */
1642 0, /* tp_init */
1643 0, /* tp_alloc */
1644 PyCArrayType_new, /* tp_new */
1645 0, /* tp_free */
1646 };
1647
1648
1649 /******************************************************************/
1650 /*
1651 PyCSimpleType_Type
1652 */
1653 /*
1654
1655 PyCSimpleType_new ensures that the new Simple_Type subclass created has a valid
1656 _type_ attribute.
1657
1658 */
1659
1660 static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g";
1661
1662 static PyObject *
c_wchar_p_from_param(PyObject * type,PyObject * value)1663 c_wchar_p_from_param(PyObject *type, PyObject *value)
1664 {
1665 _Py_IDENTIFIER(_as_parameter_);
1666 PyObject *as_parameter;
1667 int res;
1668 if (value == Py_None) {
1669 Py_RETURN_NONE;
1670 }
1671 if (PyUnicode_Check(value)) {
1672 PyCArgObject *parg;
1673 struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1674
1675 parg = PyCArgObject_new();
1676 if (parg == NULL)
1677 return NULL;
1678 parg->pffi_type = &ffi_type_pointer;
1679 parg->tag = 'Z';
1680 parg->obj = fd->setfunc(&parg->value, value, 0);
1681 if (parg->obj == NULL) {
1682 Py_DECREF(parg);
1683 return NULL;
1684 }
1685 return (PyObject *)parg;
1686 }
1687 res = PyObject_IsInstance(value, type);
1688 if (res == -1)
1689 return NULL;
1690 if (res) {
1691 Py_INCREF(value);
1692 return value;
1693 }
1694 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1695 /* c_wchar array instance or pointer(c_wchar(...)) */
1696 StgDictObject *dt = PyObject_stgdict(value);
1697 StgDictObject *dict;
1698 assert(dt); /* Cannot be NULL for pointer or array objects */
1699 dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1700 if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1701 Py_INCREF(value);
1702 return value;
1703 }
1704 }
1705 if (PyCArg_CheckExact(value)) {
1706 /* byref(c_char(...)) */
1707 PyCArgObject *a = (PyCArgObject *)value;
1708 StgDictObject *dict = PyObject_stgdict(a->obj);
1709 if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1710 Py_INCREF(value);
1711 return value;
1712 }
1713 }
1714
1715 if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
1716 return NULL;
1717 }
1718 if (as_parameter) {
1719 value = c_wchar_p_from_param(type, as_parameter);
1720 Py_DECREF(as_parameter);
1721 return value;
1722 }
1723 /* XXX better message */
1724 PyErr_SetString(PyExc_TypeError,
1725 "wrong type");
1726 return NULL;
1727 }
1728
1729 static PyObject *
c_char_p_from_param(PyObject * type,PyObject * value)1730 c_char_p_from_param(PyObject *type, PyObject *value)
1731 {
1732 _Py_IDENTIFIER(_as_parameter_);
1733 PyObject *as_parameter;
1734 int res;
1735 if (value == Py_None) {
1736 Py_RETURN_NONE;
1737 }
1738 if (PyBytes_Check(value)) {
1739 PyCArgObject *parg;
1740 struct fielddesc *fd = _ctypes_get_fielddesc("z");
1741
1742 parg = PyCArgObject_new();
1743 if (parg == NULL)
1744 return NULL;
1745 parg->pffi_type = &ffi_type_pointer;
1746 parg->tag = 'z';
1747 parg->obj = fd->setfunc(&parg->value, value, 0);
1748 if (parg->obj == NULL) {
1749 Py_DECREF(parg);
1750 return NULL;
1751 }
1752 return (PyObject *)parg;
1753 }
1754 res = PyObject_IsInstance(value, type);
1755 if (res == -1)
1756 return NULL;
1757 if (res) {
1758 Py_INCREF(value);
1759 return value;
1760 }
1761 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1762 /* c_char array instance or pointer(c_char(...)) */
1763 StgDictObject *dt = PyObject_stgdict(value);
1764 StgDictObject *dict;
1765 assert(dt); /* Cannot be NULL for pointer or array objects */
1766 dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1767 if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1768 Py_INCREF(value);
1769 return value;
1770 }
1771 }
1772 if (PyCArg_CheckExact(value)) {
1773 /* byref(c_char(...)) */
1774 PyCArgObject *a = (PyCArgObject *)value;
1775 StgDictObject *dict = PyObject_stgdict(a->obj);
1776 if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1777 Py_INCREF(value);
1778 return value;
1779 }
1780 }
1781
1782 if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
1783 return NULL;
1784 }
1785 if (as_parameter) {
1786 value = c_char_p_from_param(type, as_parameter);
1787 Py_DECREF(as_parameter);
1788 return value;
1789 }
1790 /* XXX better message */
1791 PyErr_SetString(PyExc_TypeError,
1792 "wrong type");
1793 return NULL;
1794 }
1795
1796 static PyObject *
c_void_p_from_param(PyObject * type,PyObject * value)1797 c_void_p_from_param(PyObject *type, PyObject *value)
1798 {
1799 _Py_IDENTIFIER(_as_parameter_);
1800 StgDictObject *stgd;
1801 PyObject *as_parameter;
1802 int res;
1803
1804 /* None */
1805 if (value == Py_None) {
1806 Py_RETURN_NONE;
1807 }
1808 /* Should probably allow buffer interface as well */
1809 /* int, long */
1810 if (PyLong_Check(value)) {
1811 PyCArgObject *parg;
1812 struct fielddesc *fd = _ctypes_get_fielddesc("P");
1813
1814 parg = PyCArgObject_new();
1815 if (parg == NULL)
1816 return NULL;
1817 parg->pffi_type = &ffi_type_pointer;
1818 parg->tag = 'P';
1819 parg->obj = fd->setfunc(&parg->value, value, 0);
1820 if (parg->obj == NULL) {
1821 Py_DECREF(parg);
1822 return NULL;
1823 }
1824 return (PyObject *)parg;
1825 }
1826 /* XXX struni: remove later */
1827 /* bytes */
1828 if (PyBytes_Check(value)) {
1829 PyCArgObject *parg;
1830 struct fielddesc *fd = _ctypes_get_fielddesc("z");
1831
1832 parg = PyCArgObject_new();
1833 if (parg == NULL)
1834 return NULL;
1835 parg->pffi_type = &ffi_type_pointer;
1836 parg->tag = 'z';
1837 parg->obj = fd->setfunc(&parg->value, value, 0);
1838 if (parg->obj == NULL) {
1839 Py_DECREF(parg);
1840 return NULL;
1841 }
1842 return (PyObject *)parg;
1843 }
1844 /* unicode */
1845 if (PyUnicode_Check(value)) {
1846 PyCArgObject *parg;
1847 struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1848
1849 parg = PyCArgObject_new();
1850 if (parg == NULL)
1851 return NULL;
1852 parg->pffi_type = &ffi_type_pointer;
1853 parg->tag = 'Z';
1854 parg->obj = fd->setfunc(&parg->value, value, 0);
1855 if (parg->obj == NULL) {
1856 Py_DECREF(parg);
1857 return NULL;
1858 }
1859 return (PyObject *)parg;
1860 }
1861 /* c_void_p instance (or subclass) */
1862 res = PyObject_IsInstance(value, type);
1863 if (res == -1)
1864 return NULL;
1865 if (res) {
1866 /* c_void_p instances */
1867 Py_INCREF(value);
1868 return value;
1869 }
1870 /* ctypes array or pointer instance */
1871 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1872 /* Any array or pointer is accepted */
1873 Py_INCREF(value);
1874 return value;
1875 }
1876 /* byref(...) */
1877 if (PyCArg_CheckExact(value)) {
1878 /* byref(c_xxx()) */
1879 PyCArgObject *a = (PyCArgObject *)value;
1880 if (a->tag == 'P') {
1881 Py_INCREF(value);
1882 return value;
1883 }
1884 }
1885 /* function pointer */
1886 if (PyCFuncPtrObject_Check(value)) {
1887 PyCArgObject *parg;
1888 PyCFuncPtrObject *func;
1889 func = (PyCFuncPtrObject *)value;
1890 parg = PyCArgObject_new();
1891 if (parg == NULL)
1892 return NULL;
1893 parg->pffi_type = &ffi_type_pointer;
1894 parg->tag = 'P';
1895 Py_INCREF(value);
1896 parg->value.p = *(void **)func->b_ptr;
1897 parg->obj = value;
1898 return (PyObject *)parg;
1899 }
1900 /* c_char_p, c_wchar_p */
1901 stgd = PyObject_stgdict(value);
1902 if (stgd && CDataObject_Check(value) && stgd->proto && PyUnicode_Check(stgd->proto)) {
1903 PyCArgObject *parg;
1904
1905 switch (PyUnicode_AsUTF8(stgd->proto)[0]) {
1906 case 'z': /* c_char_p */
1907 case 'Z': /* c_wchar_p */
1908 parg = PyCArgObject_new();
1909 if (parg == NULL)
1910 return NULL;
1911 parg->pffi_type = &ffi_type_pointer;
1912 parg->tag = 'Z';
1913 Py_INCREF(value);
1914 parg->obj = value;
1915 /* Remember: b_ptr points to where the pointer is stored! */
1916 parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
1917 return (PyObject *)parg;
1918 }
1919 }
1920
1921 if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
1922 return NULL;
1923 }
1924 if (as_parameter) {
1925 value = c_void_p_from_param(type, as_parameter);
1926 Py_DECREF(as_parameter);
1927 return value;
1928 }
1929 /* XXX better message */
1930 PyErr_SetString(PyExc_TypeError,
1931 "wrong type");
1932 return NULL;
1933 }
1934
1935 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1936 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
1937 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1938
CreateSwappedType(PyTypeObject * type,PyObject * args,PyObject * kwds,PyObject * proto,struct fielddesc * fmt)1939 static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
1940 PyObject *proto, struct fielddesc *fmt)
1941 {
1942 PyTypeObject *result;
1943 StgDictObject *stgdict;
1944 PyObject *name = PyTuple_GET_ITEM(args, 0);
1945 PyObject *newname;
1946 PyObject *swapped_args;
1947 static PyObject *suffix;
1948 Py_ssize_t i;
1949
1950 swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
1951 if (!swapped_args)
1952 return NULL;
1953
1954 if (suffix == NULL)
1955 #ifdef WORDS_BIGENDIAN
1956 suffix = PyUnicode_InternFromString("_le");
1957 #else
1958 suffix = PyUnicode_InternFromString("_be");
1959 #endif
1960 if (suffix == NULL) {
1961 Py_DECREF(swapped_args);
1962 return NULL;
1963 }
1964
1965 newname = PyUnicode_Concat(name, suffix);
1966 if (newname == NULL) {
1967 Py_DECREF(swapped_args);
1968 return NULL;
1969 }
1970
1971 PyTuple_SET_ITEM(swapped_args, 0, newname);
1972 for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
1973 PyObject *v = PyTuple_GET_ITEM(args, i);
1974 Py_INCREF(v);
1975 PyTuple_SET_ITEM(swapped_args, i, v);
1976 }
1977
1978 /* create the new instance (which is a class,
1979 since we are a metatype!) */
1980 result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
1981 Py_DECREF(swapped_args);
1982 if (result == NULL)
1983 return NULL;
1984
1985 stgdict = (StgDictObject *)_PyObject_CallNoArgs(
1986 (PyObject *)&PyCStgDict_Type);
1987 if (!stgdict) {
1988 Py_DECREF(result);
1989 return NULL;
1990 }
1991
1992 stgdict->ffi_type_pointer = *fmt->pffi_type;
1993 stgdict->align = fmt->pffi_type->alignment;
1994 stgdict->length = 0;
1995 stgdict->size = fmt->pffi_type->size;
1996 stgdict->setfunc = fmt->setfunc_swapped;
1997 stgdict->getfunc = fmt->getfunc_swapped;
1998
1999 Py_INCREF(proto);
2000 stgdict->proto = proto;
2001
2002 /* replace the class dict by our updated spam dict */
2003 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2004 Py_DECREF(result);
2005 Py_DECREF((PyObject *)stgdict);
2006 return NULL;
2007 }
2008 Py_SETREF(result->tp_dict, (PyObject *)stgdict);
2009
2010 return (PyObject *)result;
2011 }
2012
2013 static PyCArgObject *
PyCSimpleType_paramfunc(CDataObject * self)2014 PyCSimpleType_paramfunc(CDataObject *self)
2015 {
2016 StgDictObject *dict;
2017 const char *fmt;
2018 PyCArgObject *parg;
2019 struct fielddesc *fd;
2020
2021 dict = PyObject_stgdict((PyObject *)self);
2022 assert(dict); /* Cannot be NULL for CDataObject instances */
2023 fmt = PyUnicode_AsUTF8(dict->proto);
2024 assert(fmt);
2025
2026 fd = _ctypes_get_fielddesc(fmt);
2027 assert(fd);
2028
2029 parg = PyCArgObject_new();
2030 if (parg == NULL)
2031 return NULL;
2032
2033 parg->tag = fmt[0];
2034 parg->pffi_type = fd->pffi_type;
2035 Py_INCREF(self);
2036 parg->obj = (PyObject *)self;
2037 memcpy(&parg->value, self->b_ptr, self->b_size);
2038 return parg;
2039 }
2040
2041 static PyObject *
PyCSimpleType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)2042 PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2043 {
2044 _Py_IDENTIFIER(_type_);
2045 PyTypeObject *result;
2046 StgDictObject *stgdict;
2047 PyObject *proto;
2048 const char *proto_str;
2049 Py_ssize_t proto_len;
2050 PyMethodDef *ml;
2051 struct fielddesc *fmt;
2052
2053 /* create the new instance (which is a class,
2054 since we are a metatype!) */
2055 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2056 if (result == NULL)
2057 return NULL;
2058
2059 if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &proto) < 0) {
2060 return NULL;
2061 }
2062 if (!proto) {
2063 PyErr_SetString(PyExc_AttributeError,
2064 "class must define a '_type_' attribute");
2065 error:
2066 Py_XDECREF(proto);
2067 Py_DECREF(result);
2068 return NULL;
2069 }
2070 if (PyUnicode_Check(proto)) {
2071 proto_str = PyUnicode_AsUTF8AndSize(proto, &proto_len);
2072 if (!proto_str)
2073 goto error;
2074 } else {
2075 PyErr_SetString(PyExc_TypeError,
2076 "class must define a '_type_' string attribute");
2077 goto error;
2078 }
2079 if (proto_len != 1) {
2080 PyErr_SetString(PyExc_ValueError,
2081 "class must define a '_type_' attribute "
2082 "which must be a string of length 1");
2083 goto error;
2084 }
2085 if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
2086 PyErr_Format(PyExc_AttributeError,
2087 "class must define a '_type_' attribute which must be\n"
2088 "a single character string containing one of '%s'.",
2089 SIMPLE_TYPE_CHARS);
2090 goto error;
2091 }
2092 fmt = _ctypes_get_fielddesc(proto_str);
2093 if (fmt == NULL) {
2094 PyErr_Format(PyExc_ValueError,
2095 "_type_ '%s' not supported", proto_str);
2096 goto error;
2097 }
2098
2099 stgdict = (StgDictObject *)_PyObject_CallNoArgs(
2100 (PyObject *)&PyCStgDict_Type);
2101 if (!stgdict)
2102 goto error;
2103
2104 stgdict->ffi_type_pointer = *fmt->pffi_type;
2105 stgdict->align = fmt->pffi_type->alignment;
2106 stgdict->length = 0;
2107 stgdict->size = fmt->pffi_type->size;
2108 stgdict->setfunc = fmt->setfunc;
2109 stgdict->getfunc = fmt->getfunc;
2110 #ifdef WORDS_BIGENDIAN
2111 stgdict->format = _ctypes_alloc_format_string_for_type(proto_str[0], 1);
2112 #else
2113 stgdict->format = _ctypes_alloc_format_string_for_type(proto_str[0], 0);
2114 #endif
2115 if (stgdict->format == NULL) {
2116 Py_DECREF(result);
2117 Py_DECREF(proto);
2118 Py_DECREF((PyObject *)stgdict);
2119 return NULL;
2120 }
2121
2122 stgdict->paramfunc = PyCSimpleType_paramfunc;
2123 /*
2124 if (result->tp_base != &Simple_Type) {
2125 stgdict->setfunc = NULL;
2126 stgdict->getfunc = NULL;
2127 }
2128 */
2129
2130 /* This consumes the refcount on proto which we have */
2131 stgdict->proto = proto;
2132
2133 /* replace the class dict by our updated spam dict */
2134 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2135 Py_DECREF(result);
2136 Py_DECREF((PyObject *)stgdict);
2137 return NULL;
2138 }
2139 Py_SETREF(result->tp_dict, (PyObject *)stgdict);
2140
2141 /* Install from_param class methods in ctypes base classes.
2142 Overrides the PyCSimpleType_from_param generic method.
2143 */
2144 if (result->tp_base == &Simple_Type) {
2145 switch (*proto_str) {
2146 case 'z': /* c_char_p */
2147 ml = &c_char_p_method;
2148 stgdict->flags |= TYPEFLAG_ISPOINTER;
2149 break;
2150 case 'Z': /* c_wchar_p */
2151 ml = &c_wchar_p_method;
2152 stgdict->flags |= TYPEFLAG_ISPOINTER;
2153 break;
2154 case 'P': /* c_void_p */
2155 ml = &c_void_p_method;
2156 stgdict->flags |= TYPEFLAG_ISPOINTER;
2157 break;
2158 case 's':
2159 case 'X':
2160 case 'O':
2161 ml = NULL;
2162 stgdict->flags |= TYPEFLAG_ISPOINTER;
2163 break;
2164 default:
2165 ml = NULL;
2166 break;
2167 }
2168
2169 if (ml) {
2170 PyObject *meth;
2171 int x;
2172 meth = PyDescr_NewClassMethod(result, ml);
2173 if (!meth) {
2174 Py_DECREF(result);
2175 return NULL;
2176 }
2177 x = PyDict_SetItemString(result->tp_dict,
2178 ml->ml_name,
2179 meth);
2180 Py_DECREF(meth);
2181 if (x == -1) {
2182 Py_DECREF(result);
2183 return NULL;
2184 }
2185 }
2186 }
2187
2188 if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
2189 PyObject *swapped = CreateSwappedType(type, args, kwds,
2190 proto, fmt);
2191 StgDictObject *sw_dict;
2192 if (swapped == NULL) {
2193 Py_DECREF(result);
2194 return NULL;
2195 }
2196 sw_dict = PyType_stgdict(swapped);
2197 #ifdef WORDS_BIGENDIAN
2198 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
2199 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
2200 PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
2201 PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
2202 /* We are creating the type for the OTHER endian */
2203 sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1);
2204 #else
2205 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
2206 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
2207 PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
2208 PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
2209 /* We are creating the type for the OTHER endian */
2210 sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1);
2211 #endif
2212 Py_DECREF(swapped);
2213 if (PyErr_Occurred()) {
2214 Py_DECREF(result);
2215 return NULL;
2216 }
2217 };
2218
2219 return (PyObject *)result;
2220 }
2221
2222 /*
2223 * This is a *class method*.
2224 * Convert a parameter into something that ConvParam can handle.
2225 */
2226 static PyObject *
PyCSimpleType_from_param(PyObject * type,PyObject * value)2227 PyCSimpleType_from_param(PyObject *type, PyObject *value)
2228 {
2229 _Py_IDENTIFIER(_as_parameter_);
2230 StgDictObject *dict;
2231 const char *fmt;
2232 PyCArgObject *parg;
2233 struct fielddesc *fd;
2234 PyObject *as_parameter;
2235 int res;
2236
2237 /* If the value is already an instance of the requested type,
2238 we can use it as is */
2239 res = PyObject_IsInstance(value, type);
2240 if (res == -1)
2241 return NULL;
2242 if (res) {
2243 Py_INCREF(value);
2244 return value;
2245 }
2246
2247 dict = PyType_stgdict(type);
2248 if (!dict) {
2249 PyErr_SetString(PyExc_TypeError,
2250 "abstract class");
2251 return NULL;
2252 }
2253
2254 /* I think we can rely on this being a one-character string */
2255 fmt = PyUnicode_AsUTF8(dict->proto);
2256 assert(fmt);
2257
2258 fd = _ctypes_get_fielddesc(fmt);
2259 assert(fd);
2260
2261 parg = PyCArgObject_new();
2262 if (parg == NULL)
2263 return NULL;
2264
2265 parg->tag = fmt[0];
2266 parg->pffi_type = fd->pffi_type;
2267 parg->obj = fd->setfunc(&parg->value, value, 0);
2268 if (parg->obj)
2269 return (PyObject *)parg;
2270 PyErr_Clear();
2271 Py_DECREF(parg);
2272
2273 if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
2274 return NULL;
2275 }
2276 if (as_parameter) {
2277 if (_Py_EnterRecursiveCall("while processing _as_parameter_")) {
2278 Py_DECREF(as_parameter);
2279 return NULL;
2280 }
2281 value = PyCSimpleType_from_param(type, as_parameter);
2282 _Py_LeaveRecursiveCall();
2283 Py_DECREF(as_parameter);
2284 return value;
2285 }
2286 PyErr_SetString(PyExc_TypeError,
2287 "wrong type");
2288 return NULL;
2289 }
2290
2291 static PyMethodDef PyCSimpleType_methods[] = {
2292 { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc },
2293 { "from_address", CDataType_from_address, METH_O, from_address_doc },
2294 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
2295 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
2296 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
2297 { NULL, NULL },
2298 };
2299
2300 PyTypeObject PyCSimpleType_Type = {
2301 PyVarObject_HEAD_INIT(NULL, 0)
2302 "_ctypes.PyCSimpleType", /* tp_name */
2303 0, /* tp_basicsize */
2304 0, /* tp_itemsize */
2305 0, /* tp_dealloc */
2306 0, /* tp_vectorcall_offset */
2307 0, /* tp_getattr */
2308 0, /* tp_setattr */
2309 0, /* tp_as_async */
2310 0, /* tp_repr */
2311 0, /* tp_as_number */
2312 &CDataType_as_sequence, /* tp_as_sequence */
2313 0, /* tp_as_mapping */
2314 0, /* tp_hash */
2315 0, /* tp_call */
2316 0, /* tp_str */
2317 0, /* tp_getattro */
2318 0, /* tp_setattro */
2319 0, /* tp_as_buffer */
2320 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2321 PyDoc_STR("metatype for the PyCSimpleType Objects"), /* tp_doc */
2322 0, /* tp_traverse */
2323 0, /* tp_clear */
2324 0, /* tp_richcompare */
2325 0, /* tp_weaklistoffset */
2326 0, /* tp_iter */
2327 0, /* tp_iternext */
2328 PyCSimpleType_methods, /* tp_methods */
2329 0, /* tp_members */
2330 0, /* tp_getset */
2331 0, /* tp_base */
2332 0, /* tp_dict */
2333 0, /* tp_descr_get */
2334 0, /* tp_descr_set */
2335 0, /* tp_dictoffset */
2336 0, /* tp_init */
2337 0, /* tp_alloc */
2338 PyCSimpleType_new, /* tp_new */
2339 0, /* tp_free */
2340 };
2341
2342 /******************************************************************/
2343 /*
2344 PyCFuncPtrType_Type
2345 */
2346
2347 static PyObject *
converters_from_argtypes(PyObject * ob)2348 converters_from_argtypes(PyObject *ob)
2349 {
2350 _Py_IDENTIFIER(from_param);
2351 PyObject *converters;
2352 Py_ssize_t i;
2353
2354 ob = PySequence_Tuple(ob); /* new reference */
2355 if (!ob) {
2356 PyErr_SetString(PyExc_TypeError,
2357 "_argtypes_ must be a sequence of types");
2358 return NULL;
2359 }
2360
2361 Py_ssize_t nArgs = PyTuple_GET_SIZE(ob);
2362 if (nArgs > CTYPES_MAX_ARGCOUNT) {
2363 Py_DECREF(ob);
2364 PyErr_Format(PyExc_ArgError,
2365 "_argtypes_ has too many arguments (%zi), maximum is %i",
2366 nArgs, CTYPES_MAX_ARGCOUNT);
2367 return NULL;
2368 }
2369
2370 converters = PyTuple_New(nArgs);
2371 if (!converters) {
2372 Py_DECREF(ob);
2373 return NULL;
2374 }
2375
2376 /* I have to check if this is correct. Using c_char, which has a size
2377 of 1, will be assumed to be pushed as only one byte!
2378 Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
2379 */
2380
2381 for (i = 0; i < nArgs; ++i) {
2382 PyObject *cnv;
2383 PyObject *tp = PyTuple_GET_ITEM(ob, i);
2384 /*
2385 * The following checks, relating to bpo-16575 and bpo-16576, have been
2386 * disabled. The reason is that, although there is a definite problem with
2387 * how libffi handles unions (https://github.com/libffi/libffi/issues/33),
2388 * there are numerous libraries which pass structures containing unions
2389 * by values - especially on Windows but examples also exist on Linux
2390 * (https://bugs.python.org/msg359834).
2391 *
2392 * It may not be possible to get proper support for unions and bitfields
2393 * until support is forthcoming in libffi, but for now, adding the checks
2394 * has caused problems in otherwise-working software, which suggests it
2395 * is better to disable the checks.
2396 *
2397 * Although specific examples reported relate specifically to unions and
2398 * not bitfields, the bitfields check is also being disabled as a
2399 * precaution.
2400
2401 StgDictObject *stgdict = PyType_stgdict(tp);
2402
2403 if (stgdict != NULL) {
2404 if (stgdict->flags & TYPEFLAG_HASUNION) {
2405 Py_DECREF(converters);
2406 Py_DECREF(ob);
2407 if (!PyErr_Occurred()) {
2408 PyErr_Format(PyExc_TypeError,
2409 "item %zd in _argtypes_ passes a union by "
2410 "value, which is unsupported.",
2411 i + 1);
2412 }
2413 return NULL;
2414 }
2415 if (stgdict->flags & TYPEFLAG_HASBITFIELD) {
2416 Py_DECREF(converters);
2417 Py_DECREF(ob);
2418 if (!PyErr_Occurred()) {
2419 PyErr_Format(PyExc_TypeError,
2420 "item %zd in _argtypes_ passes a struct/"
2421 "union with a bitfield by value, which is "
2422 "unsupported.",
2423 i + 1);
2424 }
2425 return NULL;
2426 }
2427 }
2428 */
2429
2430 if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) {
2431 Py_DECREF(converters);
2432 Py_DECREF(ob);
2433 if (!PyErr_Occurred()) {
2434 PyErr_Format(PyExc_TypeError,
2435 "item %zd in _argtypes_ has no from_param method",
2436 i+1);
2437 }
2438 return NULL;
2439 }
2440 PyTuple_SET_ITEM(converters, i, cnv);
2441 }
2442 Py_DECREF(ob);
2443 return converters;
2444 }
2445
2446 static int
make_funcptrtype_dict(StgDictObject * stgdict)2447 make_funcptrtype_dict(StgDictObject *stgdict)
2448 {
2449 PyObject *ob;
2450 PyObject *converters = NULL;
2451 _Py_IDENTIFIER(_flags_);
2452 _Py_IDENTIFIER(_argtypes_);
2453 _Py_IDENTIFIER(_restype_);
2454 _Py_IDENTIFIER(_check_retval_);
2455
2456 stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
2457 stgdict->length = 1;
2458 stgdict->size = sizeof(void *);
2459 stgdict->setfunc = NULL;
2460 stgdict->getfunc = NULL;
2461 stgdict->ffi_type_pointer = ffi_type_pointer;
2462
2463 ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__flags_);
2464 if (!ob || !PyLong_Check(ob)) {
2465 if (!PyErr_Occurred()) {
2466 PyErr_SetString(PyExc_TypeError,
2467 "class must define _flags_ which must be an integer");
2468 }
2469 return -1;
2470 }
2471 stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER;
2472
2473 /* _argtypes_ is optional... */
2474 ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__argtypes_);
2475 if (ob) {
2476 converters = converters_from_argtypes(ob);
2477 if (!converters)
2478 return -1;
2479 Py_INCREF(ob);
2480 stgdict->argtypes = ob;
2481 stgdict->converters = converters;
2482 }
2483 else if (PyErr_Occurred()) {
2484 return -1;
2485 }
2486
2487 ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__restype_);
2488 if (ob) {
2489 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2490 PyErr_SetString(PyExc_TypeError,
2491 "_restype_ must be a type, a callable, or None");
2492 return -1;
2493 }
2494 Py_INCREF(ob);
2495 stgdict->restype = ob;
2496 if (_PyObject_LookupAttrId(ob, &PyId__check_retval_,
2497 &stgdict->checker) < 0)
2498 {
2499 return -1;
2500 }
2501 }
2502 else if (PyErr_Occurred()) {
2503 return -1;
2504 }
2505 /* XXX later, maybe.
2506 ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__errcheck_);
2507 if (ob) {
2508 if (!PyCallable_Check(ob)) {
2509 PyErr_SetString(PyExc_TypeError,
2510 "_errcheck_ must be callable");
2511 return -1;
2512 }
2513 Py_INCREF(ob);
2514 stgdict->errcheck = ob;
2515 }
2516 else if (PyErr_Occurred()) {
2517 return -1;
2518 }
2519 */
2520 return 0;
2521 }
2522
2523 static PyCArgObject *
PyCFuncPtrType_paramfunc(CDataObject * self)2524 PyCFuncPtrType_paramfunc(CDataObject *self)
2525 {
2526 PyCArgObject *parg;
2527
2528 parg = PyCArgObject_new();
2529 if (parg == NULL)
2530 return NULL;
2531
2532 parg->tag = 'P';
2533 parg->pffi_type = &ffi_type_pointer;
2534 Py_INCREF(self);
2535 parg->obj = (PyObject *)self;
2536 parg->value.p = *(void **)self->b_ptr;
2537 return parg;
2538 }
2539
2540 static PyObject *
PyCFuncPtrType_new(PyTypeObject * type,PyObject * args,PyObject * kwds)2541 PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2542 {
2543 PyTypeObject *result;
2544 StgDictObject *stgdict;
2545
2546 stgdict = (StgDictObject *)_PyObject_CallNoArgs(
2547 (PyObject *)&PyCStgDict_Type);
2548 if (!stgdict)
2549 return NULL;
2550
2551 stgdict->paramfunc = PyCFuncPtrType_paramfunc;
2552 /* We do NOT expose the function signature in the format string. It
2553 is impossible, generally, because the only requirement for the
2554 argtypes items is that they have a .from_param method - we do not
2555 know the types of the arguments (although, in practice, most
2556 argtypes would be a ctypes type).
2557 */
2558 stgdict->format = _ctypes_alloc_format_string(NULL, "X{}");
2559 if (stgdict->format == NULL) {
2560 Py_DECREF((PyObject *)stgdict);
2561 return NULL;
2562 }
2563 stgdict->flags |= TYPEFLAG_ISPOINTER;
2564
2565 /* create the new instance (which is a class,
2566 since we are a metatype!) */
2567 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2568 if (result == NULL) {
2569 Py_DECREF((PyObject *)stgdict);
2570 return NULL;
2571 }
2572
2573 /* replace the class dict by our updated storage dict */
2574 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2575 Py_DECREF(result);
2576 Py_DECREF((PyObject *)stgdict);
2577 return NULL;
2578 }
2579 Py_SETREF(result->tp_dict, (PyObject *)stgdict);
2580
2581 if (-1 == make_funcptrtype_dict(stgdict)) {
2582 Py_DECREF(result);
2583 return NULL;
2584 }
2585
2586 return (PyObject *)result;
2587 }
2588
2589 PyTypeObject PyCFuncPtrType_Type = {
2590 PyVarObject_HEAD_INIT(NULL, 0)
2591 "_ctypes.PyCFuncPtrType", /* tp_name */
2592 0, /* tp_basicsize */
2593 0, /* tp_itemsize */
2594 0, /* tp_dealloc */
2595 0, /* tp_vectorcall_offset */
2596 0, /* tp_getattr */
2597 0, /* tp_setattr */
2598 0, /* tp_as_async */
2599 0, /* tp_repr */
2600 0, /* tp_as_number */
2601 &CDataType_as_sequence, /* tp_as_sequence */
2602 0, /* tp_as_mapping */
2603 0, /* tp_hash */
2604 0, /* tp_call */
2605 0, /* tp_str */
2606 0, /* tp_getattro */
2607 0, /* tp_setattro */
2608 0, /* tp_as_buffer */
2609 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2610 PyDoc_STR("metatype for C function pointers"), /* tp_doc */
2611 (traverseproc)CDataType_traverse, /* tp_traverse */
2612 (inquiry)CDataType_clear, /* tp_clear */
2613 0, /* tp_richcompare */
2614 0, /* tp_weaklistoffset */
2615 0, /* tp_iter */
2616 0, /* tp_iternext */
2617 CDataType_methods, /* tp_methods */
2618 0, /* tp_members */
2619 0, /* tp_getset */
2620 0, /* tp_base */
2621 0, /* tp_dict */
2622 0, /* tp_descr_get */
2623 0, /* tp_descr_set */
2624 0, /* tp_dictoffset */
2625 0, /* tp_init */
2626 0, /* tp_alloc */
2627 PyCFuncPtrType_new, /* tp_new */
2628 0, /* tp_free */
2629 };
2630
2631
2632 /*****************************************************************
2633 * Code to keep needed objects alive
2634 */
2635
2636 static CDataObject *
PyCData_GetContainer(CDataObject * self)2637 PyCData_GetContainer(CDataObject *self)
2638 {
2639 while (self->b_base)
2640 self = self->b_base;
2641 if (self->b_objects == NULL) {
2642 if (self->b_length) {
2643 self->b_objects = PyDict_New();
2644 if (self->b_objects == NULL)
2645 return NULL;
2646 } else {
2647 Py_INCREF(Py_None);
2648 self->b_objects = Py_None;
2649 }
2650 }
2651 return self;
2652 }
2653
2654 static PyObject *
GetKeepedObjects(CDataObject * target)2655 GetKeepedObjects(CDataObject *target)
2656 {
2657 CDataObject *container;
2658 container = PyCData_GetContainer(target);
2659 if (container == NULL)
2660 return NULL;
2661 return container->b_objects;
2662 }
2663
2664 static PyObject *
unique_key(CDataObject * target,Py_ssize_t index)2665 unique_key(CDataObject *target, Py_ssize_t index)
2666 {
2667 char string[256];
2668 char *cp = string;
2669 size_t bytes_left;
2670
2671 Py_BUILD_ASSERT(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
2672 cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2673 while (target->b_base) {
2674 bytes_left = sizeof(string) - (cp - string) - 1;
2675 /* Hex format needs 2 characters per byte */
2676 if (bytes_left < sizeof(Py_ssize_t) * 2) {
2677 PyErr_SetString(PyExc_ValueError,
2678 "ctypes object structure too deep");
2679 return NULL;
2680 }
2681 cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
2682 target = target->b_base;
2683 }
2684 return PyUnicode_FromStringAndSize(string, cp-string);
2685 }
2686
2687 /*
2688 * Keep a reference to 'keep' in the 'target', at index 'index'.
2689 *
2690 * If 'keep' is None, do nothing.
2691 *
2692 * Otherwise create a dictionary (if it does not yet exist) id the root
2693 * objects 'b_objects' item, which will store the 'keep' object under a unique
2694 * key.
2695 *
2696 * The unique_key helper travels the target's b_base pointer down to the root,
2697 * building a string containing hex-formatted indexes found during traversal,
2698 * separated by colons.
2699 *
2700 * The index tuple is used as a key into the root object's b_objects dict.
2701 *
2702 * Note: This function steals a refcount of the third argument, even if it
2703 * fails!
2704 */
2705 static int
KeepRef(CDataObject * target,Py_ssize_t index,PyObject * keep)2706 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
2707 {
2708 int result;
2709 CDataObject *ob;
2710 PyObject *key;
2711
2712 /* Optimization: no need to store None */
2713 if (keep == Py_None) {
2714 Py_DECREF(Py_None);
2715 return 0;
2716 }
2717 ob = PyCData_GetContainer(target);
2718 if (ob == NULL) {
2719 Py_DECREF(keep);
2720 return -1;
2721 }
2722 if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
2723 Py_XSETREF(ob->b_objects, keep); /* refcount consumed */
2724 return 0;
2725 }
2726 key = unique_key(target, index);
2727 if (key == NULL) {
2728 Py_DECREF(keep);
2729 return -1;
2730 }
2731 result = PyDict_SetItem(ob->b_objects, key, keep);
2732 Py_DECREF(key);
2733 Py_DECREF(keep);
2734 return result;
2735 }
2736
2737 /******************************************************************/
2738 /*
2739 PyCData_Type
2740 */
2741 static int
PyCData_traverse(CDataObject * self,visitproc visit,void * arg)2742 PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
2743 {
2744 Py_VISIT(self->b_objects);
2745 Py_VISIT((PyObject *)self->b_base);
2746 return 0;
2747 }
2748
2749 static int
PyCData_clear(CDataObject * self)2750 PyCData_clear(CDataObject *self)
2751 {
2752 Py_CLEAR(self->b_objects);
2753 if ((self->b_needsfree)
2754 && _CDataObject_HasExternalBuffer(self))
2755 PyMem_Free(self->b_ptr);
2756 self->b_ptr = NULL;
2757 Py_CLEAR(self->b_base);
2758 return 0;
2759 }
2760
2761 static void
PyCData_dealloc(PyObject * self)2762 PyCData_dealloc(PyObject *self)
2763 {
2764 PyCData_clear((CDataObject *)self);
2765 Py_TYPE(self)->tp_free(self);
2766 }
2767
2768 static PyMemberDef PyCData_members[] = {
2769 { "_b_base_", T_OBJECT,
2770 offsetof(CDataObject, b_base), READONLY,
2771 "the base object" },
2772 { "_b_needsfree_", T_INT,
2773 offsetof(CDataObject, b_needsfree), READONLY,
2774 "whether the object owns the memory or not" },
2775 { "_objects", T_OBJECT,
2776 offsetof(CDataObject, b_objects), READONLY,
2777 "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2778 { NULL },
2779 };
2780
2781 /* Find the innermost type of an array type, returning a borrowed reference */
2782 static PyObject *
PyCData_item_type(PyObject * type)2783 PyCData_item_type(PyObject *type)
2784 {
2785 if (PyCArrayTypeObject_Check(type)) {
2786 StgDictObject *stg_dict;
2787 PyObject *elem_type;
2788
2789 /* asserts used here as these are all guaranteed by construction */
2790 stg_dict = PyType_stgdict(type);
2791 assert(stg_dict);
2792 elem_type = stg_dict->proto;
2793 assert(elem_type);
2794 return PyCData_item_type(elem_type);
2795 }
2796 else {
2797 return type;
2798 }
2799 }
2800
2801 static int
PyCData_NewGetBuffer(PyObject * myself,Py_buffer * view,int flags)2802 PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
2803 {
2804 CDataObject *self = (CDataObject *)myself;
2805 StgDictObject *dict = PyObject_stgdict(myself);
2806 PyObject *item_type = PyCData_item_type((PyObject*)Py_TYPE(myself));
2807 StgDictObject *item_dict = PyType_stgdict(item_type);
2808
2809 if (view == NULL) return 0;
2810
2811 view->buf = self->b_ptr;
2812 view->obj = myself;
2813 Py_INCREF(myself);
2814 view->len = self->b_size;
2815 view->readonly = 0;
2816 /* use default format character if not set */
2817 view->format = dict->format ? dict->format : "B";
2818 view->ndim = dict->ndim;
2819 view->shape = dict->shape;
2820 view->itemsize = item_dict->size;
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 PyDoc_STR("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_CallNoArgs(ob);
3989 else
3990 /* Create an instance of the pointed-to type */
3991 ob = _PyObject_CallNoArgs(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 PyDoc_STR("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 PyDoc_STR("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 PyDoc_STR("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__", 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 PyDoc_STR("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 PyDoc_STR("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 PyDoc_STR("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 PyDoc_STRVAR(_ctypes__doc__,
5473 "Create and manipulate C compatible data types in Python.");
5474
5475 #ifdef MS_WIN32
5476
5477 PyDoc_STRVAR(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_CallNoArgs(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 = _ctypes__doc__,
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("CTYPES_MAX_ARGCOUNT", PyLong_FromLong(CTYPES_MAX_ARGCOUNT));
5806 MOD_ADD("ArgumentError", Py_NewRef(PyExc_ArgError));
5807 return 0;
5808 #undef MOD_ADD
5809 }
5810
5811
5812 static int
_ctypes_mod_exec(PyObject * mod)5813 _ctypes_mod_exec(PyObject *mod)
5814 {
5815 _unpickle = PyObject_GetAttrString(mod, "_unpickle");
5816 if (_unpickle == NULL) {
5817 return -1;
5818 }
5819
5820 _ctypes_ptrtype_cache = PyDict_New();
5821 if (_ctypes_ptrtype_cache == NULL) {
5822 return -1;
5823 }
5824
5825 PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5826 if (!PyExc_ArgError) {
5827 return -1;
5828 }
5829
5830 if (_ctypes_add_types(mod) < 0) {
5831 return -1;
5832 }
5833 #ifdef MS_WIN32
5834 ComError = (PyObject*)&PyComError_Type;
5835 #endif
5836
5837 if (_ctypes_add_objects(mod) < 0) {
5838 return -1;
5839 }
5840 return 0;
5841 }
5842
5843
5844 PyMODINIT_FUNC
PyInit__ctypes(void)5845 PyInit__ctypes(void)
5846 {
5847 PyObject *mod = PyModule_Create(&_ctypesmodule);
5848 if (!mod) {
5849 return NULL;
5850 }
5851
5852 if (_ctypes_mod_exec(mod) < 0) {
5853 Py_DECREF(mod);
5854 return NULL;
5855 }
5856 return mod;
5857 }
5858
5859 /*
5860 Local Variables:
5861 compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
5862 End:
5863 */
5864