Issue #5768: Change to Unicode output logic and test case for same.
[python.git] / Modules / _ctypes / _ctypes.c
blob43da2095cdfea6188bb06eab68d2de857ce4bb71
1 /*****************************************************************
2 This file should be kept compatible with Python 2.3, see PEP 291.
3 *****************************************************************/
6 /*
7 ToDo:
9 Get rid of the checker (and also the converters) field in CFuncPtrObject and
10 StgDictObject, and replace them by slot functions in StgDictObject.
12 think about a buffer-like object (memory? bytes?)
14 Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
15 What about c_char and c_wchar arrays then?
17 Add from_mmap, from_file, from_string metaclass methods.
19 Maybe we can get away with from_file (calls read) and with a from_buffer
20 method?
22 And what about the to_mmap, to_file, to_str(?) methods? They would clobber
23 the namespace, probably. So, functions instead? And we already have memmove...
28 Name methods, members, getsets
29 ==============================================================================
31 StructType_Type __new__(), from_address(), __mul__(), from_param()
32 UnionType_Type __new__(), from_address(), __mul__(), from_param()
33 PointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type()
34 ArrayType_Type __new__(), from_address(), __mul__(), from_param()
35 SimpleType_Type __new__(), from_address(), __mul__(), from_param()
37 CData_Type
38 Struct_Type __new__(), __init__()
39 Pointer_Type __new__(), __init__(), _as_parameter_, contents
40 Array_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
41 Simple_Type __new__(), __init__(), _as_parameter_
43 CField_Type
44 StgDict_Type
46 ==============================================================================
48 class methods
49 -------------
51 It has some similarity to the byref() construct compared to pointer()
52 from_address(addr)
53 - construct an instance from a given memory block (sharing this memory block)
55 from_param(obj)
56 - typecheck and convert a Python object into a C function call parameter
57 the result may be an instance of the type, or an integer or tuple
58 (typecode, value[, obj])
60 instance methods/properties
61 ---------------------------
63 _as_parameter_
64 - convert self into a C function call parameter
65 This is either an integer, or a 3-tuple (typecode, value, obj)
67 functions
68 ---------
70 sizeof(cdata)
71 - return the number of bytes the buffer contains
73 sizeof(ctype)
74 - return the number of bytes the buffer of an instance would contain
76 byref(cdata)
78 addressof(cdata)
80 pointer(cdata)
82 POINTER(ctype)
84 bytes(cdata)
85 - return the buffer contents as a sequence of bytes (which is currently a string)
90 * StgDict_Type
91 * StructType_Type
92 * UnionType_Type
93 * PointerType_Type
94 * ArrayType_Type
95 * SimpleType_Type
97 * CData_Type
98 * Struct_Type
99 * Union_Type
100 * Array_Type
101 * Simple_Type
102 * Pointer_Type
103 * CField_Type
107 #define PY_SSIZE_T_CLEAN
109 #include "Python.h"
110 #include "structmember.h"
112 #include <ffi.h>
113 #ifdef MS_WIN32
114 #include <windows.h>
115 #include <malloc.h>
116 #ifndef IS_INTRESOURCE
117 #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
118 #endif
119 # ifdef _WIN32_WCE
120 /* Unlike desktop Windows, WinCE has both W and A variants of
121 GetProcAddress, but the default W version is not what we want */
122 # undef GetProcAddress
123 # define GetProcAddress GetProcAddressA
124 # endif
125 #else
126 #include "ctypes_dlfcn.h"
127 #endif
128 #include "ctypes.h"
130 PyObject *PyExc_ArgError;
132 /* This dict maps ctypes types to POINTER types */
133 PyObject *_pointer_type_cache;
135 static PyTypeObject Simple_Type;
137 /* a callable object used for unpickling */
138 static PyObject *_unpickle;
140 char *conversion_mode_encoding = NULL;
141 char *conversion_mode_errors = NULL;
144 /****************************************************************/
146 #if (PY_VERSION_HEX < 0x02040000)
147 /* Only in Python 2.4 and up */
148 static PyObject *
149 PyTuple_Pack(int n, ...)
151 int i;
152 PyObject *o;
153 PyObject *result;
154 PyObject **items;
155 va_list vargs;
157 va_start(vargs, n);
158 result = PyTuple_New(n);
159 if (result == NULL)
160 return NULL;
161 items = ((PyTupleObject *)result)->ob_item;
162 for (i = 0; i < n; i++) {
163 o = va_arg(vargs, PyObject *);
164 Py_INCREF(o);
165 items[i] = o;
167 va_end(vargs);
168 return result;
170 #endif
172 /****************************************************************/
174 typedef struct {
175 PyObject_HEAD
176 PyObject *key;
177 PyObject *dict;
178 } DictRemoverObject;
180 static void
181 _DictRemover_dealloc(PyObject *_self)
183 DictRemoverObject *self = (DictRemoverObject *)_self;
184 Py_XDECREF(self->key);
185 Py_XDECREF(self->dict);
186 Py_TYPE(self)->tp_free(_self);
189 static PyObject *
190 _DictRemover_call(PyObject *_self, PyObject *args, PyObject *kw)
192 DictRemoverObject *self = (DictRemoverObject *)_self;
193 if (self->key && self->dict) {
194 if (-1 == PyDict_DelItem(self->dict, self->key))
195 /* XXX Error context */
196 PyErr_WriteUnraisable(Py_None);
197 Py_DECREF(self->key);
198 self->key = NULL;
199 Py_DECREF(self->dict);
200 self->dict = NULL;
202 Py_INCREF(Py_None);
203 return Py_None;
206 static PyTypeObject DictRemover_Type = {
207 PyVarObject_HEAD_INIT(NULL, 0)
208 "_ctypes.DictRemover", /* tp_name */
209 sizeof(DictRemoverObject), /* tp_basicsize */
210 0, /* tp_itemsize */
211 _DictRemover_dealloc, /* tp_dealloc */
212 0, /* tp_print */
213 0, /* tp_getattr */
214 0, /* tp_setattr */
215 0, /* tp_compare */
216 0, /* tp_repr */
217 0, /* tp_as_number */
218 0, /* tp_as_sequence */
219 0, /* tp_as_mapping */
220 0, /* tp_hash */
221 _DictRemover_call, /* tp_call */
222 0, /* tp_str */
223 0, /* tp_getattro */
224 0, /* tp_setattro */
225 0, /* tp_as_buffer */
226 /* XXX should participate in GC? */
227 Py_TPFLAGS_DEFAULT, /* tp_flags */
228 "deletes a key from a dictionary", /* tp_doc */
229 0, /* tp_traverse */
230 0, /* tp_clear */
231 0, /* tp_richcompare */
232 0, /* tp_weaklistoffset */
233 0, /* tp_iter */
234 0, /* tp_iternext */
235 0, /* tp_methods */
236 0, /* tp_members */
237 0, /* tp_getset */
238 0, /* tp_base */
239 0, /* tp_dict */
240 0, /* tp_descr_get */
241 0, /* tp_descr_set */
242 0, /* tp_dictoffset */
243 0, /* tp_init */
244 0, /* tp_alloc */
245 0, /* tp_new */
246 0, /* tp_free */
250 PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item)
252 PyObject *obj;
253 DictRemoverObject *remover;
254 PyObject *proxy;
255 int result;
257 obj = PyObject_CallObject((PyObject *)&DictRemover_Type, NULL);
258 if (obj == NULL)
259 return -1;
261 remover = (DictRemoverObject *)obj;
262 assert(remover->key == NULL);
263 assert(remover->dict == NULL);
264 Py_INCREF(key);
265 remover->key = key;
266 Py_INCREF(dict);
267 remover->dict = dict;
269 proxy = PyWeakref_NewProxy(item, obj);
270 Py_DECREF(obj);
271 if (proxy == NULL)
272 return -1;
274 result = PyDict_SetItem(dict, key, proxy);
275 Py_DECREF(proxy);
276 return result;
279 PyObject *
280 PyDict_GetItemProxy(PyObject *dict, PyObject *key)
282 PyObject *result;
283 PyObject *item = PyDict_GetItem(dict, key);
285 if (item == NULL)
286 return NULL;
287 if (!PyWeakref_CheckProxy(item))
288 return item;
289 result = PyWeakref_GET_OBJECT(item);
290 if (result == Py_None)
291 return NULL;
292 return result;
295 /******************************************************************/
297 Allocate a memory block for a pep3118 format string, copy prefix (if
298 non-null) and suffix into it. Returns NULL on failure, with the error
299 indicator set. If called with a suffix of NULL the error indicator must
300 already be set.
302 char *
303 alloc_format_string(const char *prefix, const char *suffix)
305 size_t len;
306 char *result;
308 if (suffix == NULL) {
309 assert(PyErr_Occurred());
310 return NULL;
312 len = strlen(suffix);
313 if (prefix)
314 len += strlen(prefix);
315 result = PyMem_Malloc(len + 1);
316 if (result == NULL)
317 return NULL;
318 if (prefix)
319 strcpy(result, prefix);
320 else
321 result[0] = '\0';
322 strcat(result, suffix);
323 return result;
327 StructType_Type - a meta type/class. Creating a new class using this one as
328 __metaclass__ will call the contructor StructUnionType_new. It replaces the
329 tp_dict member with a new instance of StgDict, and initializes the C
330 accessible fields somehow.
333 static PyCArgObject *
334 StructUnionType_paramfunc(CDataObject *self)
336 PyCArgObject *parg;
337 StgDictObject *stgdict;
339 parg = new_CArgObject();
340 if (parg == NULL)
341 return NULL;
343 parg->tag = 'V';
344 stgdict = PyObject_stgdict((PyObject *)self);
345 assert(stgdict); /* Cannot be NULL for structure/union instances */
346 parg->pffi_type = &stgdict->ffi_type_pointer;
347 /* For structure parameters (by value), parg->value doesn't contain the structure
348 data itself, instead parg->value.p *points* to the structure's data
349 See also _ctypes.c, function _call_function_pointer().
351 parg->value.p = self->b_ptr;
352 parg->size = self->b_size;
353 Py_INCREF(self);
354 parg->obj = (PyObject *)self;
355 return parg;
358 static PyObject *
359 StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
361 PyTypeObject *result;
362 PyObject *fields;
363 StgDictObject *dict;
365 /* create the new instance (which is a class,
366 since we are a metatype!) */
367 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
368 if (!result)
369 return NULL;
371 /* keep this for bw compatibility */
372 if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
373 return (PyObject *)result;
375 dict = (StgDictObject *)PyObject_CallObject((PyObject *)&StgDict_Type, NULL);
376 if (!dict) {
377 Py_DECREF(result);
378 return NULL;
380 /* replace the class dict by our updated stgdict, which holds info
381 about storage requirements of the instances */
382 if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
383 Py_DECREF(result);
384 Py_DECREF((PyObject *)dict);
385 return NULL;
387 Py_DECREF(result->tp_dict);
388 result->tp_dict = (PyObject *)dict;
389 dict->format = alloc_format_string(NULL, "B");
390 if (dict->format == NULL) {
391 Py_DECREF(result);
392 return NULL;
395 dict->paramfunc = StructUnionType_paramfunc;
397 fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
398 if (!fields) {
399 StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
401 if (basedict == NULL)
402 return (PyObject *)result;
403 /* copy base dict */
404 if (-1 == StgDict_clone(dict, basedict)) {
405 Py_DECREF(result);
406 return NULL;
408 dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
409 basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
410 return (PyObject *)result;
413 if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
414 Py_DECREF(result);
415 return NULL;
417 return (PyObject *)result;
420 static PyObject *
421 StructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
423 return StructUnionType_new(type, args, kwds, 1);
426 static PyObject *
427 UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
429 return StructUnionType_new(type, args, kwds, 0);
432 static char from_address_doc[] =
433 "C.from_address(integer) -> C instance\naccess a C instance at the specified address";
435 static PyObject *
436 CDataType_from_address(PyObject *type, PyObject *value)
438 void *buf;
439 if (!PyInt_Check(value) && !PyLong_Check(value)) {
440 PyErr_SetString(PyExc_TypeError,
441 "integer expected");
442 return NULL;
444 buf = (void *)PyLong_AsVoidPtr(value);
445 if (PyErr_Occurred())
446 return NULL;
447 return CData_AtAddress(type, buf);
450 static char from_buffer_doc[] =
451 "C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer";
453 static int
454 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);
456 static PyObject *
457 CDataType_from_buffer(PyObject *type, PyObject *args)
459 void *buffer;
460 Py_ssize_t buffer_len;
461 Py_ssize_t offset = 0;
462 PyObject *obj, *result;
463 StgDictObject *dict = PyType_stgdict(type);
464 assert (dict);
466 if (!PyArg_ParseTuple(args,
467 #if (PY_VERSION_HEX < 0x02050000)
468 "O|i:from_buffer",
469 #else
470 "O|n:from_buffer",
471 #endif
472 &obj, &offset))
473 return NULL;
475 if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len))
476 return NULL;
478 if (offset < 0) {
479 PyErr_SetString(PyExc_ValueError,
480 "offset cannit be negative");
481 return NULL;
483 if (dict->size > buffer_len - offset) {
484 PyErr_Format(PyExc_ValueError,
485 #if (PY_VERSION_HEX < 0x02050000)
486 "Buffer size too small (%d instead of at least %d bytes)",
487 #else
488 "Buffer size too small (%zd instead of at least %zd bytes)",
489 #endif
490 buffer_len, dict->size + offset);
491 return NULL;
494 result = CData_AtAddress(type, (char *)buffer + offset);
495 if (result == NULL)
496 return NULL;
498 Py_INCREF(obj);
499 if (-1 == KeepRef((CDataObject *)result, -1, obj)) {
500 Py_DECREF(result);
501 return NULL;
503 return result;
506 static char from_buffer_copy_doc[] =
507 "C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer";
509 static PyObject *
510 GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
512 static PyObject *
513 CDataType_from_buffer_copy(PyObject *type, PyObject *args)
515 const void *buffer;
516 Py_ssize_t buffer_len;
517 Py_ssize_t offset = 0;
518 PyObject *obj, *result;
519 StgDictObject *dict = PyType_stgdict(type);
520 assert (dict);
522 if (!PyArg_ParseTuple(args,
523 #if (PY_VERSION_HEX < 0x02050000)
524 "O|i:from_buffer",
525 #else
526 "O|n:from_buffer",
527 #endif
528 &obj, &offset))
529 return NULL;
531 if (-1 == PyObject_AsReadBuffer(obj, &buffer, &buffer_len))
532 return NULL;
534 if (offset < 0) {
535 PyErr_SetString(PyExc_ValueError,
536 "offset cannit be negative");
537 return NULL;
540 if (dict->size > buffer_len - offset) {
541 PyErr_Format(PyExc_ValueError,
542 #if (PY_VERSION_HEX < 0x02050000)
543 "Buffer size too small (%d instead of at least %d bytes)",
544 #else
545 "Buffer size too small (%zd instead of at least %zd bytes)",
546 #endif
547 buffer_len, dict->size + offset);
548 return NULL;
551 result = GenericCData_new((PyTypeObject *)type, NULL, NULL);
552 if (result == NULL)
553 return NULL;
554 memcpy(((CDataObject *)result)->b_ptr,
555 (char *)buffer+offset, dict->size);
556 return result;
559 static char in_dll_doc[] =
560 "C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
562 static PyObject *
563 CDataType_in_dll(PyObject *type, PyObject *args)
565 PyObject *dll;
566 char *name;
567 PyObject *obj;
568 void *handle;
569 void *address;
571 if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
572 return NULL;
574 obj = PyObject_GetAttrString(dll, "_handle");
575 if (!obj)
576 return NULL;
577 if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
578 PyErr_SetString(PyExc_TypeError,
579 "the _handle attribute of the second argument must be an integer");
580 Py_DECREF(obj);
581 return NULL;
583 handle = (void *)PyLong_AsVoidPtr(obj);
584 Py_DECREF(obj);
585 if (PyErr_Occurred()) {
586 PyErr_SetString(PyExc_ValueError,
587 "could not convert the _handle attribute to a pointer");
588 return NULL;
591 #ifdef MS_WIN32
592 address = (void *)GetProcAddress(handle, name);
593 if (!address) {
594 PyErr_Format(PyExc_ValueError,
595 "symbol '%s' not found",
596 name);
597 return NULL;
599 #else
600 address = (void *)ctypes_dlsym(handle, name);
601 if (!address) {
602 #ifdef __CYGWIN__
603 /* dlerror() isn't very helpful on cygwin */
604 PyErr_Format(PyExc_ValueError,
605 "symbol '%s' not found (%s) ",
606 name);
607 #else
608 PyErr_SetString(PyExc_ValueError, ctypes_dlerror());
609 #endif
610 return NULL;
612 #endif
613 return CData_AtAddress(type, address);
616 static char from_param_doc[] =
617 "Convert a Python object into a function call parameter.";
619 static PyObject *
620 CDataType_from_param(PyObject *type, PyObject *value)
622 PyObject *as_parameter;
623 if (1 == PyObject_IsInstance(value, type)) {
624 Py_INCREF(value);
625 return value;
627 if (PyCArg_CheckExact(value)) {
628 PyCArgObject *p = (PyCArgObject *)value;
629 PyObject *ob = p->obj;
630 const char *ob_name;
631 StgDictObject *dict;
632 dict = PyType_stgdict(type);
634 /* If we got a PyCArgObject, we must check if the object packed in it
635 is an instance of the type's dict->proto */
636 if(dict && ob
637 && PyObject_IsInstance(ob, dict->proto)) {
638 Py_INCREF(value);
639 return value;
641 ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
642 PyErr_Format(PyExc_TypeError,
643 "expected %s instance instead of pointer to %s",
644 ((PyTypeObject *)type)->tp_name, ob_name);
645 return NULL;
648 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
649 if (as_parameter) {
650 value = CDataType_from_param(type, as_parameter);
651 Py_DECREF(as_parameter);
652 return value;
654 PyErr_Format(PyExc_TypeError,
655 "expected %s instance instead of %s",
656 ((PyTypeObject *)type)->tp_name,
657 Py_TYPE(value)->tp_name);
658 return NULL;
661 static PyMethodDef CDataType_methods[] = {
662 { "from_param", CDataType_from_param, METH_O, from_param_doc },
663 { "from_address", CDataType_from_address, METH_O, from_address_doc },
664 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
665 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
666 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
667 { NULL, NULL },
670 static PyObject *
671 CDataType_repeat(PyObject *self, Py_ssize_t length)
673 if (length < 0)
674 return PyErr_Format(PyExc_ValueError,
675 #if (PY_VERSION_HEX < 0x02050000)
676 "Array length must be >= 0, not %d",
677 #else
678 "Array length must be >= 0, not %zd",
679 #endif
680 length);
681 return CreateArrayType(self, length);
684 static PySequenceMethods CDataType_as_sequence = {
685 0, /* inquiry sq_length; */
686 0, /* binaryfunc sq_concat; */
687 CDataType_repeat, /* intargfunc sq_repeat; */
688 0, /* intargfunc sq_item; */
689 0, /* intintargfunc sq_slice; */
690 0, /* intobjargproc sq_ass_item; */
691 0, /* intintobjargproc sq_ass_slice; */
692 0, /* objobjproc sq_contains; */
694 0, /* binaryfunc sq_inplace_concat; */
695 0, /* intargfunc sq_inplace_repeat; */
698 static int
699 CDataType_clear(PyTypeObject *self)
701 StgDictObject *dict = PyType_stgdict((PyObject *)self);
702 if (dict)
703 Py_CLEAR(dict->proto);
704 return PyType_Type.tp_clear((PyObject *)self);
707 static int
708 CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
710 StgDictObject *dict = PyType_stgdict((PyObject *)self);
711 if (dict)
712 Py_VISIT(dict->proto);
713 return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
716 static int
717 StructType_setattro(PyObject *self, PyObject *key, PyObject *value)
719 /* XXX Should we disallow deleting _fields_? */
720 if (-1 == PyType_Type.tp_setattro(self, key, value))
721 return -1;
723 if (value && PyString_Check(key) &&
724 0 == strcmp(PyString_AS_STRING(key), "_fields_"))
725 return StructUnionType_update_stgdict(self, value, 1);
726 return 0;
730 static int
731 UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
733 /* XXX Should we disallow deleting _fields_? */
734 if (-1 == PyObject_GenericSetAttr(self, key, value))
735 return -1;
737 if (PyString_Check(key) &&
738 0 == strcmp(PyString_AS_STRING(key), "_fields_"))
739 return StructUnionType_update_stgdict(self, value, 0);
740 return 0;
744 PyTypeObject StructType_Type = {
745 PyVarObject_HEAD_INIT(NULL, 0)
746 "_ctypes.StructType", /* tp_name */
747 0, /* tp_basicsize */
748 0, /* tp_itemsize */
749 0, /* tp_dealloc */
750 0, /* tp_print */
751 0, /* tp_getattr */
752 0, /* tp_setattr */
753 0, /* tp_compare */
754 0, /* tp_repr */
755 0, /* tp_as_number */
756 &CDataType_as_sequence, /* tp_as_sequence */
757 0, /* tp_as_mapping */
758 0, /* tp_hash */
759 0, /* tp_call */
760 0, /* tp_str */
761 0, /* tp_getattro */
762 StructType_setattro, /* tp_setattro */
763 0, /* tp_as_buffer */
764 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
765 "metatype for the CData Objects", /* tp_doc */
766 (traverseproc)CDataType_traverse, /* tp_traverse */
767 (inquiry)CDataType_clear, /* tp_clear */
768 0, /* tp_richcompare */
769 0, /* tp_weaklistoffset */
770 0, /* tp_iter */
771 0, /* tp_iternext */
772 CDataType_methods, /* tp_methods */
773 0, /* tp_members */
774 0, /* tp_getset */
775 0, /* tp_base */
776 0, /* tp_dict */
777 0, /* tp_descr_get */
778 0, /* tp_descr_set */
779 0, /* tp_dictoffset */
780 0, /* tp_init */
781 0, /* tp_alloc */
782 StructType_new, /* tp_new */
783 0, /* tp_free */
786 static PyTypeObject UnionType_Type = {
787 PyVarObject_HEAD_INIT(NULL, 0)
788 "_ctypes.UnionType", /* tp_name */
789 0, /* tp_basicsize */
790 0, /* tp_itemsize */
791 0, /* tp_dealloc */
792 0, /* tp_print */
793 0, /* tp_getattr */
794 0, /* tp_setattr */
795 0, /* tp_compare */
796 0, /* tp_repr */
797 0, /* tp_as_number */
798 &CDataType_as_sequence, /* tp_as_sequence */
799 0, /* tp_as_mapping */
800 0, /* tp_hash */
801 0, /* tp_call */
802 0, /* tp_str */
803 0, /* tp_getattro */
804 UnionType_setattro, /* tp_setattro */
805 0, /* tp_as_buffer */
806 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
807 "metatype for the CData Objects", /* tp_doc */
808 (traverseproc)CDataType_traverse, /* tp_traverse */
809 (inquiry)CDataType_clear, /* tp_clear */
810 0, /* tp_richcompare */
811 0, /* tp_weaklistoffset */
812 0, /* tp_iter */
813 0, /* tp_iternext */
814 CDataType_methods, /* tp_methods */
815 0, /* tp_members */
816 0, /* tp_getset */
817 0, /* tp_base */
818 0, /* tp_dict */
819 0, /* tp_descr_get */
820 0, /* tp_descr_set */
821 0, /* tp_dictoffset */
822 0, /* tp_init */
823 0, /* tp_alloc */
824 UnionType_new, /* tp_new */
825 0, /* tp_free */
829 /******************************************************************/
833 The PointerType_Type metaclass must ensure that the subclass of Pointer can be
834 created. It must check for a _type_ attribute in the class. Since are no
835 runtime created properties, a CField is probably *not* needed ?
837 class IntPointer(Pointer):
838 _type_ = "i"
840 The Pointer_Type provides the functionality: a contents method/property, a
841 size property/method, and the sequence protocol.
845 static int
846 PointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
848 if (!proto || !PyType_Check(proto)) {
849 PyErr_SetString(PyExc_TypeError,
850 "_type_ must be a type");
851 return -1;
853 if (!PyType_stgdict(proto)) {
854 PyErr_SetString(PyExc_TypeError,
855 "_type_ must have storage info");
856 return -1;
858 Py_INCREF(proto);
859 Py_XDECREF(stgdict->proto);
860 stgdict->proto = proto;
861 return 0;
864 static PyCArgObject *
865 PointerType_paramfunc(CDataObject *self)
867 PyCArgObject *parg;
869 parg = new_CArgObject();
870 if (parg == NULL)
871 return NULL;
873 parg->tag = 'P';
874 parg->pffi_type = &ffi_type_pointer;
875 Py_INCREF(self);
876 parg->obj = (PyObject *)self;
877 parg->value.p = *(void **)self->b_ptr;
878 return parg;
881 static PyObject *
882 PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
884 PyTypeObject *result;
885 StgDictObject *stgdict;
886 PyObject *proto;
887 PyObject *typedict;
889 typedict = PyTuple_GetItem(args, 2);
890 if (!typedict)
891 return NULL;
893 stgdict items size, align, length contain info about pointers itself,
894 stgdict->proto has info about the pointed to type!
896 stgdict = (StgDictObject *)PyObject_CallObject(
897 (PyObject *)&StgDict_Type, NULL);
898 if (!stgdict)
899 return NULL;
900 stgdict->size = sizeof(void *);
901 stgdict->align = getentry("P")->pffi_type->alignment;
902 stgdict->length = 1;
903 stgdict->ffi_type_pointer = ffi_type_pointer;
904 stgdict->paramfunc = PointerType_paramfunc;
905 stgdict->flags |= TYPEFLAG_ISPOINTER;
907 proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
908 if (proto && -1 == PointerType_SetProto(stgdict, proto)) {
909 Py_DECREF((PyObject *)stgdict);
910 return NULL;
913 if (proto) {
914 StgDictObject *itemdict = PyType_stgdict(proto);
915 assert(itemdict);
916 /* If itemdict->format is NULL, then this is a pointer to an
917 incomplete type. We create a generic format string
918 'pointer to bytes' in this case. XXX Better would be to
919 fix the format string later...
921 stgdict->format = alloc_format_string("&",
922 itemdict->format ? itemdict->format : "B");
923 if (stgdict->format == NULL) {
924 Py_DECREF((PyObject *)stgdict);
925 return NULL;
929 /* create the new instance (which is a class,
930 since we are a metatype!) */
931 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
932 if (result == NULL) {
933 Py_DECREF((PyObject *)stgdict);
934 return NULL;
937 /* replace the class dict by our updated spam dict */
938 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
939 Py_DECREF(result);
940 Py_DECREF((PyObject *)stgdict);
941 return NULL;
943 Py_DECREF(result->tp_dict);
944 result->tp_dict = (PyObject *)stgdict;
946 return (PyObject *)result;
950 static PyObject *
951 PointerType_set_type(PyTypeObject *self, PyObject *type)
953 StgDictObject *dict;
955 dict = PyType_stgdict((PyObject *)self);
956 assert(dict);
958 if (-1 == PointerType_SetProto(dict, type))
959 return NULL;
961 if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
962 return NULL;
964 Py_INCREF(Py_None);
965 return Py_None;
968 staticforward PyObject *_byref(PyObject *);
970 static PyObject *
971 PointerType_from_param(PyObject *type, PyObject *value)
973 StgDictObject *typedict;
975 if (value == Py_None)
976 return PyInt_FromLong(0); /* NULL pointer */
978 typedict = PyType_stgdict(type);
979 assert(typedict); /* Cannot be NULL for pointer types */
981 /* If we expect POINTER(<type>), but receive a <type> instance, accept
982 it by calling byref(<type>).
984 switch (PyObject_IsInstance(value, typedict->proto)) {
985 case 1:
986 Py_INCREF(value); /* _byref steals a refcount */
987 return _byref(value);
988 case -1:
989 PyErr_Clear();
990 break;
991 default:
992 break;
995 if (PointerObject_Check(value) || ArrayObject_Check(value)) {
996 /* Array instances are also pointers when
997 the item types are the same.
999 StgDictObject *v = PyObject_stgdict(value);
1000 assert(v); /* Cannot be NULL for pointer or array objects */
1001 if (PyObject_IsSubclass(v->proto, typedict->proto)) {
1002 Py_INCREF(value);
1003 return value;
1006 return CDataType_from_param(type, value);
1009 static PyMethodDef PointerType_methods[] = {
1010 { "from_address", CDataType_from_address, METH_O, from_address_doc },
1011 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
1012 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
1013 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
1014 { "from_param", (PyCFunction)PointerType_from_param, METH_O, from_param_doc},
1015 { "set_type", (PyCFunction)PointerType_set_type, METH_O },
1016 { NULL, NULL },
1019 PyTypeObject PointerType_Type = {
1020 PyVarObject_HEAD_INIT(NULL, 0)
1021 "_ctypes.PointerType", /* tp_name */
1022 0, /* tp_basicsize */
1023 0, /* tp_itemsize */
1024 0, /* tp_dealloc */
1025 0, /* tp_print */
1026 0, /* tp_getattr */
1027 0, /* tp_setattr */
1028 0, /* tp_compare */
1029 0, /* tp_repr */
1030 0, /* tp_as_number */
1031 &CDataType_as_sequence, /* tp_as_sequence */
1032 0, /* tp_as_mapping */
1033 0, /* tp_hash */
1034 0, /* tp_call */
1035 0, /* tp_str */
1036 0, /* tp_getattro */
1037 0, /* tp_setattro */
1038 0, /* tp_as_buffer */
1039 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1040 "metatype for the Pointer Objects", /* tp_doc */
1041 (traverseproc)CDataType_traverse, /* tp_traverse */
1042 (inquiry)CDataType_clear, /* tp_clear */
1043 0, /* tp_richcompare */
1044 0, /* tp_weaklistoffset */
1045 0, /* tp_iter */
1046 0, /* tp_iternext */
1047 PointerType_methods, /* tp_methods */
1048 0, /* tp_members */
1049 0, /* tp_getset */
1050 0, /* tp_base */
1051 0, /* tp_dict */
1052 0, /* tp_descr_get */
1053 0, /* tp_descr_set */
1054 0, /* tp_dictoffset */
1055 0, /* tp_init */
1056 0, /* tp_alloc */
1057 PointerType_new, /* tp_new */
1058 0, /* tp_free */
1062 /******************************************************************/
1064 ArrayType_Type
1067 ArrayType_new ensures that the new Array subclass created has a _length_
1068 attribute, and a _type_ attribute.
1071 static int
1072 CharArray_set_raw(CDataObject *self, PyObject *value)
1074 char *ptr;
1075 Py_ssize_t size;
1076 if (PyBuffer_Check(value)) {
1077 size = Py_TYPE(value)->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
1078 if (size < 0)
1079 return -1;
1080 } else if (-1 == PyString_AsStringAndSize(value, &ptr, &size)) {
1081 return -1;
1083 if (size > self->b_size) {
1084 PyErr_SetString(PyExc_ValueError,
1085 "string too long");
1086 return -1;
1089 memcpy(self->b_ptr, ptr, size);
1091 return 0;
1094 static PyObject *
1095 CharArray_get_raw(CDataObject *self)
1097 return PyString_FromStringAndSize(self->b_ptr, self->b_size);
1100 static PyObject *
1101 CharArray_get_value(CDataObject *self)
1103 int i;
1104 char *ptr = self->b_ptr;
1105 for (i = 0; i < self->b_size; ++i)
1106 if (*ptr++ == '\0')
1107 break;
1108 return PyString_FromStringAndSize(self->b_ptr, i);
1111 static int
1112 CharArray_set_value(CDataObject *self, PyObject *value)
1114 char *ptr;
1115 Py_ssize_t size;
1117 if (value == NULL) {
1118 PyErr_SetString(PyExc_TypeError,
1119 "can't delete attribute");
1120 return -1;
1123 if (PyUnicode_Check(value)) {
1124 value = PyUnicode_AsEncodedString(value,
1125 conversion_mode_encoding,
1126 conversion_mode_errors);
1127 if (!value)
1128 return -1;
1129 } else if (!PyString_Check(value)) {
1130 PyErr_Format(PyExc_TypeError,
1131 "string expected instead of %s instance",
1132 Py_TYPE(value)->tp_name);
1133 return -1;
1134 } else
1135 Py_INCREF(value);
1136 size = PyString_GET_SIZE(value);
1137 if (size > self->b_size) {
1138 PyErr_SetString(PyExc_ValueError,
1139 "string too long");
1140 Py_DECREF(value);
1141 return -1;
1144 ptr = PyString_AS_STRING(value);
1145 memcpy(self->b_ptr, ptr, size);
1146 if (size < self->b_size)
1147 self->b_ptr[size] = '\0';
1148 Py_DECREF(value);
1150 return 0;
1153 static PyGetSetDef CharArray_getsets[] = {
1154 { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
1155 "value", NULL },
1156 { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
1157 "string value"},
1158 { NULL, NULL }
1161 #ifdef CTYPES_UNICODE
1162 static PyObject *
1163 WCharArray_get_value(CDataObject *self)
1165 unsigned int i;
1166 wchar_t *ptr = (wchar_t *)self->b_ptr;
1167 for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
1168 if (*ptr++ == (wchar_t)0)
1169 break;
1170 return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
1173 static int
1174 WCharArray_set_value(CDataObject *self, PyObject *value)
1176 Py_ssize_t result = 0;
1178 if (value == NULL) {
1179 PyErr_SetString(PyExc_TypeError,
1180 "can't delete attribute");
1181 return -1;
1183 if (PyString_Check(value)) {
1184 value = PyUnicode_FromEncodedObject(value,
1185 conversion_mode_encoding,
1186 conversion_mode_errors);
1187 if (!value)
1188 return -1;
1189 } else if (!PyUnicode_Check(value)) {
1190 PyErr_Format(PyExc_TypeError,
1191 "unicode string expected instead of %s instance",
1192 Py_TYPE(value)->tp_name);
1193 return -1;
1194 } else
1195 Py_INCREF(value);
1196 if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
1197 PyErr_SetString(PyExc_ValueError,
1198 "string too long");
1199 result = -1;
1200 goto done;
1202 result = PyUnicode_AsWideChar((PyUnicodeObject *)value,
1203 (wchar_t *)self->b_ptr,
1204 self->b_size/sizeof(wchar_t));
1205 if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
1206 ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
1207 done:
1208 Py_DECREF(value);
1210 return result >= 0 ? 0 : -1;
1213 static PyGetSetDef WCharArray_getsets[] = {
1214 { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
1215 "string value"},
1216 { NULL, NULL }
1218 #endif
1221 The next three functions copied from Python's typeobject.c.
1223 They are used to attach methods, members, or getsets to a type *after* it
1224 has been created: Arrays of characters have additional getsets to treat them
1225 as strings.
1228 static int
1229 add_methods(PyTypeObject *type, PyMethodDef *meth)
1231 PyObject *dict = type->tp_dict;
1232 for (; meth->ml_name != NULL; meth++) {
1233 PyObject *descr;
1234 descr = PyDescr_NewMethod(type, meth);
1235 if (descr == NULL)
1236 return -1;
1237 if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
1238 return -1;
1239 Py_DECREF(descr);
1241 return 0;
1244 static int
1245 add_members(PyTypeObject *type, PyMemberDef *memb)
1247 PyObject *dict = type->tp_dict;
1248 for (; memb->name != NULL; memb++) {
1249 PyObject *descr;
1250 descr = PyDescr_NewMember(type, memb);
1251 if (descr == NULL)
1252 return -1;
1253 if (PyDict_SetItemString(dict, memb->name, descr) < 0)
1254 return -1;
1255 Py_DECREF(descr);
1257 return 0;
1261 static int
1262 add_getset(PyTypeObject *type, PyGetSetDef *gsp)
1264 PyObject *dict = type->tp_dict;
1265 for (; gsp->name != NULL; gsp++) {
1266 PyObject *descr;
1267 descr = PyDescr_NewGetSet(type, gsp);
1268 if (descr == NULL)
1269 return -1;
1270 if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
1271 return -1;
1272 Py_DECREF(descr);
1274 return 0;
1277 static PyCArgObject *
1278 ArrayType_paramfunc(CDataObject *self)
1280 PyCArgObject *p = new_CArgObject();
1281 if (p == NULL)
1282 return NULL;
1283 p->tag = 'P';
1284 p->pffi_type = &ffi_type_pointer;
1285 p->value.p = (char *)self->b_ptr;
1286 Py_INCREF(self);
1287 p->obj = (PyObject *)self;
1288 return p;
1291 static PyObject *
1292 ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1294 PyTypeObject *result;
1295 StgDictObject *stgdict;
1296 StgDictObject *itemdict;
1297 PyObject *proto;
1298 PyObject *typedict;
1299 long length;
1301 Py_ssize_t itemsize, itemalign;
1302 char buf[32];
1304 typedict = PyTuple_GetItem(args, 2);
1305 if (!typedict)
1306 return NULL;
1308 proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
1309 if (!proto || !PyInt_Check(proto)) {
1310 PyErr_SetString(PyExc_AttributeError,
1311 "class must define a '_length_' attribute, "
1312 "which must be a positive integer");
1313 return NULL;
1315 length = PyInt_AS_LONG(proto);
1317 proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
1318 if (!proto) {
1319 PyErr_SetString(PyExc_AttributeError,
1320 "class must define a '_type_' attribute");
1321 return NULL;
1324 stgdict = (StgDictObject *)PyObject_CallObject(
1325 (PyObject *)&StgDict_Type, NULL);
1326 if (!stgdict)
1327 return NULL;
1329 itemdict = PyType_stgdict(proto);
1330 if (!itemdict) {
1331 PyErr_SetString(PyExc_TypeError,
1332 "_type_ must have storage info");
1333 Py_DECREF((PyObject *)stgdict);
1334 return NULL;
1337 assert(itemdict->format);
1338 if (itemdict->format[0] == '(') {
1339 sprintf(buf, "(%ld,", length);
1340 stgdict->format = alloc_format_string(buf, itemdict->format+1);
1341 } else {
1342 sprintf(buf, "(%ld)", length);
1343 stgdict->format = alloc_format_string(buf, itemdict->format);
1345 if (stgdict->format == NULL) {
1346 Py_DECREF((PyObject *)stgdict);
1347 return NULL;
1349 stgdict->ndim = itemdict->ndim + 1;
1350 stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t *) * stgdict->ndim);
1351 if (stgdict->shape == NULL) {
1352 Py_DECREF((PyObject *)stgdict);
1353 return NULL;
1355 stgdict->shape[0] = length;
1356 memmove(&stgdict->shape[1], itemdict->shape,
1357 sizeof(Py_ssize_t) * (stgdict->ndim - 1));
1359 itemsize = itemdict->size;
1360 if (length * itemsize < 0) {
1361 PyErr_SetString(PyExc_OverflowError,
1362 "array too large");
1363 return NULL;
1366 itemalign = itemdict->align;
1368 if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
1369 stgdict->flags |= TYPEFLAG_HASPOINTER;
1371 stgdict->size = itemsize * length;
1372 stgdict->align = itemalign;
1373 stgdict->length = length;
1374 Py_INCREF(proto);
1375 stgdict->proto = proto;
1377 stgdict->paramfunc = &ArrayType_paramfunc;
1379 /* Arrays are passed as pointers to function calls. */
1380 stgdict->ffi_type_pointer = ffi_type_pointer;
1382 /* create the new instance (which is a class,
1383 since we are a metatype!) */
1384 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1385 if (result == NULL)
1386 return NULL;
1388 /* replace the class dict by our updated spam dict */
1389 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1390 Py_DECREF(result);
1391 Py_DECREF((PyObject *)stgdict);
1392 return NULL;
1394 Py_DECREF(result->tp_dict);
1395 result->tp_dict = (PyObject *)stgdict;
1397 /* Special case for character arrays.
1398 A permanent annoyance: char arrays are also strings!
1400 if (itemdict->getfunc == getentry("c")->getfunc) {
1401 if (-1 == add_getset(result, CharArray_getsets))
1402 return NULL;
1403 #ifdef CTYPES_UNICODE
1404 } else if (itemdict->getfunc == getentry("u")->getfunc) {
1405 if (-1 == add_getset(result, WCharArray_getsets))
1406 return NULL;
1407 #endif
1410 return (PyObject *)result;
1413 PyTypeObject ArrayType_Type = {
1414 PyVarObject_HEAD_INIT(NULL, 0)
1415 "_ctypes.ArrayType", /* tp_name */
1416 0, /* tp_basicsize */
1417 0, /* tp_itemsize */
1418 0, /* tp_dealloc */
1419 0, /* tp_print */
1420 0, /* tp_getattr */
1421 0, /* tp_setattr */
1422 0, /* tp_compare */
1423 0, /* tp_repr */
1424 0, /* tp_as_number */
1425 &CDataType_as_sequence, /* tp_as_sequence */
1426 0, /* tp_as_mapping */
1427 0, /* tp_hash */
1428 0, /* tp_call */
1429 0, /* tp_str */
1430 0, /* tp_getattro */
1431 0, /* tp_setattro */
1432 0, /* tp_as_buffer */
1433 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1434 "metatype for the Array Objects", /* tp_doc */
1435 0, /* tp_traverse */
1436 0, /* tp_clear */
1437 0, /* tp_richcompare */
1438 0, /* tp_weaklistoffset */
1439 0, /* tp_iter */
1440 0, /* tp_iternext */
1441 CDataType_methods, /* tp_methods */
1442 0, /* tp_members */
1443 0, /* tp_getset */
1444 0, /* tp_base */
1445 0, /* tp_dict */
1446 0, /* tp_descr_get */
1447 0, /* tp_descr_set */
1448 0, /* tp_dictoffset */
1449 0, /* tp_init */
1450 0, /* tp_alloc */
1451 ArrayType_new, /* tp_new */
1452 0, /* tp_free */
1456 /******************************************************************/
1458 SimpleType_Type
1462 SimpleType_new ensures that the new Simple_Type subclass created has a valid
1463 _type_ attribute.
1467 static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv?g";
1469 static PyObject *
1470 c_wchar_p_from_param(PyObject *type, PyObject *value)
1472 PyObject *as_parameter;
1473 #if (PYTHON_API_VERSION < 1012)
1474 # error not supported
1475 #endif
1476 if (value == Py_None) {
1477 Py_INCREF(Py_None);
1478 return Py_None;
1480 if (PyUnicode_Check(value) || PyString_Check(value)) {
1481 PyCArgObject *parg;
1482 struct fielddesc *fd = getentry("Z");
1484 parg = new_CArgObject();
1485 if (parg == NULL)
1486 return NULL;
1487 parg->pffi_type = &ffi_type_pointer;
1488 parg->tag = 'Z';
1489 parg->obj = fd->setfunc(&parg->value, value, 0);
1490 if (parg->obj == NULL) {
1491 Py_DECREF(parg);
1492 return NULL;
1494 return (PyObject *)parg;
1496 if (PyObject_IsInstance(value, type)) {
1497 Py_INCREF(value);
1498 return value;
1500 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1501 /* c_wchar array instance or pointer(c_wchar(...)) */
1502 StgDictObject *dt = PyObject_stgdict(value);
1503 StgDictObject *dict;
1504 assert(dt); /* Cannot be NULL for pointer or array objects */
1505 dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1506 if (dict && (dict->setfunc == getentry("u")->setfunc)) {
1507 Py_INCREF(value);
1508 return value;
1511 if (PyCArg_CheckExact(value)) {
1512 /* byref(c_char(...)) */
1513 PyCArgObject *a = (PyCArgObject *)value;
1514 StgDictObject *dict = PyObject_stgdict(a->obj);
1515 if (dict && (dict->setfunc == getentry("u")->setfunc)) {
1516 Py_INCREF(value);
1517 return value;
1521 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1522 if (as_parameter) {
1523 value = c_wchar_p_from_param(type, as_parameter);
1524 Py_DECREF(as_parameter);
1525 return value;
1527 /* XXX better message */
1528 PyErr_SetString(PyExc_TypeError,
1529 "wrong type");
1530 return NULL;
1533 static PyObject *
1534 c_char_p_from_param(PyObject *type, PyObject *value)
1536 PyObject *as_parameter;
1537 #if (PYTHON_API_VERSION < 1012)
1538 # error not supported
1539 #endif
1540 if (value == Py_None) {
1541 Py_INCREF(Py_None);
1542 return Py_None;
1544 if (PyString_Check(value) || PyUnicode_Check(value)) {
1545 PyCArgObject *parg;
1546 struct fielddesc *fd = getentry("z");
1548 parg = new_CArgObject();
1549 if (parg == NULL)
1550 return NULL;
1551 parg->pffi_type = &ffi_type_pointer;
1552 parg->tag = 'z';
1553 parg->obj = fd->setfunc(&parg->value, value, 0);
1554 if (parg->obj == NULL) {
1555 Py_DECREF(parg);
1556 return NULL;
1558 return (PyObject *)parg;
1560 if (PyObject_IsInstance(value, type)) {
1561 Py_INCREF(value);
1562 return value;
1564 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1565 /* c_char array instance or pointer(c_char(...)) */
1566 StgDictObject *dt = PyObject_stgdict(value);
1567 StgDictObject *dict;
1568 assert(dt); /* Cannot be NULL for pointer or array objects */
1569 dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1570 if (dict && (dict->setfunc == getentry("c")->setfunc)) {
1571 Py_INCREF(value);
1572 return value;
1575 if (PyCArg_CheckExact(value)) {
1576 /* byref(c_char(...)) */
1577 PyCArgObject *a = (PyCArgObject *)value;
1578 StgDictObject *dict = PyObject_stgdict(a->obj);
1579 if (dict && (dict->setfunc == getentry("c")->setfunc)) {
1580 Py_INCREF(value);
1581 return value;
1585 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1586 if (as_parameter) {
1587 value = c_char_p_from_param(type, as_parameter);
1588 Py_DECREF(as_parameter);
1589 return value;
1591 /* XXX better message */
1592 PyErr_SetString(PyExc_TypeError,
1593 "wrong type");
1594 return NULL;
1597 static PyObject *
1598 c_void_p_from_param(PyObject *type, PyObject *value)
1600 StgDictObject *stgd;
1601 PyObject *as_parameter;
1602 #if (PYTHON_API_VERSION < 1012)
1603 # error not supported
1604 #endif
1606 /* None */
1607 if (value == Py_None) {
1608 Py_INCREF(Py_None);
1609 return Py_None;
1611 /* Should probably allow buffer interface as well */
1612 /* int, long */
1613 if (PyInt_Check(value) || PyLong_Check(value)) {
1614 PyCArgObject *parg;
1615 struct fielddesc *fd = getentry("P");
1617 parg = new_CArgObject();
1618 if (parg == NULL)
1619 return NULL;
1620 parg->pffi_type = &ffi_type_pointer;
1621 parg->tag = 'P';
1622 parg->obj = fd->setfunc(&parg->value, value, 0);
1623 if (parg->obj == NULL) {
1624 Py_DECREF(parg);
1625 return NULL;
1627 return (PyObject *)parg;
1629 /* string */
1630 if (PyString_Check(value)) {
1631 PyCArgObject *parg;
1632 struct fielddesc *fd = getentry("z");
1634 parg = new_CArgObject();
1635 if (parg == NULL)
1636 return NULL;
1637 parg->pffi_type = &ffi_type_pointer;
1638 parg->tag = 'z';
1639 parg->obj = fd->setfunc(&parg->value, value, 0);
1640 if (parg->obj == NULL) {
1641 Py_DECREF(parg);
1642 return NULL;
1644 return (PyObject *)parg;
1646 /* unicode */
1647 if (PyUnicode_Check(value)) {
1648 PyCArgObject *parg;
1649 struct fielddesc *fd = getentry("Z");
1651 parg = new_CArgObject();
1652 if (parg == NULL)
1653 return NULL;
1654 parg->pffi_type = &ffi_type_pointer;
1655 parg->tag = 'Z';
1656 parg->obj = fd->setfunc(&parg->value, value, 0);
1657 if (parg->obj == NULL) {
1658 Py_DECREF(parg);
1659 return NULL;
1661 return (PyObject *)parg;
1663 /* c_void_p instance (or subclass) */
1664 if (PyObject_IsInstance(value, type)) {
1665 /* c_void_p instances */
1666 Py_INCREF(value);
1667 return value;
1669 /* ctypes array or pointer instance */
1670 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1671 /* Any array or pointer is accepted */
1672 Py_INCREF(value);
1673 return value;
1675 /* byref(...) */
1676 if (PyCArg_CheckExact(value)) {
1677 /* byref(c_xxx()) */
1678 PyCArgObject *a = (PyCArgObject *)value;
1679 if (a->tag == 'P') {
1680 Py_INCREF(value);
1681 return value;
1684 /* function pointer */
1685 if (CFuncPtrObject_Check(value)) {
1686 PyCArgObject *parg;
1687 CFuncPtrObject *func;
1688 func = (CFuncPtrObject *)value;
1689 parg = new_CArgObject();
1690 if (parg == NULL)
1691 return NULL;
1692 parg->pffi_type = &ffi_type_pointer;
1693 parg->tag = 'P';
1694 Py_INCREF(value);
1695 parg->value.p = *(void **)func->b_ptr;
1696 parg->obj = value;
1697 return (PyObject *)parg;
1699 /* c_char_p, c_wchar_p */
1700 stgd = PyObject_stgdict(value);
1701 if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
1702 PyCArgObject *parg;
1704 switch (PyString_AS_STRING(stgd->proto)[0]) {
1705 case 'z': /* c_char_p */
1706 case 'Z': /* c_wchar_p */
1707 parg = new_CArgObject();
1708 if (parg == NULL)
1709 return NULL;
1710 parg->pffi_type = &ffi_type_pointer;
1711 parg->tag = 'Z';
1712 Py_INCREF(value);
1713 parg->obj = value;
1714 /* Remember: b_ptr points to where the pointer is stored! */
1715 parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
1716 return (PyObject *)parg;
1720 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1721 if (as_parameter) {
1722 value = c_void_p_from_param(type, as_parameter);
1723 Py_DECREF(as_parameter);
1724 return value;
1726 /* XXX better message */
1727 PyErr_SetString(PyExc_TypeError,
1728 "wrong type");
1729 return NULL;
1731 #if (PYTHON_API_VERSION >= 1012)
1733 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1734 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
1735 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1737 #else
1738 #error
1739 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_VARARGS };
1740 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_VARARGS };
1741 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_VARARGS };
1743 #endif
1745 static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
1746 PyObject *proto, struct fielddesc *fmt)
1748 PyTypeObject *result;
1749 StgDictObject *stgdict;
1750 PyObject *name = PyTuple_GET_ITEM(args, 0);
1751 PyObject *swapped_args;
1752 static PyObject *suffix;
1753 Py_ssize_t i;
1755 swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
1756 if (!swapped_args)
1757 return NULL;
1759 if (suffix == NULL)
1760 #ifdef WORDS_BIGENDIAN
1761 suffix = PyString_InternFromString("_le");
1762 #else
1763 suffix = PyString_InternFromString("_be");
1764 #endif
1766 Py_INCREF(name);
1767 PyString_Concat(&name, suffix);
1768 if (name == NULL)
1769 return NULL;
1771 PyTuple_SET_ITEM(swapped_args, 0, name);
1772 for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
1773 PyObject *v = PyTuple_GET_ITEM(args, i);
1774 Py_INCREF(v);
1775 PyTuple_SET_ITEM(swapped_args, i, v);
1778 /* create the new instance (which is a class,
1779 since we are a metatype!) */
1780 result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
1781 Py_DECREF(swapped_args);
1782 if (result == NULL)
1783 return NULL;
1785 stgdict = (StgDictObject *)PyObject_CallObject(
1786 (PyObject *)&StgDict_Type, NULL);
1787 if (!stgdict) /* XXX leaks result! */
1788 return NULL;
1790 stgdict->ffi_type_pointer = *fmt->pffi_type;
1791 stgdict->align = fmt->pffi_type->alignment;
1792 stgdict->length = 0;
1793 stgdict->size = fmt->pffi_type->size;
1794 stgdict->setfunc = fmt->setfunc_swapped;
1795 stgdict->getfunc = fmt->getfunc_swapped;
1797 Py_INCREF(proto);
1798 stgdict->proto = proto;
1800 /* replace the class dict by our updated spam dict */
1801 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1802 Py_DECREF(result);
1803 Py_DECREF((PyObject *)stgdict);
1804 return NULL;
1806 Py_DECREF(result->tp_dict);
1807 result->tp_dict = (PyObject *)stgdict;
1809 return (PyObject *)result;
1812 static PyCArgObject *
1813 SimpleType_paramfunc(CDataObject *self)
1815 StgDictObject *dict;
1816 char *fmt;
1817 PyCArgObject *parg;
1818 struct fielddesc *fd;
1820 dict = PyObject_stgdict((PyObject *)self);
1821 assert(dict); /* Cannot be NULL for CDataObject instances */
1822 fmt = PyString_AsString(dict->proto);
1823 assert(fmt);
1825 fd = getentry(fmt);
1826 assert(fd);
1828 parg = new_CArgObject();
1829 if (parg == NULL)
1830 return NULL;
1832 parg->tag = fmt[0];
1833 parg->pffi_type = fd->pffi_type;
1834 Py_INCREF(self);
1835 parg->obj = (PyObject *)self;
1836 memcpy(&parg->value, self->b_ptr, self->b_size);
1837 return parg;
1840 static PyObject *
1841 SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1843 PyTypeObject *result;
1844 StgDictObject *stgdict;
1845 PyObject *proto;
1846 const char *proto_str;
1847 Py_ssize_t proto_len;
1848 PyMethodDef *ml;
1849 struct fielddesc *fmt;
1851 /* create the new instance (which is a class,
1852 since we are a metatype!) */
1853 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1854 if (result == NULL)
1855 return NULL;
1857 proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
1858 if (!proto) {
1859 PyErr_SetString(PyExc_AttributeError,
1860 "class must define a '_type_' attribute");
1861 error:
1862 Py_XDECREF(proto);
1863 Py_XDECREF(result);
1864 return NULL;
1866 if (PyString_Check(proto)) {
1867 proto_str = PyString_AS_STRING(proto);
1868 proto_len = PyString_GET_SIZE(proto);
1869 } else {
1870 PyErr_SetString(PyExc_TypeError,
1871 "class must define a '_type_' string attribute");
1872 goto error;
1874 if (proto_len != 1) {
1875 PyErr_SetString(PyExc_ValueError,
1876 "class must define a '_type_' attribute "
1877 "which must be a string of length 1");
1878 goto error;
1880 if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
1881 PyErr_Format(PyExc_AttributeError,
1882 "class must define a '_type_' attribute which must be\n"
1883 "a single character string containing one of '%s'.",
1884 SIMPLE_TYPE_CHARS);
1885 goto error;
1887 fmt = getentry(PyString_AS_STRING(proto));
1888 if (fmt == NULL) {
1889 Py_DECREF(result);
1890 PyErr_Format(PyExc_ValueError,
1891 "_type_ '%s' not supported",
1892 PyString_AS_STRING(proto));
1893 return NULL;
1896 stgdict = (StgDictObject *)PyObject_CallObject(
1897 (PyObject *)&StgDict_Type, NULL);
1898 if (!stgdict)
1899 return NULL;
1901 stgdict->ffi_type_pointer = *fmt->pffi_type;
1902 stgdict->align = fmt->pffi_type->alignment;
1903 stgdict->length = 0;
1904 stgdict->size = fmt->pffi_type->size;
1905 stgdict->setfunc = fmt->setfunc;
1906 stgdict->getfunc = fmt->getfunc;
1907 #ifdef WORDS_BIGENDIAN
1908 stgdict->format = alloc_format_string(">", proto_str);
1909 #else
1910 stgdict->format = alloc_format_string("<", proto_str);
1911 #endif
1912 if (stgdict->format == NULL) {
1913 Py_DECREF(result);
1914 Py_DECREF((PyObject *)stgdict);
1915 return NULL;
1918 stgdict->paramfunc = SimpleType_paramfunc;
1920 if (result->tp_base != &Simple_Type) {
1921 stgdict->setfunc = NULL;
1922 stgdict->getfunc = NULL;
1926 /* This consumes the refcount on proto which we have */
1927 stgdict->proto = proto;
1929 /* replace the class dict by our updated spam dict */
1930 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1931 Py_DECREF(result);
1932 Py_DECREF((PyObject *)stgdict);
1933 return NULL;
1935 Py_DECREF(result->tp_dict);
1936 result->tp_dict = (PyObject *)stgdict;
1938 /* Install from_param class methods in ctypes base classes.
1939 Overrides the SimpleType_from_param generic method.
1941 if (result->tp_base == &Simple_Type) {
1942 switch (PyString_AS_STRING(proto)[0]) {
1943 case 'z': /* c_char_p */
1944 ml = &c_char_p_method;
1945 stgdict->flags |= TYPEFLAG_ISPOINTER;
1946 break;
1947 case 'Z': /* c_wchar_p */
1948 ml = &c_wchar_p_method;
1949 stgdict->flags |= TYPEFLAG_ISPOINTER;
1950 break;
1951 case 'P': /* c_void_p */
1952 ml = &c_void_p_method;
1953 stgdict->flags |= TYPEFLAG_ISPOINTER;
1954 break;
1955 case 'u':
1956 case 'X':
1957 case 'O':
1958 ml = NULL;
1959 stgdict->flags |= TYPEFLAG_ISPOINTER;
1960 break;
1961 default:
1962 ml = NULL;
1963 break;
1966 if (ml) {
1967 #if (PYTHON_API_VERSION >= 1012)
1968 PyObject *meth;
1969 int x;
1970 meth = PyDescr_NewClassMethod(result, ml);
1971 if (!meth)
1972 return NULL;
1973 #else
1974 #error
1975 PyObject *meth, *func;
1976 int x;
1977 func = PyCFunction_New(ml, NULL);
1978 if (!func)
1979 return NULL;
1980 meth = PyObject_CallFunctionObjArgs(
1981 (PyObject *)&PyClassMethod_Type,
1982 func, NULL);
1983 Py_DECREF(func);
1984 if (!meth) {
1985 return NULL;
1987 #endif
1988 x = PyDict_SetItemString(result->tp_dict,
1989 ml->ml_name,
1990 meth);
1991 Py_DECREF(meth);
1992 if (x == -1) {
1993 Py_DECREF(result);
1994 return NULL;
1999 if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
2000 PyObject *swapped = CreateSwappedType(type, args, kwds,
2001 proto, fmt);
2002 StgDictObject *sw_dict;
2003 if (swapped == NULL) {
2004 Py_DECREF(result);
2005 return NULL;
2007 sw_dict = PyType_stgdict(swapped);
2008 #ifdef WORDS_BIGENDIAN
2009 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
2010 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
2011 PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
2012 PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
2013 /* We are creating the type for the OTHER endian */
2014 sw_dict->format = alloc_format_string("<", stgdict->format+1);
2015 #else
2016 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
2017 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
2018 PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
2019 PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
2020 /* We are creating the type for the OTHER endian */
2021 sw_dict->format = alloc_format_string(">", stgdict->format+1);
2022 #endif
2023 Py_DECREF(swapped);
2024 if (PyErr_Occurred()) {
2025 Py_DECREF(result);
2026 return NULL;
2030 return (PyObject *)result;
2034 * This is a *class method*.
2035 * Convert a parameter into something that ConvParam can handle.
2037 static PyObject *
2038 SimpleType_from_param(PyObject *type, PyObject *value)
2040 StgDictObject *dict;
2041 char *fmt;
2042 PyCArgObject *parg;
2043 struct fielddesc *fd;
2044 PyObject *as_parameter;
2046 /* If the value is already an instance of the requested type,
2047 we can use it as is */
2048 if (1 == PyObject_IsInstance(value, type)) {
2049 Py_INCREF(value);
2050 return value;
2053 dict = PyType_stgdict(type);
2054 assert(dict);
2056 /* I think we can rely on this being a one-character string */
2057 fmt = PyString_AsString(dict->proto);
2058 assert(fmt);
2060 fd = getentry(fmt);
2061 assert(fd);
2063 parg = new_CArgObject();
2064 if (parg == NULL)
2065 return NULL;
2067 parg->tag = fmt[0];
2068 parg->pffi_type = fd->pffi_type;
2069 parg->obj = fd->setfunc(&parg->value, value, 0);
2070 if (parg->obj)
2071 return (PyObject *)parg;
2072 PyErr_Clear();
2073 Py_DECREF(parg);
2075 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
2076 if (as_parameter) {
2077 value = SimpleType_from_param(type, as_parameter);
2078 Py_DECREF(as_parameter);
2079 return value;
2081 PyErr_SetString(PyExc_TypeError,
2082 "wrong type");
2083 return NULL;
2086 static PyMethodDef SimpleType_methods[] = {
2087 { "from_param", SimpleType_from_param, METH_O, from_param_doc },
2088 { "from_address", CDataType_from_address, METH_O, from_address_doc },
2089 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
2090 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
2091 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
2092 { NULL, NULL },
2095 PyTypeObject SimpleType_Type = {
2096 PyVarObject_HEAD_INIT(NULL, 0)
2097 "_ctypes.SimpleType", /* tp_name */
2098 0, /* tp_basicsize */
2099 0, /* tp_itemsize */
2100 0, /* tp_dealloc */
2101 0, /* tp_print */
2102 0, /* tp_getattr */
2103 0, /* tp_setattr */
2104 0, /* tp_compare */
2105 0, /* tp_repr */
2106 0, /* tp_as_number */
2107 &CDataType_as_sequence, /* tp_as_sequence */
2108 0, /* tp_as_mapping */
2109 0, /* tp_hash */
2110 0, /* tp_call */
2111 0, /* tp_str */
2112 0, /* tp_getattro */
2113 0, /* tp_setattro */
2114 0, /* tp_as_buffer */
2115 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2116 "metatype for the SimpleType Objects", /* tp_doc */
2117 0, /* tp_traverse */
2118 0, /* tp_clear */
2119 0, /* tp_richcompare */
2120 0, /* tp_weaklistoffset */
2121 0, /* tp_iter */
2122 0, /* tp_iternext */
2123 SimpleType_methods, /* tp_methods */
2124 0, /* tp_members */
2125 0, /* tp_getset */
2126 0, /* tp_base */
2127 0, /* tp_dict */
2128 0, /* tp_descr_get */
2129 0, /* tp_descr_set */
2130 0, /* tp_dictoffset */
2131 0, /* tp_init */
2132 0, /* tp_alloc */
2133 SimpleType_new, /* tp_new */
2134 0, /* tp_free */
2137 /******************************************************************/
2139 CFuncPtrType_Type
2142 static PyObject *
2143 converters_from_argtypes(PyObject *ob)
2145 PyObject *converters;
2146 Py_ssize_t i;
2147 Py_ssize_t nArgs;
2149 ob = PySequence_Tuple(ob); /* new reference */
2150 if (!ob) {
2151 PyErr_SetString(PyExc_TypeError,
2152 "_argtypes_ must be a sequence of types");
2153 return NULL;
2156 nArgs = PyTuple_GET_SIZE(ob);
2157 converters = PyTuple_New(nArgs);
2158 if (!converters)
2159 return NULL;
2161 /* I have to check if this is correct. Using c_char, which has a size
2162 of 1, will be assumed to be pushed as only one byte!
2163 Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
2166 for (i = 0; i < nArgs; ++i) {
2167 PyObject *tp = PyTuple_GET_ITEM(ob, i);
2168 PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
2169 if (!cnv)
2170 goto argtypes_error_1;
2171 PyTuple_SET_ITEM(converters, i, cnv);
2173 Py_DECREF(ob);
2174 return converters;
2176 argtypes_error_1:
2177 Py_XDECREF(converters);
2178 Py_DECREF(ob);
2179 PyErr_Format(PyExc_TypeError,
2180 #if (PY_VERSION_HEX < 0x02050000)
2181 "item %d in _argtypes_ has no from_param method",
2182 #else
2183 "item %zd in _argtypes_ has no from_param method",
2184 #endif
2185 i+1);
2186 return NULL;
2189 static int
2190 make_funcptrtype_dict(StgDictObject *stgdict)
2192 PyObject *ob;
2193 PyObject *converters = NULL;
2195 stgdict->align = getentry("P")->pffi_type->alignment;
2196 stgdict->length = 1;
2197 stgdict->size = sizeof(void *);
2198 stgdict->setfunc = NULL;
2199 stgdict->getfunc = NULL;
2200 stgdict->ffi_type_pointer = ffi_type_pointer;
2202 ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
2203 if (!ob || !PyInt_Check(ob)) {
2204 PyErr_SetString(PyExc_TypeError,
2205 "class must define _flags_ which must be an integer");
2206 return -1;
2208 stgdict->flags = PyInt_AS_LONG(ob) | TYPEFLAG_ISPOINTER;
2210 /* _argtypes_ is optional... */
2211 ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
2212 if (ob) {
2213 converters = converters_from_argtypes(ob);
2214 if (!converters)
2215 goto error;
2216 Py_INCREF(ob);
2217 stgdict->argtypes = ob;
2218 stgdict->converters = converters;
2221 ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
2222 if (ob) {
2223 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2224 PyErr_SetString(PyExc_TypeError,
2225 "_restype_ must be a type, a callable, or None");
2226 return -1;
2228 Py_INCREF(ob);
2229 stgdict->restype = ob;
2230 stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
2231 if (stgdict->checker == NULL)
2232 PyErr_Clear();
2234 /* XXX later, maybe.
2235 ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
2236 if (ob) {
2237 if (!PyCallable_Check(ob)) {
2238 PyErr_SetString(PyExc_TypeError,
2239 "_errcheck_ must be callable");
2240 return -1;
2242 Py_INCREF(ob);
2243 stgdict->errcheck = ob;
2246 return 0;
2248 error:
2249 Py_XDECREF(converters);
2250 return -1;
2254 static PyCArgObject *
2255 CFuncPtrType_paramfunc(CDataObject *self)
2257 PyCArgObject *parg;
2259 parg = new_CArgObject();
2260 if (parg == NULL)
2261 return NULL;
2263 parg->tag = 'P';
2264 parg->pffi_type = &ffi_type_pointer;
2265 Py_INCREF(self);
2266 parg->obj = (PyObject *)self;
2267 parg->value.p = *(void **)self->b_ptr;
2268 return parg;
2271 static PyObject *
2272 CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2274 PyTypeObject *result;
2275 StgDictObject *stgdict;
2277 stgdict = (StgDictObject *)PyObject_CallObject(
2278 (PyObject *)&StgDict_Type, NULL);
2279 if (!stgdict)
2280 return NULL;
2282 stgdict->paramfunc = CFuncPtrType_paramfunc;
2283 /* We do NOT expose the function signature in the format string. It
2284 is impossible, generally, because the only requirement for the
2285 argtypes items is that they have a .from_param method - we do not
2286 know the types of the arguments (although, in practice, most
2287 argtypes would be a ctypes type).
2289 stgdict->format = alloc_format_string(NULL, "X{}");
2290 stgdict->flags |= TYPEFLAG_ISPOINTER;
2292 /* create the new instance (which is a class,
2293 since we are a metatype!) */
2294 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2295 if (result == NULL) {
2296 Py_DECREF((PyObject *)stgdict);
2297 return NULL;
2300 /* replace the class dict by our updated storage dict */
2301 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2302 Py_DECREF(result);
2303 Py_DECREF((PyObject *)stgdict);
2304 return NULL;
2306 Py_DECREF(result->tp_dict);
2307 result->tp_dict = (PyObject *)stgdict;
2309 if (-1 == make_funcptrtype_dict(stgdict)) {
2310 Py_DECREF(result);
2311 return NULL;
2314 return (PyObject *)result;
2317 PyTypeObject CFuncPtrType_Type = {
2318 PyVarObject_HEAD_INIT(NULL, 0)
2319 "_ctypes.CFuncPtrType", /* tp_name */
2320 0, /* tp_basicsize */
2321 0, /* tp_itemsize */
2322 0, /* tp_dealloc */
2323 0, /* tp_print */
2324 0, /* tp_getattr */
2325 0, /* tp_setattr */
2326 0, /* tp_compare */
2327 0, /* tp_repr */
2328 0, /* tp_as_number */
2329 &CDataType_as_sequence, /* tp_as_sequence */
2330 0, /* tp_as_mapping */
2331 0, /* tp_hash */
2332 0, /* tp_call */
2333 0, /* tp_str */
2334 0, /* tp_getattro */
2335 0, /* tp_setattro */
2336 0, /* tp_as_buffer */
2337 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2338 "metatype for C function pointers", /* tp_doc */
2339 (traverseproc)CDataType_traverse, /* tp_traverse */
2340 (inquiry)CDataType_clear, /* tp_clear */
2341 0, /* tp_richcompare */
2342 0, /* tp_weaklistoffset */
2343 0, /* tp_iter */
2344 0, /* tp_iternext */
2345 CDataType_methods, /* tp_methods */
2346 0, /* tp_members */
2347 0, /* tp_getset */
2348 0, /* tp_base */
2349 0, /* tp_dict */
2350 0, /* tp_descr_get */
2351 0, /* tp_descr_set */
2352 0, /* tp_dictoffset */
2353 0, /* tp_init */
2354 0, /* tp_alloc */
2355 CFuncPtrType_new, /* tp_new */
2356 0, /* tp_free */
2360 /*****************************************************************
2361 * Code to keep needed objects alive
2364 static CDataObject *
2365 CData_GetContainer(CDataObject *self)
2367 while (self->b_base)
2368 self = self->b_base;
2369 if (self->b_objects == NULL) {
2370 if (self->b_length) {
2371 self->b_objects = PyDict_New();
2372 } else {
2373 Py_INCREF(Py_None);
2374 self->b_objects = Py_None;
2377 return self;
2380 static PyObject *
2381 GetKeepedObjects(CDataObject *target)
2383 return CData_GetContainer(target)->b_objects;
2386 static PyObject *
2387 unique_key(CDataObject *target, Py_ssize_t index)
2389 char string[256];
2390 char *cp = string;
2391 size_t bytes_left;
2393 assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
2394 #if (PY_VERSION_HEX < 0x02050000)
2395 cp += sprintf(cp, "%x", index);
2396 #else
2397 cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2398 #endif
2399 while (target->b_base) {
2400 bytes_left = sizeof(string) - (cp - string) - 1;
2401 /* Hex format needs 2 characters per byte */
2402 if (bytes_left < sizeof(Py_ssize_t) * 2) {
2403 PyErr_SetString(PyExc_ValueError,
2404 "ctypes object structure too deep");
2405 return NULL;
2407 #if (PY_VERSION_HEX < 0x02050000)
2408 cp += sprintf(cp, ":%x", (int)target->b_index);
2409 #else
2410 cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
2411 #endif
2412 target = target->b_base;
2414 return PyString_FromStringAndSize(string, cp-string);
2418 * Keep a reference to 'keep' in the 'target', at index 'index'.
2420 * If 'keep' is None, do nothing.
2422 * Otherwise create a dictionary (if it does not yet exist) id the root
2423 * objects 'b_objects' item, which will store the 'keep' object under a unique
2424 * key.
2426 * The unique_key helper travels the target's b_base pointer down to the root,
2427 * building a string containing hex-formatted indexes found during traversal,
2428 * separated by colons.
2430 * The index tuple is used as a key into the root object's b_objects dict.
2432 * Note: This function steals a refcount of the third argument, even if it
2433 * fails!
2435 static int
2436 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
2438 int result;
2439 CDataObject *ob;
2440 PyObject *key;
2442 /* Optimization: no need to store None */
2443 if (keep == Py_None) {
2444 Py_DECREF(Py_None);
2445 return 0;
2447 ob = CData_GetContainer(target);
2448 if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
2449 Py_XDECREF(ob->b_objects);
2450 ob->b_objects = keep; /* refcount consumed */
2451 return 0;
2453 key = unique_key(target, index);
2454 if (key == NULL) {
2455 Py_DECREF(keep);
2456 return -1;
2458 result = PyDict_SetItem(ob->b_objects, key, keep);
2459 Py_DECREF(key);
2460 Py_DECREF(keep);
2461 return result;
2464 /******************************************************************/
2466 CData_Type
2468 static int
2469 CData_traverse(CDataObject *self, visitproc visit, void *arg)
2471 Py_VISIT(self->b_objects);
2472 Py_VISIT((PyObject *)self->b_base);
2473 return 0;
2476 static int
2477 CData_clear(CDataObject *self)
2479 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
2480 assert(dict); /* Cannot be NULL for CDataObject instances */
2481 Py_CLEAR(self->b_objects);
2482 if ((self->b_needsfree)
2483 && ((size_t)dict->size > sizeof(self->b_value)))
2484 PyMem_Free(self->b_ptr);
2485 self->b_ptr = NULL;
2486 Py_CLEAR(self->b_base);
2487 return 0;
2490 static void
2491 CData_dealloc(PyObject *self)
2493 CData_clear((CDataObject *)self);
2494 Py_TYPE(self)->tp_free(self);
2497 static PyMemberDef CData_members[] = {
2498 { "_b_base_", T_OBJECT,
2499 offsetof(CDataObject, b_base), READONLY,
2500 "the base object" },
2501 { "_b_needsfree_", T_INT,
2502 offsetof(CDataObject, b_needsfree), READONLY,
2503 "whether the object owns the memory or not" },
2504 { "_objects", T_OBJECT,
2505 offsetof(CDataObject, b_objects), READONLY,
2506 "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2507 { NULL },
2510 #if (PY_VERSION_HEX >= 0x02060000)
2511 static int CData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags)
2513 CDataObject *self = (CDataObject *)_self;
2514 StgDictObject *dict = PyObject_stgdict(_self);
2515 Py_ssize_t i;
2517 if (view == NULL) return 0;
2519 view->buf = self->b_ptr;
2520 view->obj = _self;
2521 Py_INCREF(_self);
2522 view->len = self->b_size;
2523 view->readonly = 0;
2524 /* use default format character if not set */
2525 view->format = dict->format ? dict->format : "B";
2526 view->ndim = dict->ndim;
2527 view->shape = dict->shape;
2528 view->itemsize = self->b_size;
2529 for (i = 0; i < view->ndim; ++i) {
2530 view->itemsize /= dict->shape[i];
2532 view->strides = NULL;
2533 view->suboffsets = NULL;
2534 view->internal = NULL;
2535 return 0;
2537 #endif
2539 static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
2541 if (lenp)
2542 *lenp = 1;
2543 return 1;
2546 static Py_ssize_t CData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr)
2548 CDataObject *self = (CDataObject *)_self;
2549 if (seg != 0) {
2550 /* Hm. Must this set an exception? */
2551 return -1;
2553 *pptr = self->b_ptr;
2554 return self->b_size;
2557 static PyBufferProcs CData_as_buffer = {
2558 (readbufferproc)CData_GetBuffer,
2559 (writebufferproc)CData_GetBuffer,
2560 (segcountproc)CData_GetSegcount,
2561 (charbufferproc)NULL,
2562 #if (PY_VERSION_HEX >= 0x02060000)
2563 (getbufferproc)CData_NewGetBuffer,
2564 (releasebufferproc)NULL,
2565 #endif
2569 * CData objects are mutable, so they cannot be hashable!
2571 static long
2572 CData_nohash(PyObject *self)
2574 PyErr_SetString(PyExc_TypeError, "unhashable type");
2575 return -1;
2578 static PyObject *
2579 CData_reduce(PyObject *_self, PyObject *args)
2581 CDataObject *self = (CDataObject *)_self;
2583 if (PyObject_stgdict(_self)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
2584 PyErr_SetString(PyExc_ValueError,
2585 "ctypes objects containing pointers cannot be pickled");
2586 return NULL;
2588 return Py_BuildValue("O(O(NN))",
2589 _unpickle,
2590 Py_TYPE(_self),
2591 PyObject_GetAttrString(_self, "__dict__"),
2592 PyString_FromStringAndSize(self->b_ptr, self->b_size));
2595 static PyObject *
2596 CData_setstate(PyObject *_self, PyObject *args)
2598 void *data;
2599 Py_ssize_t len;
2600 int res;
2601 PyObject *dict, *mydict;
2602 CDataObject *self = (CDataObject *)_self;
2603 if (!PyArg_ParseTuple(args, "Os#", &dict, &data, &len))
2604 return NULL;
2605 if (len > self->b_size)
2606 len = self->b_size;
2607 memmove(self->b_ptr, data, len);
2608 mydict = PyObject_GetAttrString(_self, "__dict__");
2609 res = PyDict_Update(mydict, dict);
2610 Py_DECREF(mydict);
2611 if (res == -1)
2612 return NULL;
2613 Py_INCREF(Py_None);
2614 return Py_None;
2618 * default __ctypes_from_outparam__ method returns self.
2620 static PyObject *
2621 CData_from_outparam(PyObject *self, PyObject *args)
2623 Py_INCREF(self);
2624 return self;
2627 static PyMethodDef CData_methods[] = {
2628 { "__ctypes_from_outparam__", CData_from_outparam, METH_NOARGS, },
2629 { "__reduce__", CData_reduce, METH_NOARGS, },
2630 { "__setstate__", CData_setstate, METH_VARARGS, },
2631 { NULL, NULL },
2634 PyTypeObject CData_Type = {
2635 PyVarObject_HEAD_INIT(NULL, 0)
2636 "_ctypes._CData",
2637 sizeof(CDataObject), /* tp_basicsize */
2638 0, /* tp_itemsize */
2639 CData_dealloc, /* tp_dealloc */
2640 0, /* tp_print */
2641 0, /* tp_getattr */
2642 0, /* tp_setattr */
2643 0, /* tp_compare */
2644 0, /* tp_repr */
2645 0, /* tp_as_number */
2646 0, /* tp_as_sequence */
2647 0, /* tp_as_mapping */
2648 CData_nohash, /* tp_hash */
2649 0, /* tp_call */
2650 0, /* tp_str */
2651 0, /* tp_getattro */
2652 0, /* tp_setattro */
2653 &CData_as_buffer, /* tp_as_buffer */
2654 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
2655 "XXX to be provided", /* tp_doc */
2656 (traverseproc)CData_traverse, /* tp_traverse */
2657 (inquiry)CData_clear, /* tp_clear */
2658 0, /* tp_richcompare */
2659 0, /* tp_weaklistoffset */
2660 0, /* tp_iter */
2661 0, /* tp_iternext */
2662 CData_methods, /* tp_methods */
2663 CData_members, /* tp_members */
2664 0, /* tp_getset */
2665 0, /* tp_base */
2666 0, /* tp_dict */
2667 0, /* tp_descr_get */
2668 0, /* tp_descr_set */
2669 0, /* tp_dictoffset */
2670 0, /* tp_init */
2671 0, /* tp_alloc */
2672 0, /* tp_new */
2673 0, /* tp_free */
2676 static int CData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
2678 if ((size_t)dict->size <= sizeof(obj->b_value)) {
2679 /* No need to call malloc, can use the default buffer */
2680 obj->b_ptr = (char *)&obj->b_value;
2681 /* The b_needsfree flag does not mean that we actually did
2682 call PyMem_Malloc to allocate the memory block; instead it
2683 means we are the *owner* of the memory and are responsible
2684 for freeing resources associated with the memory. This is
2685 also the reason that b_needsfree is exposed to Python.
2687 obj->b_needsfree = 1;
2688 } else {
2689 /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2690 33% of the creation time for c_int().
2692 obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2693 if (obj->b_ptr == NULL) {
2694 PyErr_NoMemory();
2695 return -1;
2697 obj->b_needsfree = 1;
2698 memset(obj->b_ptr, 0, dict->size);
2700 obj->b_size = dict->size;
2701 return 0;
2704 PyObject *
2705 CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
2707 CDataObject *cmem;
2708 StgDictObject *dict;
2710 assert(PyType_Check(type));
2711 dict = PyType_stgdict(type);
2712 if (!dict) {
2713 PyErr_SetString(PyExc_TypeError,
2714 "abstract class");
2715 return NULL;
2717 dict->flags |= DICTFLAG_FINAL;
2718 cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2719 if (cmem == NULL)
2720 return NULL;
2721 assert(CDataObject_Check(cmem));
2723 cmem->b_length = dict->length;
2724 cmem->b_size = dict->size;
2725 if (base) { /* use base's buffer */
2726 assert(CDataObject_Check(base));
2727 cmem->b_ptr = adr;
2728 cmem->b_needsfree = 0;
2729 Py_INCREF(base);
2730 cmem->b_base = (CDataObject *)base;
2731 cmem->b_index = index;
2732 } else { /* copy contents of adr */
2733 if (-1 == CData_MallocBuffer(cmem, dict)) {
2734 return NULL;
2735 Py_DECREF(cmem);
2737 memcpy(cmem->b_ptr, adr, dict->size);
2738 cmem->b_index = index;
2740 return (PyObject *)cmem;
2744 Box a memory block into a CData instance.
2746 PyObject *
2747 CData_AtAddress(PyObject *type, void *buf)
2749 CDataObject *pd;
2750 StgDictObject *dict;
2752 assert(PyType_Check(type));
2753 dict = PyType_stgdict(type);
2754 if (!dict) {
2755 PyErr_SetString(PyExc_TypeError,
2756 "abstract class");
2757 return NULL;
2759 dict->flags |= DICTFLAG_FINAL;
2761 pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2762 if (!pd)
2763 return NULL;
2764 assert(CDataObject_Check(pd));
2765 pd->b_ptr = (char *)buf;
2766 pd->b_length = dict->length;
2767 pd->b_size = dict->size;
2768 return (PyObject *)pd;
2772 This function returns TRUE for c_int, c_void_p, and these kind of
2773 classes. FALSE otherwise FALSE also for subclasses of c_int and
2774 such.
2776 int IsSimpleSubType(PyObject *obj)
2778 PyTypeObject *type = (PyTypeObject *)obj;
2780 if (SimpleTypeObject_Check(type))
2781 return type->tp_base != &Simple_Type;
2782 return 0;
2785 PyObject *
2786 CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
2787 Py_ssize_t index, Py_ssize_t size, char *adr)
2789 StgDictObject *dict;
2790 if (getfunc)
2791 return getfunc(adr, size);
2792 assert(type);
2793 dict = PyType_stgdict(type);
2794 if (dict && dict->getfunc && !IsSimpleSubType(type))
2795 return dict->getfunc(adr, size);
2796 return CData_FromBaseObj(type, src, index, adr);
2800 Helper function for CData_set below.
2802 static PyObject *
2803 _CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2804 Py_ssize_t size, char *ptr)
2806 CDataObject *src;
2808 if (setfunc)
2809 return setfunc(ptr, value, size);
2811 if (!CDataObject_Check(value)) {
2812 StgDictObject *dict = PyType_stgdict(type);
2813 if (dict && dict->setfunc)
2814 return dict->setfunc(ptr, value, size);
2816 If value is a tuple, we try to call the type with the tuple
2817 and use the result!
2819 assert(PyType_Check(type));
2820 if (PyTuple_Check(value)) {
2821 PyObject *ob;
2822 PyObject *result;
2823 ob = PyObject_CallObject(type, value);
2824 if (ob == NULL) {
2825 Extend_Error_Info(PyExc_RuntimeError, "(%s) ",
2826 ((PyTypeObject *)type)->tp_name);
2827 return NULL;
2829 result = _CData_set(dst, type, setfunc, ob,
2830 size, ptr);
2831 Py_DECREF(ob);
2832 return result;
2833 } else if (value == Py_None && PointerTypeObject_Check(type)) {
2834 *(void **)ptr = NULL;
2835 Py_INCREF(Py_None);
2836 return Py_None;
2837 } else {
2838 PyErr_Format(PyExc_TypeError,
2839 "expected %s instance, got %s",
2840 ((PyTypeObject *)type)->tp_name,
2841 Py_TYPE(value)->tp_name);
2842 return NULL;
2845 src = (CDataObject *)value;
2847 if (PyObject_IsInstance(value, type)) {
2848 memcpy(ptr,
2849 src->b_ptr,
2850 size);
2852 if (PointerTypeObject_Check(type))
2853 /* XXX */;
2855 value = GetKeepedObjects(src);
2856 Py_INCREF(value);
2857 return value;
2860 if (PointerTypeObject_Check(type)
2861 && ArrayObject_Check(value)) {
2862 StgDictObject *p1, *p2;
2863 PyObject *keep;
2864 p1 = PyObject_stgdict(value);
2865 assert(p1); /* Cannot be NULL for array instances */
2866 p2 = PyType_stgdict(type);
2867 assert(p2); /* Cannot be NULL for pointer types */
2869 if (p1->proto != p2->proto) {
2870 PyErr_Format(PyExc_TypeError,
2871 "incompatible types, %s instance instead of %s instance",
2872 Py_TYPE(value)->tp_name,
2873 ((PyTypeObject *)type)->tp_name);
2874 return NULL;
2876 *(void **)ptr = src->b_ptr;
2878 keep = GetKeepedObjects(src);
2880 We are assigning an array object to a field which represents
2881 a pointer. This has the same effect as converting an array
2882 into a pointer. So, again, we have to keep the whole object
2883 pointed to (which is the array in this case) alive, and not
2884 only it's object list. So we create a tuple, containing
2885 b_objects list PLUS the array itself, and return that!
2887 return PyTuple_Pack(2, keep, value);
2889 PyErr_Format(PyExc_TypeError,
2890 "incompatible types, %s instance instead of %s instance",
2891 Py_TYPE(value)->tp_name,
2892 ((PyTypeObject *)type)->tp_name);
2893 return NULL;
2897 * Set a slice in object 'dst', which has the type 'type',
2898 * to the value 'value'.
2901 CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2902 Py_ssize_t index, Py_ssize_t size, char *ptr)
2904 CDataObject *mem = (CDataObject *)dst;
2905 PyObject *result;
2907 if (!CDataObject_Check(dst)) {
2908 PyErr_SetString(PyExc_TypeError,
2909 "not a ctype instance");
2910 return -1;
2913 result = _CData_set(mem, type, setfunc, value,
2914 size, ptr);
2915 if (result == NULL)
2916 return -1;
2918 /* KeepRef steals a refcount from it's last argument */
2919 /* If KeepRef fails, we are stumped. The dst memory block has already
2920 been changed */
2921 return KeepRef(mem, index, result);
2925 /******************************************************************/
2926 static PyObject *
2927 GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2929 CDataObject *obj;
2930 StgDictObject *dict;
2932 dict = PyType_stgdict((PyObject *)type);
2933 if (!dict) {
2934 PyErr_SetString(PyExc_TypeError,
2935 "abstract class");
2936 return NULL;
2938 dict->flags |= DICTFLAG_FINAL;
2940 obj = (CDataObject *)type->tp_alloc(type, 0);
2941 if (!obj)
2942 return NULL;
2944 obj->b_base = NULL;
2945 obj->b_index = 0;
2946 obj->b_objects = NULL;
2947 obj->b_length = dict->length;
2949 if (-1 == CData_MallocBuffer(obj, dict)) {
2950 Py_DECREF(obj);
2951 return NULL;
2953 return (PyObject *)obj;
2955 /*****************************************************************/
2957 CFuncPtr_Type
2960 static int
2961 CFuncPtr_set_errcheck(CFuncPtrObject *self, PyObject *ob)
2963 if (ob && !PyCallable_Check(ob)) {
2964 PyErr_SetString(PyExc_TypeError,
2965 "the errcheck attribute must be callable");
2966 return -1;
2968 Py_XDECREF(self->errcheck);
2969 Py_XINCREF(ob);
2970 self->errcheck = ob;
2971 return 0;
2974 static PyObject *
2975 CFuncPtr_get_errcheck(CFuncPtrObject *self)
2977 if (self->errcheck) {
2978 Py_INCREF(self->errcheck);
2979 return self->errcheck;
2981 Py_INCREF(Py_None);
2982 return Py_None;
2985 static int
2986 CFuncPtr_set_restype(CFuncPtrObject *self, PyObject *ob)
2988 if (ob == NULL) {
2989 Py_XDECREF(self->restype);
2990 self->restype = NULL;
2991 Py_XDECREF(self->checker);
2992 self->checker = NULL;
2993 return 0;
2995 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2996 PyErr_SetString(PyExc_TypeError,
2997 "restype must be a type, a callable, or None");
2998 return -1;
3000 Py_XDECREF(self->checker);
3001 Py_XDECREF(self->restype);
3002 Py_INCREF(ob);
3003 self->restype = ob;
3004 self->checker = PyObject_GetAttrString(ob, "_check_retval_");
3005 if (self->checker == NULL)
3006 PyErr_Clear();
3007 return 0;
3010 static PyObject *
3011 CFuncPtr_get_restype(CFuncPtrObject *self)
3013 StgDictObject *dict;
3014 if (self->restype) {
3015 Py_INCREF(self->restype);
3016 return self->restype;
3018 dict = PyObject_stgdict((PyObject *)self);
3019 assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
3020 if (dict->restype) {
3021 Py_INCREF(dict->restype);
3022 return dict->restype;
3023 } else {
3024 Py_INCREF(Py_None);
3025 return Py_None;
3029 static int
3030 CFuncPtr_set_argtypes(CFuncPtrObject *self, PyObject *ob)
3032 PyObject *converters;
3034 if (ob == NULL || ob == Py_None) {
3035 Py_XDECREF(self->converters);
3036 self->converters = NULL;
3037 Py_XDECREF(self->argtypes);
3038 self->argtypes = NULL;
3039 } else {
3040 converters = converters_from_argtypes(ob);
3041 if (!converters)
3042 return -1;
3043 Py_XDECREF(self->converters);
3044 self->converters = converters;
3045 Py_XDECREF(self->argtypes);
3046 Py_INCREF(ob);
3047 self->argtypes = ob;
3049 return 0;
3052 static PyObject *
3053 CFuncPtr_get_argtypes(CFuncPtrObject *self)
3055 StgDictObject *dict;
3056 if (self->argtypes) {
3057 Py_INCREF(self->argtypes);
3058 return self->argtypes;
3060 dict = PyObject_stgdict((PyObject *)self);
3061 assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
3062 if (dict->argtypes) {
3063 Py_INCREF(dict->argtypes);
3064 return dict->argtypes;
3065 } else {
3066 Py_INCREF(Py_None);
3067 return Py_None;
3071 static PyGetSetDef CFuncPtr_getsets[] = {
3072 { "errcheck", (getter)CFuncPtr_get_errcheck, (setter)CFuncPtr_set_errcheck,
3073 "a function to check for errors", NULL },
3074 { "restype", (getter)CFuncPtr_get_restype, (setter)CFuncPtr_set_restype,
3075 "specify the result type", NULL },
3076 { "argtypes", (getter)CFuncPtr_get_argtypes,
3077 (setter)CFuncPtr_set_argtypes,
3078 "specify the argument types", NULL },
3079 { NULL, NULL }
3082 #ifdef MS_WIN32
3083 static PPROC FindAddress(void *handle, char *name, PyObject *type)
3085 #ifdef MS_WIN64
3086 /* win64 has no stdcall calling conv, so it should
3087 also not have the name mangling of it.
3089 return (PPROC)GetProcAddress(handle, name);
3090 #else
3091 PPROC address;
3092 char *mangled_name;
3093 int i;
3094 StgDictObject *dict;
3096 address = (PPROC)GetProcAddress(handle, name);
3097 if (address)
3098 return address;
3099 if (((size_t)name & ~0xFFFF) == 0) {
3100 return NULL;
3103 dict = PyType_stgdict((PyObject *)type);
3104 /* It should not happen that dict is NULL, but better be safe */
3105 if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
3106 return address;
3108 /* for stdcall, try mangled names:
3109 funcname -> _funcname@<n>
3110 where n is 0, 4, 8, 12, ..., 128
3112 mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
3113 if (!mangled_name)
3114 return NULL;
3115 for (i = 0; i < 32; ++i) {
3116 sprintf(mangled_name, "_%s@%d", name, i*4);
3117 address = (PPROC)GetProcAddress(handle, mangled_name);
3118 if (address)
3119 return address;
3121 return NULL;
3122 #endif
3124 #endif
3126 /* Return 1 if usable, 0 else and exception set. */
3127 static int
3128 _check_outarg_type(PyObject *arg, Py_ssize_t index)
3130 StgDictObject *dict;
3132 if (PointerTypeObject_Check(arg))
3133 return 1;
3135 if (ArrayTypeObject_Check(arg))
3136 return 1;
3138 dict = PyType_stgdict(arg);
3139 if (dict
3140 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
3141 && PyString_Check(dict->proto)
3142 /* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
3143 && (strchr("PzZ", PyString_AS_STRING(dict->proto)[0]))) {
3144 return 1;
3147 PyErr_Format(PyExc_TypeError,
3148 "'out' parameter %d must be a pointer type, not %s",
3149 Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
3150 PyType_Check(arg) ?
3151 ((PyTypeObject *)arg)->tp_name :
3152 Py_TYPE(arg)->tp_name);
3153 return 0;
3156 /* Returns 1 on success, 0 on error */
3157 static int
3158 _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
3160 Py_ssize_t i, len;
3161 StgDictObject *dict;
3162 PyObject *argtypes;
3164 dict = PyType_stgdict((PyObject *)type);
3165 assert(dict); /* Cannot be NULL. 'type' is a CFuncPtr type. */
3166 argtypes = dict->argtypes;
3168 if (paramflags == NULL || dict->argtypes == NULL)
3169 return 1;
3171 if (!PyTuple_Check(paramflags)) {
3172 PyErr_SetString(PyExc_TypeError,
3173 "paramflags must be a tuple or None");
3174 return 0;
3177 len = PyTuple_GET_SIZE(paramflags);
3178 if (len != PyTuple_GET_SIZE(dict->argtypes)) {
3179 PyErr_SetString(PyExc_ValueError,
3180 "paramflags must have the same length as argtypes");
3181 return 0;
3184 for (i = 0; i < len; ++i) {
3185 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3186 int flag;
3187 char *name;
3188 PyObject *defval;
3189 PyObject *typ;
3190 if (!PyArg_ParseTuple(item, "i|zO", &flag, &name, &defval)) {
3191 PyErr_SetString(PyExc_TypeError,
3192 "paramflags must be a sequence of (int [,string [,value]]) tuples");
3193 return 0;
3195 typ = PyTuple_GET_ITEM(argtypes, i);
3196 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3197 case 0:
3198 case PARAMFLAG_FIN:
3199 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3200 case PARAMFLAG_FIN | PARAMFLAG_FOUT:
3201 break;
3202 case PARAMFLAG_FOUT:
3203 if (!_check_outarg_type(typ, i+1))
3204 return 0;
3205 break;
3206 default:
3207 PyErr_Format(PyExc_TypeError,
3208 "paramflag value %d not supported",
3209 flag);
3210 return 0;
3213 return 1;
3216 static int
3217 _get_name(PyObject *obj, char **pname)
3219 #ifdef MS_WIN32
3220 if (PyInt_Check(obj) || PyLong_Check(obj)) {
3221 /* We have to use MAKEINTRESOURCEA for Windows CE.
3222 Works on Windows as well, of course.
3224 *pname = MAKEINTRESOURCEA(PyInt_AsUnsignedLongMask(obj) & 0xFFFF);
3225 return 1;
3227 #endif
3228 if (PyString_Check(obj) || PyUnicode_Check(obj)) {
3229 *pname = PyString_AsString(obj);
3230 return *pname ? 1 : 0;
3232 PyErr_SetString(PyExc_TypeError,
3233 "function name must be string or integer");
3234 return 0;
3238 static PyObject *
3239 CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
3241 char *name;
3242 int (* address)(void);
3243 PyObject *dll;
3244 PyObject *obj;
3245 CFuncPtrObject *self;
3246 void *handle;
3247 PyObject *paramflags = NULL;
3249 if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
3250 return NULL;
3251 if (paramflags == Py_None)
3252 paramflags = NULL;
3254 obj = PyObject_GetAttrString(dll, "_handle");
3255 if (!obj)
3256 return NULL;
3257 if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
3258 PyErr_SetString(PyExc_TypeError,
3259 "the _handle attribute of the second argument must be an integer");
3260 Py_DECREF(obj);
3261 return NULL;
3263 handle = (void *)PyLong_AsVoidPtr(obj);
3264 Py_DECREF(obj);
3265 if (PyErr_Occurred()) {
3266 PyErr_SetString(PyExc_ValueError,
3267 "could not convert the _handle attribute to a pointer");
3268 return NULL;
3271 #ifdef MS_WIN32
3272 address = FindAddress(handle, name, (PyObject *)type);
3273 if (!address) {
3274 if (!IS_INTRESOURCE(name))
3275 PyErr_Format(PyExc_AttributeError,
3276 "function '%s' not found",
3277 name);
3278 else
3279 PyErr_Format(PyExc_AttributeError,
3280 "function ordinal %d not found",
3281 (WORD)(size_t)name);
3282 return NULL;
3284 #else
3285 address = (PPROC)ctypes_dlsym(handle, name);
3286 if (!address) {
3287 #ifdef __CYGWIN__
3288 /* dlerror() isn't very helpful on cygwin */
3289 PyErr_Format(PyExc_AttributeError,
3290 "function '%s' not found (%s) ",
3291 name);
3292 #else
3293 PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
3294 #endif
3295 return NULL;
3297 #endif
3298 if (!_validate_paramflags(type, paramflags))
3299 return NULL;
3301 self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
3302 if (!self)
3303 return NULL;
3305 Py_XINCREF(paramflags);
3306 self->paramflags = paramflags;
3308 *(void **)self->b_ptr = address;
3310 Py_INCREF((PyObject *)dll); /* for KeepRef */
3311 if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
3312 Py_DECREF((PyObject *)self);
3313 return NULL;
3316 Py_INCREF(self);
3317 self->callable = (PyObject *)self;
3318 return (PyObject *)self;
3321 #ifdef MS_WIN32
3322 static PyObject *
3323 CFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
3325 CFuncPtrObject *self;
3326 int index;
3327 char *name = NULL;
3328 PyObject *paramflags = NULL;
3329 GUID *iid = NULL;
3330 Py_ssize_t iid_len = 0;
3332 if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
3333 return NULL;
3334 if (paramflags == Py_None)
3335 paramflags = NULL;
3337 if (!_validate_paramflags(type, paramflags))
3338 return NULL;
3340 self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
3341 self->index = index + 0x1000;
3342 Py_XINCREF(paramflags);
3343 self->paramflags = paramflags;
3344 if (iid_len == sizeof(GUID))
3345 self->iid = iid;
3346 return (PyObject *)self;
3348 #endif
3351 CFuncPtr_new accepts different argument lists in addition to the standard
3352 _basespec_ keyword arg:
3354 one argument form
3355 "i" - function address
3356 "O" - must be a callable, creates a C callable function
3358 two or more argument forms (the third argument is a paramflags tuple)
3359 "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
3360 "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
3361 "is|..." - vtable index, method name, creates callable calling COM vtbl
3363 static PyObject *
3364 CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3366 CFuncPtrObject *self;
3367 PyObject *callable;
3368 StgDictObject *dict;
3369 CThunkObject *thunk;
3371 if (PyTuple_GET_SIZE(args) == 0)
3372 return GenericCData_new(type, args, kwds);
3374 if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
3375 return CFuncPtr_FromDll(type, args, kwds);
3377 #ifdef MS_WIN32
3378 if (2 <= PyTuple_GET_SIZE(args) && PyInt_Check(PyTuple_GET_ITEM(args, 0)))
3379 return CFuncPtr_FromVtblIndex(type, args, kwds);
3380 #endif
3382 if (1 == PyTuple_GET_SIZE(args)
3383 && (PyInt_Check(PyTuple_GET_ITEM(args, 0))
3384 || PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
3385 CDataObject *ob;
3386 void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
3387 if (ptr == NULL && PyErr_Occurred())
3388 return NULL;
3389 ob = (CDataObject *)GenericCData_new(type, args, kwds);
3390 if (ob == NULL)
3391 return NULL;
3392 *(void **)ob->b_ptr = ptr;
3393 return (PyObject *)ob;
3396 if (!PyArg_ParseTuple(args, "O", &callable))
3397 return NULL;
3398 if (!PyCallable_Check(callable)) {
3399 PyErr_SetString(PyExc_TypeError,
3400 "argument must be callable or integer function address");
3401 return NULL;
3404 /* XXX XXX This would allow to pass additional options. For COM
3405 method *implementations*, we would probably want different
3406 behaviour than in 'normal' callback functions: return a HRESULT if
3407 an exception occurrs in the callback, and print the traceback not
3408 only on the console, but also to OutputDebugString() or something
3409 like that.
3412 if (kwds && PyDict_GetItemString(kwds, "options")) {
3417 dict = PyType_stgdict((PyObject *)type);
3418 /* XXXX Fails if we do: 'CFuncPtr(lambda x: x)' */
3419 if (!dict || !dict->argtypes) {
3420 PyErr_SetString(PyExc_TypeError,
3421 "cannot construct instance of this class:"
3422 " no argtypes");
3423 return NULL;
3426 thunk = AllocFunctionCallback(callable,
3427 dict->argtypes,
3428 dict->restype,
3429 dict->flags);
3430 if (!thunk)
3431 return NULL;
3433 self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
3434 if (self == NULL) {
3435 Py_DECREF(thunk);
3436 return NULL;
3439 Py_INCREF(callable);
3440 self->callable = callable;
3442 self->thunk = thunk;
3443 *(void **)self->b_ptr = (void *)thunk->pcl;
3445 Py_INCREF((PyObject *)thunk); /* for KeepRef */
3446 if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3447 Py_DECREF((PyObject *)self);
3448 return NULL;
3450 return (PyObject *)self;
3455 _byref consumes a refcount to its argument
3457 static PyObject *
3458 _byref(PyObject *obj)
3460 PyCArgObject *parg;
3461 if (!CDataObject_Check(obj)) {
3462 PyErr_SetString(PyExc_TypeError,
3463 "expected CData instance");
3464 return NULL;
3467 parg = new_CArgObject();
3468 if (parg == NULL) {
3469 Py_DECREF(obj);
3470 return NULL;
3473 parg->tag = 'P';
3474 parg->pffi_type = &ffi_type_pointer;
3475 parg->obj = obj;
3476 parg->value.p = ((CDataObject *)obj)->b_ptr;
3477 return (PyObject *)parg;
3480 static PyObject *
3481 _get_arg(int *pindex, char *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
3483 PyObject *v;
3485 if (*pindex < PyTuple_GET_SIZE(inargs)) {
3486 v = PyTuple_GET_ITEM(inargs, *pindex);
3487 ++*pindex;
3488 Py_INCREF(v);
3489 return v;
3491 if (kwds && (v = PyDict_GetItemString(kwds, name))) {
3492 ++*pindex;
3493 Py_INCREF(v);
3494 return v;
3496 if (defval) {
3497 Py_INCREF(defval);
3498 return defval;
3500 /* we can't currently emit a better error message */
3501 if (name)
3502 PyErr_Format(PyExc_TypeError,
3503 "required argument '%s' missing", name);
3504 else
3505 PyErr_Format(PyExc_TypeError,
3506 "not enough arguments");
3507 return NULL;
3511 This function implements higher level functionality plus the ability to call
3512 functions with keyword arguments by looking at parameter flags. parameter
3513 flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer
3514 specifying the direction of the data transfer for this parameter - 'in',
3515 'out' or 'inout' (zero means the same as 'in'). The second entry is the
3516 parameter name, and the third is the default value if the parameter is
3517 missing in the function call.
3519 This function builds and returns a new tuple 'callargs' which contains the
3520 parameters to use in the call. Items on this tuple are copied from the
3521 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
3522 'argtypes' tuple for 'out' parameters. It also calculates numretvals which
3523 is the number of return values for the function, outmask/inoutmask are
3524 bitmasks containing indexes into the callargs tuple specifying which
3525 parameters have to be returned. _build_result builds the return value of the
3526 function.
3528 static PyObject *
3529 _build_callargs(CFuncPtrObject *self, PyObject *argtypes,
3530 PyObject *inargs, PyObject *kwds,
3531 int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
3533 PyObject *paramflags = self->paramflags;
3534 PyObject *callargs;
3535 StgDictObject *dict;
3536 Py_ssize_t i, len;
3537 int inargs_index = 0;
3538 /* It's a little bit difficult to determine how many arguments the
3539 function call requires/accepts. For simplicity, we count the consumed
3540 args and compare this to the number of supplied args. */
3541 Py_ssize_t actual_args;
3543 *poutmask = 0;
3544 *pinoutmask = 0;
3545 *pnumretvals = 0;
3547 /* Trivial cases, where we either return inargs itself, or a slice of it. */
3548 if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
3549 #ifdef MS_WIN32
3550 if (self->index)
3551 return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
3552 #endif
3553 Py_INCREF(inargs);
3554 return inargs;
3557 len = PyTuple_GET_SIZE(argtypes);
3558 callargs = PyTuple_New(len); /* the argument tuple we build */
3559 if (callargs == NULL)
3560 return NULL;
3562 #ifdef MS_WIN32
3563 /* For a COM method, skip the first arg */
3564 if (self->index) {
3565 inargs_index = 1;
3567 #endif
3568 for (i = 0; i < len; ++i) {
3569 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3570 PyObject *ob;
3571 int flag;
3572 char *name = NULL;
3573 PyObject *defval = NULL;
3575 /* This way seems to be ~2 us faster than the PyArg_ParseTuple
3576 calls below. */
3577 /* We HAVE already checked that the tuple can be parsed with "i|zO", so... */
3578 Py_ssize_t tsize = PyTuple_GET_SIZE(item);
3579 flag = PyInt_AS_LONG(PyTuple_GET_ITEM(item, 0));
3580 name = tsize > 1 ? PyString_AS_STRING(PyTuple_GET_ITEM(item, 1)) : NULL;
3581 defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
3583 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3584 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3585 /* ['in', 'lcid'] parameter. Always taken from defval,
3586 if given, else the integer 0. */
3587 if (defval == NULL) {
3588 defval = PyInt_FromLong(0);
3589 if (defval == NULL)
3590 goto error;
3591 } else
3592 Py_INCREF(defval);
3593 PyTuple_SET_ITEM(callargs, i, defval);
3594 break;
3595 case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
3596 *pinoutmask |= (1 << i); /* mark as inout arg */
3597 (*pnumretvals)++;
3598 /* fall through to PARAMFLAG_FIN... */
3599 case 0:
3600 case PARAMFLAG_FIN:
3601 /* 'in' parameter. Copy it from inargs. */
3602 ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
3603 if (ob == NULL)
3604 goto error;
3605 PyTuple_SET_ITEM(callargs, i, ob);
3606 break;
3607 case PARAMFLAG_FOUT:
3608 /* XXX Refactor this code into a separate function. */
3609 /* 'out' parameter.
3610 argtypes[i] must be a POINTER to a c type.
3612 Cannot by supplied in inargs, but a defval will be used
3613 if available. XXX Should we support getting it from kwds?
3615 if (defval) {
3616 /* XXX Using mutable objects as defval will
3617 make the function non-threadsafe, unless we
3618 copy the object in each invocation */
3619 Py_INCREF(defval);
3620 PyTuple_SET_ITEM(callargs, i, defval);
3621 *poutmask |= (1 << i); /* mark as out arg */
3622 (*pnumretvals)++;
3623 break;
3625 ob = PyTuple_GET_ITEM(argtypes, i);
3626 dict = PyType_stgdict(ob);
3627 if (dict == NULL) {
3628 /* Cannot happen: _validate_paramflags()
3629 would not accept such an object */
3630 PyErr_Format(PyExc_RuntimeError,
3631 "NULL stgdict unexpected");
3632 goto error;
3634 if (PyString_Check(dict->proto)) {
3635 PyErr_Format(
3636 PyExc_TypeError,
3637 "%s 'out' parameter must be passed as default value",
3638 ((PyTypeObject *)ob)->tp_name);
3639 goto error;
3641 if (ArrayTypeObject_Check(ob))
3642 ob = PyObject_CallObject(ob, NULL);
3643 else
3644 /* Create an instance of the pointed-to type */
3645 ob = PyObject_CallObject(dict->proto, NULL);
3647 XXX Is the following correct any longer?
3648 We must not pass a byref() to the array then but
3649 the array instance itself. Then, we cannot retrive
3650 the result from the PyCArgObject.
3652 if (ob == NULL)
3653 goto error;
3654 /* The .from_param call that will ocurr later will pass this
3655 as a byref parameter. */
3656 PyTuple_SET_ITEM(callargs, i, ob);
3657 *poutmask |= (1 << i); /* mark as out arg */
3658 (*pnumretvals)++;
3659 break;
3660 default:
3661 PyErr_Format(PyExc_ValueError,
3662 "paramflag %d not yet implemented", flag);
3663 goto error;
3664 break;
3668 /* We have counted the arguments we have consumed in 'inargs_index'. This
3669 must be the same as len(inargs) + len(kwds), otherwise we have
3670 either too much or not enough arguments. */
3672 actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
3673 if (actual_args != inargs_index) {
3674 /* When we have default values or named parameters, this error
3675 message is misleading. See unittests/test_paramflags.py
3677 PyErr_Format(PyExc_TypeError,
3678 #if (PY_VERSION_HEX < 0x02050000)
3679 "call takes exactly %d arguments (%d given)",
3680 #else
3681 "call takes exactly %d arguments (%zd given)",
3682 #endif
3683 inargs_index, actual_args);
3684 goto error;
3687 /* outmask is a bitmask containing indexes into callargs. Items at
3688 these indexes contain values to return.
3690 return callargs;
3691 error:
3692 Py_DECREF(callargs);
3693 return NULL;
3696 /* See also:
3697 http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
3700 Build return value of a function.
3702 Consumes the refcount on result and callargs.
3704 static PyObject *
3705 _build_result(PyObject *result, PyObject *callargs,
3706 int outmask, int inoutmask, unsigned int numretvals)
3708 unsigned int i, index;
3709 int bit;
3710 PyObject *tup = NULL;
3712 if (callargs == NULL)
3713 return result;
3714 if (result == NULL || numretvals == 0) {
3715 Py_DECREF(callargs);
3716 return result;
3718 Py_DECREF(result);
3720 /* tup will not be allocated if numretvals == 1 */
3721 /* allocate tuple to hold the result */
3722 if (numretvals > 1) {
3723 tup = PyTuple_New(numretvals);
3724 if (tup == NULL) {
3725 Py_DECREF(callargs);
3726 return NULL;
3730 index = 0;
3731 for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
3732 PyObject *v;
3733 if (bit & inoutmask) {
3734 v = PyTuple_GET_ITEM(callargs, i);
3735 Py_INCREF(v);
3736 if (numretvals == 1) {
3737 Py_DECREF(callargs);
3738 return v;
3740 PyTuple_SET_ITEM(tup, index, v);
3741 index++;
3742 } else if (bit & outmask) {
3743 v = PyTuple_GET_ITEM(callargs, i);
3744 v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
3745 if (v == NULL || numretvals == 1) {
3746 Py_DECREF(callargs);
3747 return v;
3749 PyTuple_SET_ITEM(tup, index, v);
3750 index++;
3752 if (index == numretvals)
3753 break;
3756 Py_DECREF(callargs);
3757 return tup;
3760 static PyObject *
3761 CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
3763 PyObject *restype;
3764 PyObject *converters;
3765 PyObject *checker;
3766 PyObject *argtypes;
3767 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3768 PyObject *result;
3769 PyObject *callargs;
3770 PyObject *errcheck;
3771 #ifdef MS_WIN32
3772 IUnknown *piunk = NULL;
3773 #endif
3774 void *pProc = NULL;
3776 int inoutmask;
3777 int outmask;
3778 unsigned int numretvals;
3780 assert(dict); /* Cannot be NULL for CFuncPtrObject instances */
3781 restype = self->restype ? self->restype : dict->restype;
3782 converters = self->converters ? self->converters : dict->converters;
3783 checker = self->checker ? self->checker : dict->checker;
3784 argtypes = self->argtypes ? self->argtypes : dict->argtypes;
3785 /* later, we probably want to have an errcheck field in stgdict */
3786 errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
3789 pProc = *(void **)self->b_ptr;
3790 #ifdef MS_WIN32
3791 if (self->index) {
3792 /* It's a COM method */
3793 CDataObject *this;
3794 this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
3795 if (!this) {
3796 PyErr_SetString(PyExc_ValueError,
3797 "native com method call without 'this' parameter");
3798 return NULL;
3800 if (!CDataObject_Check(this)) {
3801 PyErr_SetString(PyExc_TypeError,
3802 "Expected a COM this pointer as first argument");
3803 return NULL;
3805 /* there should be more checks? No, in Python */
3806 /* First arg is an pointer to an interface instance */
3807 if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
3808 PyErr_SetString(PyExc_ValueError,
3809 "NULL COM pointer access");
3810 return NULL;
3812 piunk = *(IUnknown **)this->b_ptr;
3813 if (NULL == piunk->lpVtbl) {
3814 PyErr_SetString(PyExc_ValueError,
3815 "COM method call without VTable");
3816 return NULL;
3818 pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
3820 #endif
3821 callargs = _build_callargs(self, argtypes,
3822 inargs, kwds,
3823 &outmask, &inoutmask, &numretvals);
3824 if (callargs == NULL)
3825 return NULL;
3827 if (converters) {
3828 int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
3829 Py_ssize_t, int);
3830 int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
3831 Py_ssize_t, int);
3833 if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
3834 /* For cdecl functions, we allow more actual arguments
3835 than the length of the argtypes tuple.
3837 if (required > actual) {
3838 Py_DECREF(callargs);
3839 PyErr_Format(PyExc_TypeError,
3840 "this function takes at least %d argument%s (%d given)",
3841 required,
3842 required == 1 ? "" : "s",
3843 actual);
3844 return NULL;
3846 } else if (required != actual) {
3847 Py_DECREF(callargs);
3848 PyErr_Format(PyExc_TypeError,
3849 "this function takes %d argument%s (%d given)",
3850 required,
3851 required == 1 ? "" : "s",
3852 actual);
3853 return NULL;
3857 result = _CallProc(pProc,
3858 callargs,
3859 #ifdef MS_WIN32
3860 piunk,
3861 self->iid,
3862 #endif
3863 dict->flags,
3864 converters,
3865 restype,
3866 checker);
3867 /* The 'errcheck' protocol */
3868 if (result != NULL && errcheck) {
3869 PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
3870 result,
3871 self,
3872 callargs,
3873 NULL);
3874 /* If the errcheck funtion failed, return NULL.
3875 If the errcheck function returned callargs unchanged,
3876 continue normal processing.
3877 If the errcheck function returned something else,
3878 use that as result.
3880 if (v == NULL || v != callargs) {
3881 Py_DECREF(result);
3882 Py_DECREF(callargs);
3883 return v;
3885 Py_DECREF(v);
3888 return _build_result(result, callargs,
3889 outmask, inoutmask, numretvals);
3892 static int
3893 CFuncPtr_traverse(CFuncPtrObject *self, visitproc visit, void *arg)
3895 Py_VISIT(self->callable);
3896 Py_VISIT(self->restype);
3897 Py_VISIT(self->checker);
3898 Py_VISIT(self->errcheck);
3899 Py_VISIT(self->argtypes);
3900 Py_VISIT(self->converters);
3901 Py_VISIT(self->paramflags);
3902 Py_VISIT(self->thunk);
3903 return CData_traverse((CDataObject *)self, visit, arg);
3906 static int
3907 CFuncPtr_clear(CFuncPtrObject *self)
3909 Py_CLEAR(self->callable);
3910 Py_CLEAR(self->restype);
3911 Py_CLEAR(self->checker);
3912 Py_CLEAR(self->errcheck);
3913 Py_CLEAR(self->argtypes);
3914 Py_CLEAR(self->converters);
3915 Py_CLEAR(self->paramflags);
3916 Py_CLEAR(self->thunk);
3917 return CData_clear((CDataObject *)self);
3920 static void
3921 CFuncPtr_dealloc(CFuncPtrObject *self)
3923 CFuncPtr_clear(self);
3924 Py_TYPE(self)->tp_free((PyObject *)self);
3927 static PyObject *
3928 CFuncPtr_repr(CFuncPtrObject *self)
3930 #ifdef MS_WIN32
3931 if (self->index)
3932 return PyString_FromFormat("<COM method offset %d: %s at %p>",
3933 self->index - 0x1000,
3934 Py_TYPE(self)->tp_name,
3935 self);
3936 #endif
3937 return PyString_FromFormat("<%s object at %p>",
3938 Py_TYPE(self)->tp_name,
3939 self);
3942 static int
3943 CFuncPtr_nonzero(CFuncPtrObject *self)
3945 return ((*(void **)self->b_ptr != NULL)
3946 #ifdef MS_WIN32
3947 || (self->index != 0)
3948 #endif
3952 static PyNumberMethods CFuncPtr_as_number = {
3953 0, /* nb_add */
3954 0, /* nb_subtract */
3955 0, /* nb_multiply */
3956 0, /* nb_divide */
3957 0, /* nb_remainder */
3958 0, /* nb_divmod */
3959 0, /* nb_power */
3960 0, /* nb_negative */
3961 0, /* nb_positive */
3962 0, /* nb_absolute */
3963 (inquiry)CFuncPtr_nonzero, /* nb_nonzero */
3966 PyTypeObject CFuncPtr_Type = {
3967 PyVarObject_HEAD_INIT(NULL, 0)
3968 "_ctypes.CFuncPtr",
3969 sizeof(CFuncPtrObject), /* tp_basicsize */
3970 0, /* tp_itemsize */
3971 (destructor)CFuncPtr_dealloc, /* tp_dealloc */
3972 0, /* tp_print */
3973 0, /* tp_getattr */
3974 0, /* tp_setattr */
3975 0, /* tp_compare */
3976 (reprfunc)CFuncPtr_repr, /* tp_repr */
3977 &CFuncPtr_as_number, /* tp_as_number */
3978 0, /* tp_as_sequence */
3979 0, /* tp_as_mapping */
3980 0, /* tp_hash */
3981 (ternaryfunc)CFuncPtr_call, /* tp_call */
3982 0, /* tp_str */
3983 0, /* tp_getattro */
3984 0, /* tp_setattro */
3985 &CData_as_buffer, /* tp_as_buffer */
3986 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
3987 "Function Pointer", /* tp_doc */
3988 (traverseproc)CFuncPtr_traverse, /* tp_traverse */
3989 (inquiry)CFuncPtr_clear, /* tp_clear */
3990 0, /* tp_richcompare */
3991 0, /* tp_weaklistoffset */
3992 0, /* tp_iter */
3993 0, /* tp_iternext */
3994 0, /* tp_methods */
3995 0, /* tp_members */
3996 CFuncPtr_getsets, /* tp_getset */
3997 0, /* tp_base */
3998 0, /* tp_dict */
3999 0, /* tp_descr_get */
4000 0, /* tp_descr_set */
4001 0, /* tp_dictoffset */
4002 0, /* tp_init */
4003 0, /* tp_alloc */
4004 CFuncPtr_new, /* tp_new */
4005 0, /* tp_free */
4008 /*****************************************************************/
4010 Struct_Type
4012 static int
4013 IBUG(char *msg)
4015 PyErr_Format(PyExc_RuntimeError,
4016 "inconsistent state in CDataObject (%s)", msg);
4017 return -1;
4020 static int
4021 Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
4023 int i;
4024 PyObject *fields;
4026 /* Optimization possible: Store the attribute names _fields_[x][0]
4027 * in C accessible fields somewhere ?
4030 /* Check this code again for correctness! */
4032 if (!PyTuple_Check(args)) {
4033 PyErr_SetString(PyExc_TypeError,
4034 "args not a tuple?");
4035 return -1;
4037 if (PyTuple_GET_SIZE(args)) {
4038 fields = PyObject_GetAttrString(self, "_fields_");
4039 if (!fields) {
4040 PyErr_Clear();
4041 fields = PyTuple_New(0);
4042 if (!fields)
4043 return -1;
4046 if (PyTuple_GET_SIZE(args) > PySequence_Length(fields)) {
4047 Py_DECREF(fields);
4048 PyErr_SetString(PyExc_TypeError,
4049 "too many initializers");
4050 return -1;
4053 for (i = 0; i < PyTuple_GET_SIZE(args); ++i) {
4054 PyObject *pair = PySequence_GetItem(fields, i);
4055 PyObject *name;
4056 PyObject *val;
4057 if (!pair) {
4058 Py_DECREF(fields);
4059 return IBUG("_fields_[i] failed");
4062 name = PySequence_GetItem(pair, 0);
4063 if (!name) {
4064 Py_DECREF(pair);
4065 Py_DECREF(fields);
4066 return IBUG("_fields_[i][0] failed");
4069 if (kwds && PyDict_GetItem(kwds, name)) {
4070 char *field = PyString_AsString(name);
4071 if (field == NULL) {
4072 PyErr_Clear();
4073 field = "???";
4075 PyErr_Format(PyExc_TypeError,
4076 "duplicate values for field %s",
4077 field);
4078 Py_DECREF(pair);
4079 Py_DECREF(name);
4080 Py_DECREF(fields);
4081 return -1;
4084 val = PyTuple_GET_ITEM(args, i);
4085 if (-1 == PyObject_SetAttr(self, name, val)) {
4086 Py_DECREF(pair);
4087 Py_DECREF(name);
4088 Py_DECREF(fields);
4089 return -1;
4092 Py_DECREF(name);
4093 Py_DECREF(pair);
4095 Py_DECREF(fields);
4098 if (kwds) {
4099 PyObject *key, *value;
4100 Py_ssize_t pos = 0;
4101 while(PyDict_Next(kwds, &pos, &key, &value)) {
4102 if (-1 == PyObject_SetAttr(self, key, value))
4103 return -1;
4106 return 0;
4109 static PyTypeObject Struct_Type = {
4110 PyVarObject_HEAD_INIT(NULL, 0)
4111 "_ctypes.Structure",
4112 sizeof(CDataObject), /* tp_basicsize */
4113 0, /* tp_itemsize */
4114 0, /* tp_dealloc */
4115 0, /* tp_print */
4116 0, /* tp_getattr */
4117 0, /* tp_setattr */
4118 0, /* tp_compare */
4119 0, /* tp_repr */
4120 0, /* tp_as_number */
4121 0, /* tp_as_sequence */
4122 0, /* tp_as_mapping */
4123 0, /* tp_hash */
4124 0, /* tp_call */
4125 0, /* tp_str */
4126 0, /* tp_getattro */
4127 0, /* tp_setattro */
4128 &CData_as_buffer, /* tp_as_buffer */
4129 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4130 "Structure base class", /* tp_doc */
4131 (traverseproc)CData_traverse, /* tp_traverse */
4132 (inquiry)CData_clear, /* tp_clear */
4133 0, /* tp_richcompare */
4134 0, /* tp_weaklistoffset */
4135 0, /* tp_iter */
4136 0, /* tp_iternext */
4137 0, /* tp_methods */
4138 0, /* tp_members */
4139 0, /* tp_getset */
4140 0, /* tp_base */
4141 0, /* tp_dict */
4142 0, /* tp_descr_get */
4143 0, /* tp_descr_set */
4144 0, /* tp_dictoffset */
4145 Struct_init, /* tp_init */
4146 0, /* tp_alloc */
4147 GenericCData_new, /* tp_new */
4148 0, /* tp_free */
4151 static PyTypeObject Union_Type = {
4152 PyVarObject_HEAD_INIT(NULL, 0)
4153 "_ctypes.Union",
4154 sizeof(CDataObject), /* tp_basicsize */
4155 0, /* tp_itemsize */
4156 0, /* tp_dealloc */
4157 0, /* tp_print */
4158 0, /* tp_getattr */
4159 0, /* tp_setattr */
4160 0, /* tp_compare */
4161 0, /* tp_repr */
4162 0, /* tp_as_number */
4163 0, /* tp_as_sequence */
4164 0, /* tp_as_mapping */
4165 0, /* tp_hash */
4166 0, /* tp_call */
4167 0, /* tp_str */
4168 0, /* tp_getattro */
4169 0, /* tp_setattro */
4170 &CData_as_buffer, /* tp_as_buffer */
4171 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4172 "Union base class", /* tp_doc */
4173 (traverseproc)CData_traverse, /* tp_traverse */
4174 (inquiry)CData_clear, /* tp_clear */
4175 0, /* tp_richcompare */
4176 0, /* tp_weaklistoffset */
4177 0, /* tp_iter */
4178 0, /* tp_iternext */
4179 0, /* tp_methods */
4180 0, /* tp_members */
4181 0, /* tp_getset */
4182 0, /* tp_base */
4183 0, /* tp_dict */
4184 0, /* tp_descr_get */
4185 0, /* tp_descr_set */
4186 0, /* tp_dictoffset */
4187 Struct_init, /* tp_init */
4188 0, /* tp_alloc */
4189 GenericCData_new, /* tp_new */
4190 0, /* tp_free */
4194 /******************************************************************/
4196 Array_Type
4198 static int
4199 Array_init(CDataObject *self, PyObject *args, PyObject *kw)
4201 Py_ssize_t i;
4202 Py_ssize_t n;
4204 if (!PyTuple_Check(args)) {
4205 PyErr_SetString(PyExc_TypeError,
4206 "args not a tuple?");
4207 return -1;
4209 n = PyTuple_GET_SIZE(args);
4210 for (i = 0; i < n; ++i) {
4211 PyObject *v;
4212 v = PyTuple_GET_ITEM(args, i);
4213 if (-1 == PySequence_SetItem((PyObject *)self, i, v))
4214 return -1;
4216 return 0;
4219 static PyObject *
4220 Array_item(PyObject *_self, Py_ssize_t index)
4222 CDataObject *self = (CDataObject *)_self;
4223 Py_ssize_t offset, size;
4224 StgDictObject *stgdict;
4227 if (index < 0 || index >= self->b_length) {
4228 PyErr_SetString(PyExc_IndexError,
4229 "invalid index");
4230 return NULL;
4233 stgdict = PyObject_stgdict((PyObject *)self);
4234 assert(stgdict); /* Cannot be NULL for array instances */
4235 /* Would it be clearer if we got the item size from
4236 stgdict->proto's stgdict?
4238 size = stgdict->size / stgdict->length;
4239 offset = index * size;
4241 return CData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
4242 index, size, self->b_ptr + offset);
4245 static PyObject *
4246 Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
4248 CDataObject *self = (CDataObject *)_self;
4249 StgDictObject *stgdict, *itemdict;
4250 PyObject *proto;
4251 PyListObject *np;
4252 Py_ssize_t i, len;
4254 if (ilow < 0)
4255 ilow = 0;
4256 else if (ilow > self->b_length)
4257 ilow = self->b_length;
4258 if (ihigh < ilow)
4259 ihigh = ilow;
4260 else if (ihigh > self->b_length)
4261 ihigh = self->b_length;
4262 len = ihigh - ilow;
4264 stgdict = PyObject_stgdict((PyObject *)self);
4265 assert(stgdict); /* Cannot be NULL for array object instances */
4266 proto = stgdict->proto;
4267 itemdict = PyType_stgdict(proto);
4268 assert(itemdict); /* proto is the item type of the array, a ctypes
4269 type, so this cannot be NULL */
4270 if (itemdict->getfunc == getentry("c")->getfunc) {
4271 char *ptr = (char *)self->b_ptr;
4272 return PyString_FromStringAndSize(ptr + ilow, len);
4273 #ifdef CTYPES_UNICODE
4274 } else if (itemdict->getfunc == getentry("u")->getfunc) {
4275 wchar_t *ptr = (wchar_t *)self->b_ptr;
4276 return PyUnicode_FromWideChar(ptr + ilow, len);
4277 #endif
4280 np = (PyListObject *) PyList_New(len);
4281 if (np == NULL)
4282 return NULL;
4284 for (i = 0; i < len; i++) {
4285 PyObject *v = Array_item(_self, i+ilow);
4286 PyList_SET_ITEM(np, i, v);
4288 return (PyObject *)np;
4291 static PyObject *
4292 Array_subscript(PyObject *_self, PyObject *item)
4294 CDataObject *self = (CDataObject *)_self;
4296 if (PyIndex_Check(item)) {
4297 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4299 if (i == -1 && PyErr_Occurred())
4300 return NULL;
4301 if (i < 0)
4302 i += self->b_length;
4303 return Array_item(_self, i);
4305 else if PySlice_Check(item) {
4306 StgDictObject *stgdict, *itemdict;
4307 PyObject *proto;
4308 PyObject *np;
4309 Py_ssize_t start, stop, step, slicelen, cur, i;
4311 if (PySlice_GetIndicesEx((PySliceObject *)item,
4312 self->b_length, &start, &stop,
4313 &step, &slicelen) < 0) {
4314 return NULL;
4317 stgdict = PyObject_stgdict((PyObject *)self);
4318 assert(stgdict); /* Cannot be NULL for array object instances */
4319 proto = stgdict->proto;
4320 itemdict = PyType_stgdict(proto);
4321 assert(itemdict); /* proto is the item type of the array, a
4322 ctypes type, so this cannot be NULL */
4324 if (itemdict->getfunc == getentry("c")->getfunc) {
4325 char *ptr = (char *)self->b_ptr;
4326 char *dest;
4328 if (slicelen <= 0)
4329 return PyString_FromString("");
4330 if (step == 1) {
4331 return PyString_FromStringAndSize(ptr + start,
4332 slicelen);
4334 dest = (char *)PyMem_Malloc(slicelen);
4336 if (dest == NULL)
4337 return PyErr_NoMemory();
4339 for (cur = start, i = 0; i < slicelen;
4340 cur += step, i++) {
4341 dest[i] = ptr[cur];
4344 np = PyString_FromStringAndSize(dest, slicelen);
4345 PyMem_Free(dest);
4346 return np;
4348 #ifdef CTYPES_UNICODE
4349 if (itemdict->getfunc == getentry("u")->getfunc) {
4350 wchar_t *ptr = (wchar_t *)self->b_ptr;
4351 wchar_t *dest;
4353 if (slicelen <= 0)
4354 return PyUnicode_FromUnicode(NULL, 0);
4355 if (step == 1) {
4356 return PyUnicode_FromWideChar(ptr + start,
4357 slicelen);
4360 dest = (wchar_t *)PyMem_Malloc(
4361 slicelen * sizeof(wchar_t));
4363 for (cur = start, i = 0; i < slicelen;
4364 cur += step, i++) {
4365 dest[i] = ptr[cur];
4368 np = PyUnicode_FromWideChar(dest, slicelen);
4369 PyMem_Free(dest);
4370 return np;
4372 #endif
4374 np = PyList_New(slicelen);
4375 if (np == NULL)
4376 return NULL;
4378 for (cur = start, i = 0; i < slicelen;
4379 cur += step, i++) {
4380 PyObject *v = Array_item(_self, cur);
4381 PyList_SET_ITEM(np, i, v);
4383 return np;
4385 else {
4386 PyErr_SetString(PyExc_TypeError,
4387 "indices must be integers");
4388 return NULL;
4393 static int
4394 Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4396 CDataObject *self = (CDataObject *)_self;
4397 Py_ssize_t size, offset;
4398 StgDictObject *stgdict;
4399 char *ptr;
4401 if (value == NULL) {
4402 PyErr_SetString(PyExc_TypeError,
4403 "Array does not support item deletion");
4404 return -1;
4407 stgdict = PyObject_stgdict((PyObject *)self);
4408 assert(stgdict); /* Cannot be NULL for array object instances */
4409 if (index < 0 || index >= stgdict->length) {
4410 PyErr_SetString(PyExc_IndexError,
4411 "invalid index");
4412 return -1;
4414 size = stgdict->size / stgdict->length;
4415 offset = index * size;
4416 ptr = self->b_ptr + offset;
4418 return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
4419 index, size, ptr);
4422 static int
4423 Array_ass_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *value)
4425 CDataObject *self = (CDataObject *)_self;
4426 Py_ssize_t i, len;
4428 if (value == NULL) {
4429 PyErr_SetString(PyExc_TypeError,
4430 "Array does not support item deletion");
4431 return -1;
4434 if (ilow < 0)
4435 ilow = 0;
4436 else if (ilow > self->b_length)
4437 ilow = self->b_length;
4438 if (ihigh < 0)
4439 ihigh = 0;
4440 if (ihigh < ilow)
4441 ihigh = ilow;
4442 else if (ihigh > self->b_length)
4443 ihigh = self->b_length;
4445 len = PySequence_Length(value);
4446 if (len != ihigh - ilow) {
4447 PyErr_SetString(PyExc_ValueError,
4448 "Can only assign sequence of same size");
4449 return -1;
4451 for (i = 0; i < len; i++) {
4452 PyObject *item = PySequence_GetItem(value, i);
4453 int result;
4454 if (item == NULL)
4455 return -1;
4456 result = Array_ass_item(_self, i+ilow, item);
4457 Py_DECREF(item);
4458 if (result == -1)
4459 return -1;
4461 return 0;
4464 static int
4465 Array_ass_subscript(PyObject *_self, PyObject *item, PyObject *value)
4467 CDataObject *self = (CDataObject *)_self;
4469 if (value == NULL) {
4470 PyErr_SetString(PyExc_TypeError,
4471 "Array does not support item deletion");
4472 return -1;
4475 if (PyIndex_Check(item)) {
4476 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4478 if (i == -1 && PyErr_Occurred())
4479 return -1;
4480 if (i < 0)
4481 i += self->b_length;
4482 return Array_ass_item(_self, i, value);
4484 else if (PySlice_Check(item)) {
4485 Py_ssize_t start, stop, step, slicelen, otherlen, i, cur;
4487 if (PySlice_GetIndicesEx((PySliceObject *)item,
4488 self->b_length, &start, &stop,
4489 &step, &slicelen) < 0) {
4490 return -1;
4492 if ((step < 0 && start < stop) ||
4493 (step > 0 && start > stop))
4494 stop = start;
4496 otherlen = PySequence_Length(value);
4497 if (otherlen != slicelen) {
4498 PyErr_SetString(PyExc_ValueError,
4499 "Can only assign sequence of same size");
4500 return -1;
4502 for (cur = start, i = 0; i < otherlen; cur += step, i++) {
4503 PyObject *item = PySequence_GetItem(value, i);
4504 int result;
4505 if (item == NULL)
4506 return -1;
4507 result = Array_ass_item(_self, cur, item);
4508 Py_DECREF(item);
4509 if (result == -1)
4510 return -1;
4512 return 0;
4514 else {
4515 PyErr_SetString(PyExc_TypeError,
4516 "indices must be integer");
4517 return -1;
4521 static Py_ssize_t
4522 Array_length(PyObject *_self)
4524 CDataObject *self = (CDataObject *)_self;
4525 return self->b_length;
4528 static PySequenceMethods Array_as_sequence = {
4529 Array_length, /* sq_length; */
4530 0, /* sq_concat; */
4531 0, /* sq_repeat; */
4532 Array_item, /* sq_item; */
4533 Array_slice, /* sq_slice; */
4534 Array_ass_item, /* sq_ass_item; */
4535 Array_ass_slice, /* sq_ass_slice; */
4536 0, /* sq_contains; */
4538 0, /* sq_inplace_concat; */
4539 0, /* sq_inplace_repeat; */
4542 static PyMappingMethods Array_as_mapping = {
4543 Array_length,
4544 Array_subscript,
4545 Array_ass_subscript,
4548 PyTypeObject Array_Type = {
4549 PyVarObject_HEAD_INIT(NULL, 0)
4550 "_ctypes.Array",
4551 sizeof(CDataObject), /* tp_basicsize */
4552 0, /* tp_itemsize */
4553 0, /* tp_dealloc */
4554 0, /* tp_print */
4555 0, /* tp_getattr */
4556 0, /* tp_setattr */
4557 0, /* tp_compare */
4558 0, /* tp_repr */
4559 0, /* tp_as_number */
4560 &Array_as_sequence, /* tp_as_sequence */
4561 &Array_as_mapping, /* tp_as_mapping */
4562 0, /* tp_hash */
4563 0, /* tp_call */
4564 0, /* tp_str */
4565 0, /* tp_getattro */
4566 0, /* tp_setattro */
4567 &CData_as_buffer, /* tp_as_buffer */
4568 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4569 "XXX to be provided", /* tp_doc */
4570 (traverseproc)CData_traverse, /* tp_traverse */
4571 (inquiry)CData_clear, /* tp_clear */
4572 0, /* tp_richcompare */
4573 0, /* tp_weaklistoffset */
4574 0, /* tp_iter */
4575 0, /* tp_iternext */
4576 0, /* tp_methods */
4577 0, /* tp_members */
4578 0, /* tp_getset */
4579 0, /* tp_base */
4580 0, /* tp_dict */
4581 0, /* tp_descr_get */
4582 0, /* tp_descr_set */
4583 0, /* tp_dictoffset */
4584 (initproc)Array_init, /* tp_init */
4585 0, /* tp_alloc */
4586 GenericCData_new, /* tp_new */
4587 0, /* tp_free */
4590 PyObject *
4591 CreateArrayType(PyObject *itemtype, Py_ssize_t length)
4593 static PyObject *cache;
4594 PyObject *key;
4595 PyObject *result;
4596 char name[256];
4597 PyObject *len;
4599 if (cache == NULL) {
4600 cache = PyDict_New();
4601 if (cache == NULL)
4602 return NULL;
4604 len = PyInt_FromSsize_t(length);
4605 if (len == NULL)
4606 return NULL;
4607 key = PyTuple_Pack(2, itemtype, len);
4608 Py_DECREF(len);
4609 if (!key)
4610 return NULL;
4611 result = PyDict_GetItemProxy(cache, key);
4612 if (result) {
4613 Py_INCREF(result);
4614 Py_DECREF(key);
4615 return result;
4618 if (!PyType_Check(itemtype)) {
4619 PyErr_SetString(PyExc_TypeError,
4620 "Expected a type object");
4621 return NULL;
4623 #ifdef MS_WIN64
4624 sprintf(name, "%.200s_Array_%Id",
4625 ((PyTypeObject *)itemtype)->tp_name, length);
4626 #else
4627 sprintf(name, "%.200s_Array_%ld",
4628 ((PyTypeObject *)itemtype)->tp_name, (long)length);
4629 #endif
4631 result = PyObject_CallFunction((PyObject *)&ArrayType_Type,
4632 #if (PY_VERSION_HEX < 0x02050000)
4633 "s(O){s:i,s:O}",
4634 #else
4635 "s(O){s:n,s:O}",
4636 #endif
4637 name,
4638 &Array_Type,
4639 "_length_",
4640 length,
4641 "_type_",
4642 itemtype
4644 if (result == NULL) {
4645 Py_DECREF(key);
4646 return NULL;
4648 if (-1 == PyDict_SetItemProxy(cache, key, result)) {
4649 Py_DECREF(key);
4650 Py_DECREF(result);
4651 return NULL;
4653 Py_DECREF(key);
4654 return result;
4658 /******************************************************************/
4660 Simple_Type
4663 static int
4664 Simple_set_value(CDataObject *self, PyObject *value)
4666 PyObject *result;
4667 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
4669 if (value == NULL) {
4670 PyErr_SetString(PyExc_TypeError,
4671 "can't delete attribute");
4672 return -1;
4674 assert(dict); /* Cannot be NULL for CDataObject instances */
4675 assert(dict->setfunc);
4676 result = dict->setfunc(self->b_ptr, value, dict->size);
4677 if (!result)
4678 return -1;
4680 /* consumes the refcount the setfunc returns */
4681 return KeepRef(self, 0, result);
4684 static int
4685 Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
4687 PyObject *value = NULL;
4688 if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
4689 return -1;
4690 if (value)
4691 return Simple_set_value(self, value);
4692 return 0;
4695 static PyObject *
4696 Simple_get_value(CDataObject *self)
4698 StgDictObject *dict;
4699 dict = PyObject_stgdict((PyObject *)self);
4700 assert(dict); /* Cannot be NULL for CDataObject instances */
4701 assert(dict->getfunc);
4702 return dict->getfunc(self->b_ptr, self->b_size);
4705 static PyGetSetDef Simple_getsets[] = {
4706 { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4707 "current value", NULL },
4708 { NULL, NULL }
4711 static PyObject *
4712 Simple_from_outparm(PyObject *self, PyObject *args)
4714 if (IsSimpleSubType((PyObject *)Py_TYPE(self))) {
4715 Py_INCREF(self);
4716 return self;
4718 /* call stgdict->getfunc */
4719 return Simple_get_value((CDataObject *)self);
4722 static PyMethodDef Simple_methods[] = {
4723 { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
4724 { NULL, NULL },
4727 static int Simple_nonzero(CDataObject *self)
4729 return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
4732 static PyNumberMethods Simple_as_number = {
4733 0, /* nb_add */
4734 0, /* nb_subtract */
4735 0, /* nb_multiply */
4736 0, /* nb_divide */
4737 0, /* nb_remainder */
4738 0, /* nb_divmod */
4739 0, /* nb_power */
4740 0, /* nb_negative */
4741 0, /* nb_positive */
4742 0, /* nb_absolute */
4743 (inquiry)Simple_nonzero, /* nb_nonzero */
4746 /* "%s(%s)" % (self.__class__.__name__, self.value) */
4747 static PyObject *
4748 Simple_repr(CDataObject *self)
4750 PyObject *val, *name, *args, *result;
4751 static PyObject *format;
4753 if (Py_TYPE(self)->tp_base != &Simple_Type) {
4754 return PyString_FromFormat("<%s object at %p>",
4755 Py_TYPE(self)->tp_name, self);
4758 if (format == NULL) {
4759 format = PyString_InternFromString("%s(%r)");
4760 if (format == NULL)
4761 return NULL;
4764 val = Simple_get_value(self);
4765 if (val == NULL)
4766 return NULL;
4768 name = PyString_FromString(Py_TYPE(self)->tp_name);
4769 if (name == NULL) {
4770 Py_DECREF(val);
4771 return NULL;
4774 args = PyTuple_Pack(2, name, val);
4775 Py_DECREF(name);
4776 Py_DECREF(val);
4777 if (args == NULL)
4778 return NULL;
4780 result = PyString_Format(format, args);
4781 Py_DECREF(args);
4782 return result;
4785 static PyTypeObject Simple_Type = {
4786 PyVarObject_HEAD_INIT(NULL, 0)
4787 "_ctypes._SimpleCData",
4788 sizeof(CDataObject), /* tp_basicsize */
4789 0, /* tp_itemsize */
4790 0, /* tp_dealloc */
4791 0, /* tp_print */
4792 0, /* tp_getattr */
4793 0, /* tp_setattr */
4794 0, /* tp_compare */
4795 (reprfunc)&Simple_repr, /* tp_repr */
4796 &Simple_as_number, /* tp_as_number */
4797 0, /* tp_as_sequence */
4798 0, /* tp_as_mapping */
4799 0, /* tp_hash */
4800 0, /* tp_call */
4801 0, /* tp_str */
4802 0, /* tp_getattro */
4803 0, /* tp_setattro */
4804 &CData_as_buffer, /* tp_as_buffer */
4805 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4806 "XXX to be provided", /* tp_doc */
4807 (traverseproc)CData_traverse, /* tp_traverse */
4808 (inquiry)CData_clear, /* tp_clear */
4809 0, /* tp_richcompare */
4810 0, /* tp_weaklistoffset */
4811 0, /* tp_iter */
4812 0, /* tp_iternext */
4813 Simple_methods, /* tp_methods */
4814 0, /* tp_members */
4815 Simple_getsets, /* tp_getset */
4816 0, /* tp_base */
4817 0, /* tp_dict */
4818 0, /* tp_descr_get */
4819 0, /* tp_descr_set */
4820 0, /* tp_dictoffset */
4821 (initproc)Simple_init, /* tp_init */
4822 0, /* tp_alloc */
4823 GenericCData_new, /* tp_new */
4824 0, /* tp_free */
4827 /******************************************************************/
4829 Pointer_Type
4831 static PyObject *
4832 Pointer_item(PyObject *_self, Py_ssize_t index)
4834 CDataObject *self = (CDataObject *)_self;
4835 Py_ssize_t size;
4836 Py_ssize_t offset;
4837 StgDictObject *stgdict, *itemdict;
4838 PyObject *proto;
4840 if (*(void **)self->b_ptr == NULL) {
4841 PyErr_SetString(PyExc_ValueError,
4842 "NULL pointer access");
4843 return NULL;
4846 stgdict = PyObject_stgdict((PyObject *)self);
4847 assert(stgdict); /* Cannot be NULL for pointer object instances */
4849 proto = stgdict->proto;
4850 assert(proto);
4851 itemdict = PyType_stgdict(proto);
4852 assert(itemdict); /* proto is the item type of the pointer, a ctypes
4853 type, so this cannot be NULL */
4855 size = itemdict->size;
4856 offset = index * itemdict->size;
4858 return CData_get(proto, stgdict->getfunc, (PyObject *)self,
4859 index, size, (*(char **)self->b_ptr) + offset);
4862 static int
4863 Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4865 CDataObject *self = (CDataObject *)_self;
4866 Py_ssize_t size;
4867 Py_ssize_t offset;
4868 StgDictObject *stgdict, *itemdict;
4869 PyObject *proto;
4871 if (value == NULL) {
4872 PyErr_SetString(PyExc_TypeError,
4873 "Pointer does not support item deletion");
4874 return -1;
4877 if (*(void **)self->b_ptr == NULL) {
4878 PyErr_SetString(PyExc_ValueError,
4879 "NULL pointer access");
4880 return -1;
4883 stgdict = PyObject_stgdict((PyObject *)self);
4884 assert(stgdict); /* Cannot be NULL fr pointer instances */
4886 proto = stgdict->proto;
4887 assert(proto);
4889 itemdict = PyType_stgdict(proto);
4890 assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
4891 is always a ctypes type */
4893 size = itemdict->size;
4894 offset = index * itemdict->size;
4896 return CData_set((PyObject *)self, proto, stgdict->setfunc, value,
4897 index, size, (*(char **)self->b_ptr) + offset);
4900 static PyObject *
4901 Pointer_get_contents(CDataObject *self, void *closure)
4903 StgDictObject *stgdict;
4905 if (*(void **)self->b_ptr == NULL) {
4906 PyErr_SetString(PyExc_ValueError,
4907 "NULL pointer access");
4908 return NULL;
4911 stgdict = PyObject_stgdict((PyObject *)self);
4912 assert(stgdict); /* Cannot be NULL fr pointer instances */
4913 return CData_FromBaseObj(stgdict->proto,
4914 (PyObject *)self, 0,
4915 *(void **)self->b_ptr);
4918 static int
4919 Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
4921 StgDictObject *stgdict;
4922 CDataObject *dst;
4923 PyObject *keep;
4925 if (value == NULL) {
4926 PyErr_SetString(PyExc_TypeError,
4927 "Pointer does not support item deletion");
4928 return -1;
4930 stgdict = PyObject_stgdict((PyObject *)self);
4931 assert(stgdict); /* Cannot be NULL fr pointer instances */
4932 assert(stgdict->proto);
4933 if (!CDataObject_Check(value)
4934 || 0 == PyObject_IsInstance(value, stgdict->proto)) {
4935 /* XXX PyObject_IsInstance could return -1! */
4936 PyErr_Format(PyExc_TypeError,
4937 "expected %s instead of %s",
4938 ((PyTypeObject *)(stgdict->proto))->tp_name,
4939 Py_TYPE(value)->tp_name);
4940 return -1;
4943 dst = (CDataObject *)value;
4944 *(void **)self->b_ptr = dst->b_ptr;
4947 A Pointer instance must keep a the value it points to alive. So, a
4948 pointer instance has b_length set to 2 instead of 1, and we set
4949 'value' itself as the second item of the b_objects list, additionally.
4951 Py_INCREF(value);
4952 if (-1 == KeepRef(self, 1, value))
4953 return -1;
4955 keep = GetKeepedObjects(dst);
4956 Py_INCREF(keep);
4957 return KeepRef(self, 0, keep);
4960 static PyGetSetDef Pointer_getsets[] = {
4961 { "contents", (getter)Pointer_get_contents,
4962 (setter)Pointer_set_contents,
4963 "the object this pointer points to (read-write)", NULL },
4964 { NULL, NULL }
4967 static int
4968 Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
4970 PyObject *value = NULL;
4972 if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
4973 return -1;
4974 if (value == NULL)
4975 return 0;
4976 return Pointer_set_contents(self, value, NULL);
4979 static PyObject *
4980 Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4982 StgDictObject *dict = PyType_stgdict((PyObject *)type);
4983 if (!dict || !dict->proto) {
4984 PyErr_SetString(PyExc_TypeError,
4985 "Cannot create instance: has no _type_");
4986 return NULL;
4988 return GenericCData_new(type, args, kw);
4991 static PyObject *
4992 Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
4994 CDataObject *self = (CDataObject *)_self;
4995 PyListObject *np;
4996 StgDictObject *stgdict, *itemdict;
4997 PyObject *proto;
4998 Py_ssize_t i, len;
5000 if (ilow < 0)
5001 ilow = 0;
5002 if (ihigh < ilow)
5003 ihigh = ilow;
5004 len = ihigh - ilow;
5006 stgdict = PyObject_stgdict((PyObject *)self);
5007 assert(stgdict); /* Cannot be NULL fr pointer instances */
5008 proto = stgdict->proto;
5009 assert(proto);
5010 itemdict = PyType_stgdict(proto);
5011 assert(itemdict);
5012 if (itemdict->getfunc == getentry("c")->getfunc) {
5013 char *ptr = *(char **)self->b_ptr;
5014 return PyString_FromStringAndSize(ptr + ilow, len);
5015 #ifdef CTYPES_UNICODE
5016 } else if (itemdict->getfunc == getentry("u")->getfunc) {
5017 wchar_t *ptr = *(wchar_t **)self->b_ptr;
5018 return PyUnicode_FromWideChar(ptr + ilow, len);
5019 #endif
5022 np = (PyListObject *) PyList_New(len);
5023 if (np == NULL)
5024 return NULL;
5026 for (i = 0; i < len; i++) {
5027 PyObject *v = Pointer_item(_self, i+ilow);
5028 PyList_SET_ITEM(np, i, v);
5030 return (PyObject *)np;
5033 static PyObject *
5034 Pointer_subscript(PyObject *_self, PyObject *item)
5036 CDataObject *self = (CDataObject *)_self;
5037 if (PyIndex_Check(item)) {
5038 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
5039 if (i == -1 && PyErr_Occurred())
5040 return NULL;
5041 return Pointer_item(_self, i);
5043 else if (PySlice_Check(item)) {
5044 PySliceObject *slice = (PySliceObject *)item;
5045 Py_ssize_t start, stop, step;
5046 PyObject *np;
5047 StgDictObject *stgdict, *itemdict;
5048 PyObject *proto;
5049 Py_ssize_t i, len, cur;
5051 /* Since pointers have no length, and we want to apply
5052 different semantics to negative indices than normal
5053 slicing, we have to dissect the slice object ourselves.*/
5054 if (slice->step == Py_None) {
5055 step = 1;
5057 else {
5058 step = PyNumber_AsSsize_t(slice->step,
5059 PyExc_ValueError);
5060 if (step == -1 && PyErr_Occurred())
5061 return NULL;
5062 if (step == 0) {
5063 PyErr_SetString(PyExc_ValueError,
5064 "slice step cannot be zero");
5065 return NULL;
5068 if (slice->start == Py_None) {
5069 if (step < 0) {
5070 PyErr_SetString(PyExc_ValueError,
5071 "slice start is required "
5072 "for step < 0");
5073 return NULL;
5075 start = 0;
5077 else {
5078 start = PyNumber_AsSsize_t(slice->start,
5079 PyExc_ValueError);
5080 if (start == -1 && PyErr_Occurred())
5081 return NULL;
5083 if (slice->stop == Py_None) {
5084 PyErr_SetString(PyExc_ValueError,
5085 "slice stop is required");
5086 return NULL;
5088 stop = PyNumber_AsSsize_t(slice->stop,
5089 PyExc_ValueError);
5090 if (stop == -1 && PyErr_Occurred())
5091 return NULL;
5092 if ((step > 0 && start > stop) ||
5093 (step < 0 && start < stop))
5094 len = 0;
5095 else if (step > 0)
5096 len = (stop - start - 1) / step + 1;
5097 else
5098 len = (stop - start + 1) / step + 1;
5100 stgdict = PyObject_stgdict((PyObject *)self);
5101 assert(stgdict); /* Cannot be NULL for pointer instances */
5102 proto = stgdict->proto;
5103 assert(proto);
5104 itemdict = PyType_stgdict(proto);
5105 assert(itemdict);
5106 if (itemdict->getfunc == getentry("c")->getfunc) {
5107 char *ptr = *(char **)self->b_ptr;
5108 char *dest;
5110 if (len <= 0)
5111 return PyString_FromString("");
5112 if (step == 1) {
5113 return PyString_FromStringAndSize(ptr + start,
5114 len);
5116 dest = (char *)PyMem_Malloc(len);
5117 if (dest == NULL)
5118 return PyErr_NoMemory();
5119 for (cur = start, i = 0; i < len; cur += step, i++) {
5120 dest[i] = ptr[cur];
5122 np = PyString_FromStringAndSize(dest, len);
5123 PyMem_Free(dest);
5124 return np;
5126 #ifdef CTYPES_UNICODE
5127 if (itemdict->getfunc == getentry("u")->getfunc) {
5128 wchar_t *ptr = *(wchar_t **)self->b_ptr;
5129 wchar_t *dest;
5131 if (len <= 0)
5132 return PyUnicode_FromUnicode(NULL, 0);
5133 if (step == 1) {
5134 return PyUnicode_FromWideChar(ptr + start,
5135 len);
5137 dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t));
5138 if (dest == NULL)
5139 return PyErr_NoMemory();
5140 for (cur = start, i = 0; i < len; cur += step, i++) {
5141 dest[i] = ptr[cur];
5143 np = PyUnicode_FromWideChar(dest, len);
5144 PyMem_Free(dest);
5145 return np;
5147 #endif
5149 np = PyList_New(len);
5150 if (np == NULL)
5151 return NULL;
5153 for (cur = start, i = 0; i < len; cur += step, i++) {
5154 PyObject *v = Pointer_item(_self, cur);
5155 PyList_SET_ITEM(np, i, v);
5157 return np;
5159 else {
5160 PyErr_SetString(PyExc_TypeError,
5161 "Pointer indices must be integer");
5162 return NULL;
5166 static PySequenceMethods Pointer_as_sequence = {
5167 0, /* inquiry sq_length; */
5168 0, /* binaryfunc sq_concat; */
5169 0, /* intargfunc sq_repeat; */
5170 Pointer_item, /* intargfunc sq_item; */
5171 Pointer_slice, /* intintargfunc sq_slice; */
5172 Pointer_ass_item, /* intobjargproc sq_ass_item; */
5173 0, /* intintobjargproc sq_ass_slice; */
5174 0, /* objobjproc sq_contains; */
5175 /* Added in release 2.0 */
5176 0, /* binaryfunc sq_inplace_concat; */
5177 0, /* intargfunc sq_inplace_repeat; */
5180 static PyMappingMethods Pointer_as_mapping = {
5182 Pointer_subscript,
5185 static int
5186 Pointer_nonzero(CDataObject *self)
5188 return (*(void **)self->b_ptr != NULL);
5191 static PyNumberMethods Pointer_as_number = {
5192 0, /* nb_add */
5193 0, /* nb_subtract */
5194 0, /* nb_multiply */
5195 0, /* nb_divide */
5196 0, /* nb_remainder */
5197 0, /* nb_divmod */
5198 0, /* nb_power */
5199 0, /* nb_negative */
5200 0, /* nb_positive */
5201 0, /* nb_absolute */
5202 (inquiry)Pointer_nonzero, /* nb_nonzero */
5205 PyTypeObject Pointer_Type = {
5206 PyVarObject_HEAD_INIT(NULL, 0)
5207 "_ctypes._Pointer",
5208 sizeof(CDataObject), /* tp_basicsize */
5209 0, /* tp_itemsize */
5210 0, /* tp_dealloc */
5211 0, /* tp_print */
5212 0, /* tp_getattr */
5213 0, /* tp_setattr */
5214 0, /* tp_compare */
5215 0, /* tp_repr */
5216 &Pointer_as_number, /* tp_as_number */
5217 &Pointer_as_sequence, /* tp_as_sequence */
5218 &Pointer_as_mapping, /* tp_as_mapping */
5219 0, /* tp_hash */
5220 0, /* tp_call */
5221 0, /* tp_str */
5222 0, /* tp_getattro */
5223 0, /* tp_setattro */
5224 &CData_as_buffer, /* tp_as_buffer */
5225 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
5226 "XXX to be provided", /* tp_doc */
5227 (traverseproc)CData_traverse, /* tp_traverse */
5228 (inquiry)CData_clear, /* tp_clear */
5229 0, /* tp_richcompare */
5230 0, /* tp_weaklistoffset */
5231 0, /* tp_iter */
5232 0, /* tp_iternext */
5233 0, /* tp_methods */
5234 0, /* tp_members */
5235 Pointer_getsets, /* tp_getset */
5236 0, /* tp_base */
5237 0, /* tp_dict */
5238 0, /* tp_descr_get */
5239 0, /* tp_descr_set */
5240 0, /* tp_dictoffset */
5241 (initproc)Pointer_init, /* tp_init */
5242 0, /* tp_alloc */
5243 Pointer_new, /* tp_new */
5244 0, /* tp_free */
5248 /******************************************************************/
5250 * Module initialization.
5253 static char *module_docs =
5254 "Create and manipulate C compatible data types in Python.";
5256 #ifdef MS_WIN32
5258 static char comerror_doc[] = "Raised when a COM method call failed.";
5260 static PyObject *
5261 comerror_init(PyObject *self, PyObject *args)
5263 PyObject *hresult, *text, *details;
5264 PyObject *a;
5265 int status;
5267 if (!PyArg_ParseTuple(args, "OOOO:COMError", &self, &hresult, &text, &details))
5268 return NULL;
5270 a = PySequence_GetSlice(args, 1, PySequence_Size(args));
5271 if (!a)
5272 return NULL;
5273 status = PyObject_SetAttrString(self, "args", a);
5274 Py_DECREF(a);
5275 if (status < 0)
5276 return NULL;
5278 if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
5279 return NULL;
5281 if (PyObject_SetAttrString(self, "text", text) < 0)
5282 return NULL;
5284 if (PyObject_SetAttrString(self, "details", details) < 0)
5285 return NULL;
5287 Py_INCREF(Py_None);
5288 return Py_None;
5291 static PyMethodDef comerror_methods[] = {
5292 { "__init__", comerror_init, METH_VARARGS },
5293 { NULL, NULL },
5296 static int
5297 create_comerror(void)
5299 PyObject *dict = PyDict_New();
5300 PyMethodDef *methods = comerror_methods;
5301 PyObject *s;
5302 int status;
5304 if (dict == NULL)
5305 return -1;
5307 while (methods->ml_name) {
5308 /* get a wrapper for the built-in function */
5309 PyObject *func = PyCFunction_New(methods, NULL);
5310 PyObject *meth;
5311 if (func == NULL)
5312 goto error;
5313 meth = PyMethod_New(func, NULL, ComError);
5314 Py_DECREF(func);
5315 if (meth == NULL)
5316 goto error;
5317 PyDict_SetItemString(dict, methods->ml_name, meth);
5318 Py_DECREF(meth);
5319 ++methods;
5322 s = PyString_FromString(comerror_doc);
5323 if (s == NULL)
5324 goto error;
5325 status = PyDict_SetItemString(dict, "__doc__", s);
5326 Py_DECREF(s);
5327 if (status == -1)
5328 goto error;
5330 ComError = PyErr_NewException("_ctypes.COMError",
5331 NULL,
5332 dict);
5333 if (ComError == NULL)
5334 goto error;
5336 return 0;
5337 error:
5338 Py_DECREF(dict);
5339 return -1;
5342 #endif
5344 static PyObject *
5345 string_at(const char *ptr, int size)
5347 if (size == -1)
5348 return PyString_FromString(ptr);
5349 return PyString_FromStringAndSize(ptr, size);
5352 static int
5353 cast_check_pointertype(PyObject *arg)
5355 StgDictObject *dict;
5357 if (PointerTypeObject_Check(arg))
5358 return 1;
5359 if (CFuncPtrTypeObject_Check(arg))
5360 return 1;
5361 dict = PyType_stgdict(arg);
5362 if (dict) {
5363 if (PyString_Check(dict->proto)
5364 && (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) {
5365 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
5366 return 1;
5369 PyErr_Format(PyExc_TypeError,
5370 "cast() argument 2 must be a pointer type, not %s",
5371 PyType_Check(arg)
5372 ? ((PyTypeObject *)arg)->tp_name
5373 : Py_TYPE(arg)->tp_name);
5374 return 0;
5377 static PyObject *
5378 cast(void *ptr, PyObject *src, PyObject *ctype)
5380 CDataObject *result;
5381 if (0 == cast_check_pointertype(ctype))
5382 return NULL;
5383 result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
5384 if (result == NULL)
5385 return NULL;
5388 The casted objects '_objects' member:
5390 It must certainly contain the source objects one.
5391 It must contain the source object itself.
5393 if (CDataObject_Check(src)) {
5394 CDataObject *obj = (CDataObject *)src;
5395 /* CData_GetContainer will initialize src.b_objects, we need
5396 this so it can be shared */
5397 CData_GetContainer(obj);
5398 /* But we need a dictionary! */
5399 if (obj->b_objects == Py_None) {
5400 Py_DECREF(Py_None);
5401 obj->b_objects = PyDict_New();
5402 if (obj->b_objects == NULL)
5403 goto failed;
5405 Py_XINCREF(obj->b_objects);
5406 result->b_objects = obj->b_objects;
5407 if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
5408 PyObject *index;
5409 int rc;
5410 index = PyLong_FromVoidPtr((void *)src);
5411 if (index == NULL)
5412 goto failed;
5413 rc = PyDict_SetItem(result->b_objects, index, src);
5414 Py_DECREF(index);
5415 if (rc == -1)
5416 goto failed;
5419 /* Should we assert that result is a pointer type? */
5420 memcpy(result->b_ptr, &ptr, sizeof(void *));
5421 return (PyObject *)result;
5423 failed:
5424 Py_DECREF(result);
5425 return NULL;
5428 #ifdef CTYPES_UNICODE
5429 static PyObject *
5430 wstring_at(const wchar_t *ptr, int size)
5432 Py_ssize_t ssize = size;
5433 if (ssize == -1)
5434 ssize = wcslen(ptr);
5435 return PyUnicode_FromWideChar(ptr, ssize);
5437 #endif
5439 PyMODINIT_FUNC
5440 init_ctypes(void)
5442 PyObject *m;
5444 /* Note:
5445 ob_type is the metatype (the 'type'), defaults to PyType_Type,
5446 tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
5448 #ifdef WITH_THREAD
5449 PyEval_InitThreads();
5450 #endif
5451 m = Py_InitModule3("_ctypes", module_methods, module_docs);
5452 if (!m)
5453 return;
5455 _pointer_type_cache = PyDict_New();
5456 if (_pointer_type_cache == NULL)
5457 return;
5459 PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_pointer_type_cache);
5461 _unpickle = PyObject_GetAttrString(m, "_unpickle");
5462 if (_unpickle == NULL)
5463 return;
5465 if (PyType_Ready(&PyCArg_Type) < 0)
5466 return;
5468 if (PyType_Ready(&CThunk_Type) < 0)
5469 return;
5471 /* StgDict is derived from PyDict_Type */
5472 StgDict_Type.tp_base = &PyDict_Type;
5473 if (PyType_Ready(&StgDict_Type) < 0)
5474 return;
5476 /*************************************************
5478 * Metaclasses
5481 StructType_Type.tp_base = &PyType_Type;
5482 if (PyType_Ready(&StructType_Type) < 0)
5483 return;
5485 UnionType_Type.tp_base = &PyType_Type;
5486 if (PyType_Ready(&UnionType_Type) < 0)
5487 return;
5489 PointerType_Type.tp_base = &PyType_Type;
5490 if (PyType_Ready(&PointerType_Type) < 0)
5491 return;
5493 ArrayType_Type.tp_base = &PyType_Type;
5494 if (PyType_Ready(&ArrayType_Type) < 0)
5495 return;
5497 SimpleType_Type.tp_base = &PyType_Type;
5498 if (PyType_Ready(&SimpleType_Type) < 0)
5499 return;
5501 CFuncPtrType_Type.tp_base = &PyType_Type;
5502 if (PyType_Ready(&CFuncPtrType_Type) < 0)
5503 return;
5505 /*************************************************
5507 * Classes using a custom metaclass
5510 if (PyType_Ready(&CData_Type) < 0)
5511 return;
5513 Py_TYPE(&Struct_Type) = &StructType_Type;
5514 Struct_Type.tp_base = &CData_Type;
5515 if (PyType_Ready(&Struct_Type) < 0)
5516 return;
5517 PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
5519 Py_TYPE(&Union_Type) = &UnionType_Type;
5520 Union_Type.tp_base = &CData_Type;
5521 if (PyType_Ready(&Union_Type) < 0)
5522 return;
5523 PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
5525 Py_TYPE(&Pointer_Type) = &PointerType_Type;
5526 Pointer_Type.tp_base = &CData_Type;
5527 if (PyType_Ready(&Pointer_Type) < 0)
5528 return;
5529 PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type);
5531 Py_TYPE(&Array_Type) = &ArrayType_Type;
5532 Array_Type.tp_base = &CData_Type;
5533 if (PyType_Ready(&Array_Type) < 0)
5534 return;
5535 PyModule_AddObject(m, "Array", (PyObject *)&Array_Type);
5537 Py_TYPE(&Simple_Type) = &SimpleType_Type;
5538 Simple_Type.tp_base = &CData_Type;
5539 if (PyType_Ready(&Simple_Type) < 0)
5540 return;
5541 PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
5543 Py_TYPE(&CFuncPtr_Type) = &CFuncPtrType_Type;
5544 CFuncPtr_Type.tp_base = &CData_Type;
5545 if (PyType_Ready(&CFuncPtr_Type) < 0)
5546 return;
5547 PyModule_AddObject(m, "CFuncPtr", (PyObject *)&CFuncPtr_Type);
5549 /*************************************************
5551 * Simple classes
5554 /* CField_Type is derived from PyBaseObject_Type */
5555 if (PyType_Ready(&CField_Type) < 0)
5556 return;
5558 /*************************************************
5560 * Other stuff
5563 DictRemover_Type.tp_new = PyType_GenericNew;
5564 if (PyType_Ready(&DictRemover_Type) < 0)
5565 return;
5567 #ifdef MS_WIN32
5568 if (create_comerror() < 0)
5569 return;
5570 PyModule_AddObject(m, "COMError", ComError);
5572 PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyInt_FromLong(FUNCFLAG_HRESULT));
5573 PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyInt_FromLong(FUNCFLAG_STDCALL));
5574 #endif
5575 PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
5576 PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyInt_FromLong(FUNCFLAG_USE_ERRNO));
5577 PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyInt_FromLong(FUNCFLAG_USE_LASTERROR));
5578 PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
5579 PyModule_AddStringConstant(m, "__version__", "1.1.0");
5581 PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
5582 PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
5583 PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
5584 PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
5585 #ifdef CTYPES_UNICODE
5586 PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
5587 #endif
5589 /* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
5590 #ifndef RTLD_LOCAL
5591 #define RTLD_LOCAL 0
5592 #endif
5594 /* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
5595 RTLD_LOCAL.
5597 #ifndef RTLD_GLOBAL
5598 #define RTLD_GLOBAL RTLD_LOCAL
5599 #endif
5601 PyModule_AddObject(m, "RTLD_LOCAL", PyInt_FromLong(RTLD_LOCAL));
5602 PyModule_AddObject(m, "RTLD_GLOBAL", PyInt_FromLong(RTLD_GLOBAL));
5604 PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5605 if (PyExc_ArgError) {
5606 Py_INCREF(PyExc_ArgError);
5607 PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
5611 /*****************************************************************
5612 * replacements for broken Python api functions (in Python 2.3).
5613 * See #1047269 Buffer overwrite in PyUnicode_AsWideChar
5616 #ifdef HAVE_WCHAR_H
5618 PyObject *My_PyUnicode_FromWideChar(register const wchar_t *w,
5619 Py_ssize_t size)
5621 PyUnicodeObject *unicode;
5623 if (w == NULL) {
5624 PyErr_BadInternalCall();
5625 return NULL;
5628 unicode = (PyUnicodeObject *)PyUnicode_FromUnicode(NULL, size);
5629 if (!unicode)
5630 return NULL;
5632 /* Copy the wchar_t data into the new object */
5633 #ifdef HAVE_USABLE_WCHAR_T
5634 memcpy(unicode->str, w, size * sizeof(wchar_t));
5635 #else
5637 register Py_UNICODE *u;
5638 register int i;
5639 u = PyUnicode_AS_UNICODE(unicode);
5640 /* In Python, the following line has a one-off error */
5641 for (i = size; i > 0; i--)
5642 *u++ = *w++;
5644 #endif
5646 return (PyObject *)unicode;
5649 Py_ssize_t My_PyUnicode_AsWideChar(PyUnicodeObject *unicode,
5650 register wchar_t *w,
5651 Py_ssize_t size)
5653 if (unicode == NULL) {
5654 PyErr_BadInternalCall();
5655 return -1;
5657 if (size > PyUnicode_GET_SIZE(unicode))
5658 size = PyUnicode_GET_SIZE(unicode);
5659 #ifdef HAVE_USABLE_WCHAR_T
5660 memcpy(w, unicode->str, size * sizeof(wchar_t));
5661 #else
5663 register Py_UNICODE *u;
5664 register int i;
5665 u = PyUnicode_AS_UNICODE(unicode);
5666 /* In Python, the following line has a one-off error */
5667 for (i = size; i > 0; i--)
5668 *w++ = *u++;
5670 #endif
5672 return size;
5675 #endif
5678 Local Variables:
5679 compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
5680 End: