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