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