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