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