typo: use one instead instead of two
[python.git] / Modules / _ctypes / _ctypes.c
blob4d2302d8ae308f65c6c7994d4e71bbb4d2f11f4e
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 PyCFuncPtrObject 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 PyCStructType_Type __new__(), from_address(), __mul__(), from_param()
32 UnionType_Type __new__(), from_address(), __mul__(), from_param()
33 PyCPointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type()
34 PyCArrayType_Type __new__(), from_address(), __mul__(), from_param()
35 PyCSimpleType_Type __new__(), from_address(), __mul__(), from_param()
37 PyCData_Type
38 Struct_Type __new__(), __init__()
39 PyCPointer_Type __new__(), __init__(), _as_parameter_, contents
40 PyCArray_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
41 Simple_Type __new__(), __init__(), _as_parameter_
43 PyCField_Type
44 PyCStgDict_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 * PyCStgDict_Type
91 * PyCStructType_Type
92 * UnionType_Type
93 * PyCPointerType_Type
94 * PyCArrayType_Type
95 * PyCSimpleType_Type
97 * PyCData_Type
98 * Struct_Type
99 * Union_Type
100 * PyCArray_Type
101 * Simple_Type
102 * PyCPointer_Type
103 * PyCField_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 *_ctypes_ptrtype_cache;
135 static PyTypeObject Simple_Type;
137 /* a callable object used for unpickling */
138 static PyObject *_unpickle;
140 char *_ctypes_conversion_encoding = NULL;
141 char *_ctypes_conversion_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 _ctypes_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 PyCStructType_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 = PyCArgObject_new();
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 *)&PyCStgDict_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 = _ctypes_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 == PyCStgDict_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 PyCStructType_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 PyCData_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 cannot 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 = PyCData_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 GenericPyCData_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 cannot 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 = GenericPyCData_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 PyCData_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 PyCArrayType_from_ctype(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 PyCStructType_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 PyCStructUnionType_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 PyCStructUnionType_update_stgdict(self, value, 0);
740 return 0;
744 PyTypeObject PyCStructType_Type = {
745 PyVarObject_HEAD_INIT(NULL, 0)
746 "_ctypes.PyCStructType", /* 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 PyCStructType_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 PyCStructType_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 PyCPointerType_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 PyCPointer_Type provides the functionality: a contents method/property, a
841 size property/method, and the sequence protocol.
845 static int
846 PyCPointerType_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 PyCPointerType_paramfunc(CDataObject *self)
867 PyCArgObject *parg;
869 parg = PyCArgObject_new();
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 PyCPointerType_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 *)&PyCStgDict_Type, NULL);
898 if (!stgdict)
899 return NULL;
900 stgdict->size = sizeof(void *);
901 stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
902 stgdict->length = 1;
903 stgdict->ffi_type_pointer = ffi_type_pointer;
904 stgdict->paramfunc = PyCPointerType_paramfunc;
905 stgdict->flags |= TYPEFLAG_ISPOINTER;
907 proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
908 if (proto && -1 == PyCPointerType_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 = _ctypes_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 PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
953 StgDictObject *dict;
955 dict = PyType_stgdict((PyObject *)self);
956 assert(dict);
958 if (-1 == PyCPointerType_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 PyCPointerType_from_param(PyObject *type, PyObject *value)
973 StgDictObject *typedict;
975 if (value == Py_None) {
976 /* ConvParam will convert to a NULL pointer later */
977 Py_INCREF(value);
978 return value;
981 typedict = PyType_stgdict(type);
982 assert(typedict); /* Cannot be NULL for pointer types */
984 /* If we expect POINTER(<type>), but receive a <type> instance, accept
985 it by calling byref(<type>).
987 switch (PyObject_IsInstance(value, typedict->proto)) {
988 case 1:
989 Py_INCREF(value); /* _byref steals a refcount */
990 return _byref(value);
991 case -1:
992 PyErr_Clear();
993 break;
994 default:
995 break;
998 if (PointerObject_Check(value) || ArrayObject_Check(value)) {
999 /* Array instances are also pointers when
1000 the item types are the same.
1002 StgDictObject *v = PyObject_stgdict(value);
1003 assert(v); /* Cannot be NULL for pointer or array objects */
1004 if (PyObject_IsSubclass(v->proto, typedict->proto)) {
1005 Py_INCREF(value);
1006 return value;
1009 return CDataType_from_param(type, value);
1012 static PyMethodDef PyCPointerType_methods[] = {
1013 { "from_address", CDataType_from_address, METH_O, from_address_doc },
1014 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
1015 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
1016 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
1017 { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc},
1018 { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O },
1019 { NULL, NULL },
1022 PyTypeObject PyCPointerType_Type = {
1023 PyVarObject_HEAD_INIT(NULL, 0)
1024 "_ctypes.PyCPointerType", /* tp_name */
1025 0, /* tp_basicsize */
1026 0, /* tp_itemsize */
1027 0, /* tp_dealloc */
1028 0, /* tp_print */
1029 0, /* tp_getattr */
1030 0, /* tp_setattr */
1031 0, /* tp_compare */
1032 0, /* tp_repr */
1033 0, /* tp_as_number */
1034 &CDataType_as_sequence, /* tp_as_sequence */
1035 0, /* tp_as_mapping */
1036 0, /* tp_hash */
1037 0, /* tp_call */
1038 0, /* tp_str */
1039 0, /* tp_getattro */
1040 0, /* tp_setattro */
1041 0, /* tp_as_buffer */
1042 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1043 "metatype for the Pointer Objects", /* tp_doc */
1044 (traverseproc)CDataType_traverse, /* tp_traverse */
1045 (inquiry)CDataType_clear, /* tp_clear */
1046 0, /* tp_richcompare */
1047 0, /* tp_weaklistoffset */
1048 0, /* tp_iter */
1049 0, /* tp_iternext */
1050 PyCPointerType_methods, /* tp_methods */
1051 0, /* tp_members */
1052 0, /* tp_getset */
1053 0, /* tp_base */
1054 0, /* tp_dict */
1055 0, /* tp_descr_get */
1056 0, /* tp_descr_set */
1057 0, /* tp_dictoffset */
1058 0, /* tp_init */
1059 0, /* tp_alloc */
1060 PyCPointerType_new, /* tp_new */
1061 0, /* tp_free */
1065 /******************************************************************/
1067 PyCArrayType_Type
1070 PyCArrayType_new ensures that the new Array subclass created has a _length_
1071 attribute, and a _type_ attribute.
1074 static int
1075 CharArray_set_raw(CDataObject *self, PyObject *value)
1077 char *ptr;
1078 Py_ssize_t size;
1079 if (PyBuffer_Check(value)) {
1080 size = Py_TYPE(value)->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
1081 if (size < 0)
1082 return -1;
1083 } else if (-1 == PyString_AsStringAndSize(value, &ptr, &size)) {
1084 return -1;
1086 if (size > self->b_size) {
1087 PyErr_SetString(PyExc_ValueError,
1088 "string too long");
1089 return -1;
1092 memcpy(self->b_ptr, ptr, size);
1094 return 0;
1097 static PyObject *
1098 CharArray_get_raw(CDataObject *self)
1100 return PyString_FromStringAndSize(self->b_ptr, self->b_size);
1103 static PyObject *
1104 CharArray_get_value(CDataObject *self)
1106 int i;
1107 char *ptr = self->b_ptr;
1108 for (i = 0; i < self->b_size; ++i)
1109 if (*ptr++ == '\0')
1110 break;
1111 return PyString_FromStringAndSize(self->b_ptr, i);
1114 static int
1115 CharArray_set_value(CDataObject *self, PyObject *value)
1117 char *ptr;
1118 Py_ssize_t size;
1120 if (value == NULL) {
1121 PyErr_SetString(PyExc_TypeError,
1122 "can't delete attribute");
1123 return -1;
1126 if (PyUnicode_Check(value)) {
1127 value = PyUnicode_AsEncodedString(value,
1128 _ctypes_conversion_encoding,
1129 _ctypes_conversion_errors);
1130 if (!value)
1131 return -1;
1132 } else if (!PyString_Check(value)) {
1133 PyErr_Format(PyExc_TypeError,
1134 "string expected instead of %s instance",
1135 Py_TYPE(value)->tp_name);
1136 return -1;
1137 } else
1138 Py_INCREF(value);
1139 size = PyString_GET_SIZE(value);
1140 if (size > self->b_size) {
1141 PyErr_SetString(PyExc_ValueError,
1142 "string too long");
1143 Py_DECREF(value);
1144 return -1;
1147 ptr = PyString_AS_STRING(value);
1148 memcpy(self->b_ptr, ptr, size);
1149 if (size < self->b_size)
1150 self->b_ptr[size] = '\0';
1151 Py_DECREF(value);
1153 return 0;
1156 static PyGetSetDef CharArray_getsets[] = {
1157 { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
1158 "value", NULL },
1159 { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
1160 "string value"},
1161 { NULL, NULL }
1164 #ifdef CTYPES_UNICODE
1165 static PyObject *
1166 WCharArray_get_value(CDataObject *self)
1168 unsigned int i;
1169 wchar_t *ptr = (wchar_t *)self->b_ptr;
1170 for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
1171 if (*ptr++ == (wchar_t)0)
1172 break;
1173 return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
1176 static int
1177 WCharArray_set_value(CDataObject *self, PyObject *value)
1179 Py_ssize_t result = 0;
1181 if (value == NULL) {
1182 PyErr_SetString(PyExc_TypeError,
1183 "can't delete attribute");
1184 return -1;
1186 if (PyString_Check(value)) {
1187 value = PyUnicode_FromEncodedObject(value,
1188 _ctypes_conversion_encoding,
1189 _ctypes_conversion_errors);
1190 if (!value)
1191 return -1;
1192 } else if (!PyUnicode_Check(value)) {
1193 PyErr_Format(PyExc_TypeError,
1194 "unicode string expected instead of %s instance",
1195 Py_TYPE(value)->tp_name);
1196 return -1;
1197 } else
1198 Py_INCREF(value);
1199 if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
1200 PyErr_SetString(PyExc_ValueError,
1201 "string too long");
1202 result = -1;
1203 goto done;
1205 result = PyUnicode_AsWideChar((PyUnicodeObject *)value,
1206 (wchar_t *)self->b_ptr,
1207 self->b_size/sizeof(wchar_t));
1208 if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
1209 ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
1210 done:
1211 Py_DECREF(value);
1213 return result >= 0 ? 0 : -1;
1216 static PyGetSetDef WCharArray_getsets[] = {
1217 { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
1218 "string value"},
1219 { NULL, NULL }
1221 #endif
1224 The next three functions copied from Python's typeobject.c.
1226 They are used to attach methods, members, or getsets to a type *after* it
1227 has been created: Arrays of characters have additional getsets to treat them
1228 as strings.
1231 static int
1232 add_methods(PyTypeObject *type, PyMethodDef *meth)
1234 PyObject *dict = type->tp_dict;
1235 for (; meth->ml_name != NULL; meth++) {
1236 PyObject *descr;
1237 descr = PyDescr_NewMethod(type, meth);
1238 if (descr == NULL)
1239 return -1;
1240 if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
1241 return -1;
1242 Py_DECREF(descr);
1244 return 0;
1247 static int
1248 add_members(PyTypeObject *type, PyMemberDef *memb)
1250 PyObject *dict = type->tp_dict;
1251 for (; memb->name != NULL; memb++) {
1252 PyObject *descr;
1253 descr = PyDescr_NewMember(type, memb);
1254 if (descr == NULL)
1255 return -1;
1256 if (PyDict_SetItemString(dict, memb->name, descr) < 0)
1257 return -1;
1258 Py_DECREF(descr);
1260 return 0;
1264 static int
1265 add_getset(PyTypeObject *type, PyGetSetDef *gsp)
1267 PyObject *dict = type->tp_dict;
1268 for (; gsp->name != NULL; gsp++) {
1269 PyObject *descr;
1270 descr = PyDescr_NewGetSet(type, gsp);
1271 if (descr == NULL)
1272 return -1;
1273 if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
1274 return -1;
1275 Py_DECREF(descr);
1277 return 0;
1280 static PyCArgObject *
1281 PyCArrayType_paramfunc(CDataObject *self)
1283 PyCArgObject *p = PyCArgObject_new();
1284 if (p == NULL)
1285 return NULL;
1286 p->tag = 'P';
1287 p->pffi_type = &ffi_type_pointer;
1288 p->value.p = (char *)self->b_ptr;
1289 Py_INCREF(self);
1290 p->obj = (PyObject *)self;
1291 return p;
1294 static PyObject *
1295 PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1297 PyTypeObject *result;
1298 StgDictObject *stgdict;
1299 StgDictObject *itemdict;
1300 PyObject *proto;
1301 PyObject *typedict;
1302 long length;
1304 Py_ssize_t itemsize, itemalign;
1305 char buf[32];
1307 typedict = PyTuple_GetItem(args, 2);
1308 if (!typedict)
1309 return NULL;
1311 proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
1312 if (!proto || !PyInt_Check(proto)) {
1313 PyErr_SetString(PyExc_AttributeError,
1314 "class must define a '_length_' attribute, "
1315 "which must be a positive integer");
1316 return NULL;
1318 length = PyInt_AS_LONG(proto);
1320 proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
1321 if (!proto) {
1322 PyErr_SetString(PyExc_AttributeError,
1323 "class must define a '_type_' attribute");
1324 return NULL;
1327 stgdict = (StgDictObject *)PyObject_CallObject(
1328 (PyObject *)&PyCStgDict_Type, NULL);
1329 if (!stgdict)
1330 return NULL;
1332 itemdict = PyType_stgdict(proto);
1333 if (!itemdict) {
1334 PyErr_SetString(PyExc_TypeError,
1335 "_type_ must have storage info");
1336 Py_DECREF((PyObject *)stgdict);
1337 return NULL;
1340 assert(itemdict->format);
1341 if (itemdict->format[0] == '(') {
1342 sprintf(buf, "(%ld,", length);
1343 stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1);
1344 } else {
1345 sprintf(buf, "(%ld)", length);
1346 stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format);
1348 if (stgdict->format == NULL) {
1349 Py_DECREF((PyObject *)stgdict);
1350 return NULL;
1352 stgdict->ndim = itemdict->ndim + 1;
1353 stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t *) * stgdict->ndim);
1354 if (stgdict->shape == NULL) {
1355 Py_DECREF((PyObject *)stgdict);
1356 return NULL;
1358 stgdict->shape[0] = length;
1359 memmove(&stgdict->shape[1], itemdict->shape,
1360 sizeof(Py_ssize_t) * (stgdict->ndim - 1));
1362 itemsize = itemdict->size;
1363 if (length * itemsize < 0) {
1364 PyErr_SetString(PyExc_OverflowError,
1365 "array too large");
1366 return NULL;
1369 itemalign = itemdict->align;
1371 if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
1372 stgdict->flags |= TYPEFLAG_HASPOINTER;
1374 stgdict->size = itemsize * length;
1375 stgdict->align = itemalign;
1376 stgdict->length = length;
1377 Py_INCREF(proto);
1378 stgdict->proto = proto;
1380 stgdict->paramfunc = &PyCArrayType_paramfunc;
1382 /* Arrays are passed as pointers to function calls. */
1383 stgdict->ffi_type_pointer = ffi_type_pointer;
1385 /* create the new instance (which is a class,
1386 since we are a metatype!) */
1387 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1388 if (result == NULL)
1389 return NULL;
1391 /* replace the class dict by our updated spam dict */
1392 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1393 Py_DECREF(result);
1394 Py_DECREF((PyObject *)stgdict);
1395 return NULL;
1397 Py_DECREF(result->tp_dict);
1398 result->tp_dict = (PyObject *)stgdict;
1400 /* Special case for character arrays.
1401 A permanent annoyance: char arrays are also strings!
1403 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
1404 if (-1 == add_getset(result, CharArray_getsets))
1405 return NULL;
1406 #ifdef CTYPES_UNICODE
1407 } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
1408 if (-1 == add_getset(result, WCharArray_getsets))
1409 return NULL;
1410 #endif
1413 return (PyObject *)result;
1416 PyTypeObject PyCArrayType_Type = {
1417 PyVarObject_HEAD_INIT(NULL, 0)
1418 "_ctypes.PyCArrayType", /* tp_name */
1419 0, /* tp_basicsize */
1420 0, /* tp_itemsize */
1421 0, /* tp_dealloc */
1422 0, /* tp_print */
1423 0, /* tp_getattr */
1424 0, /* tp_setattr */
1425 0, /* tp_compare */
1426 0, /* tp_repr */
1427 0, /* tp_as_number */
1428 &CDataType_as_sequence, /* tp_as_sequence */
1429 0, /* tp_as_mapping */
1430 0, /* tp_hash */
1431 0, /* tp_call */
1432 0, /* tp_str */
1433 0, /* tp_getattro */
1434 0, /* tp_setattro */
1435 0, /* tp_as_buffer */
1436 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1437 "metatype for the Array Objects", /* tp_doc */
1438 0, /* tp_traverse */
1439 0, /* tp_clear */
1440 0, /* tp_richcompare */
1441 0, /* tp_weaklistoffset */
1442 0, /* tp_iter */
1443 0, /* tp_iternext */
1444 CDataType_methods, /* tp_methods */
1445 0, /* tp_members */
1446 0, /* tp_getset */
1447 0, /* tp_base */
1448 0, /* tp_dict */
1449 0, /* tp_descr_get */
1450 0, /* tp_descr_set */
1451 0, /* tp_dictoffset */
1452 0, /* tp_init */
1453 0, /* tp_alloc */
1454 PyCArrayType_new, /* tp_new */
1455 0, /* tp_free */
1459 /******************************************************************/
1461 PyCSimpleType_Type
1465 PyCSimpleType_new ensures that the new Simple_Type subclass created has a valid
1466 _type_ attribute.
1470 static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv?g";
1472 static PyObject *
1473 c_wchar_p_from_param(PyObject *type, PyObject *value)
1475 PyObject *as_parameter;
1476 #if (PYTHON_API_VERSION < 1012)
1477 # error not supported
1478 #endif
1479 if (value == Py_None) {
1480 Py_INCREF(Py_None);
1481 return Py_None;
1483 if (PyUnicode_Check(value) || PyString_Check(value)) {
1484 PyCArgObject *parg;
1485 struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1487 parg = PyCArgObject_new();
1488 if (parg == NULL)
1489 return NULL;
1490 parg->pffi_type = &ffi_type_pointer;
1491 parg->tag = 'Z';
1492 parg->obj = fd->setfunc(&parg->value, value, 0);
1493 if (parg->obj == NULL) {
1494 Py_DECREF(parg);
1495 return NULL;
1497 return (PyObject *)parg;
1499 if (PyObject_IsInstance(value, type)) {
1500 Py_INCREF(value);
1501 return value;
1503 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1504 /* c_wchar array instance or pointer(c_wchar(...)) */
1505 StgDictObject *dt = PyObject_stgdict(value);
1506 StgDictObject *dict;
1507 assert(dt); /* Cannot be NULL for pointer or array objects */
1508 dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1509 if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1510 Py_INCREF(value);
1511 return value;
1514 if (PyCArg_CheckExact(value)) {
1515 /* byref(c_char(...)) */
1516 PyCArgObject *a = (PyCArgObject *)value;
1517 StgDictObject *dict = PyObject_stgdict(a->obj);
1518 if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1519 Py_INCREF(value);
1520 return value;
1524 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1525 if (as_parameter) {
1526 value = c_wchar_p_from_param(type, as_parameter);
1527 Py_DECREF(as_parameter);
1528 return value;
1530 /* XXX better message */
1531 PyErr_SetString(PyExc_TypeError,
1532 "wrong type");
1533 return NULL;
1536 static PyObject *
1537 c_char_p_from_param(PyObject *type, PyObject *value)
1539 PyObject *as_parameter;
1540 #if (PYTHON_API_VERSION < 1012)
1541 # error not supported
1542 #endif
1543 if (value == Py_None) {
1544 Py_INCREF(Py_None);
1545 return Py_None;
1547 if (PyString_Check(value) || PyUnicode_Check(value)) {
1548 PyCArgObject *parg;
1549 struct fielddesc *fd = _ctypes_get_fielddesc("z");
1551 parg = PyCArgObject_new();
1552 if (parg == NULL)
1553 return NULL;
1554 parg->pffi_type = &ffi_type_pointer;
1555 parg->tag = 'z';
1556 parg->obj = fd->setfunc(&parg->value, value, 0);
1557 if (parg->obj == NULL) {
1558 Py_DECREF(parg);
1559 return NULL;
1561 return (PyObject *)parg;
1563 if (PyObject_IsInstance(value, type)) {
1564 Py_INCREF(value);
1565 return value;
1567 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1568 /* c_char array instance or pointer(c_char(...)) */
1569 StgDictObject *dt = PyObject_stgdict(value);
1570 StgDictObject *dict;
1571 assert(dt); /* Cannot be NULL for pointer or array objects */
1572 dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1573 if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1574 Py_INCREF(value);
1575 return value;
1578 if (PyCArg_CheckExact(value)) {
1579 /* byref(c_char(...)) */
1580 PyCArgObject *a = (PyCArgObject *)value;
1581 StgDictObject *dict = PyObject_stgdict(a->obj);
1582 if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1583 Py_INCREF(value);
1584 return value;
1588 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1589 if (as_parameter) {
1590 value = c_char_p_from_param(type, as_parameter);
1591 Py_DECREF(as_parameter);
1592 return value;
1594 /* XXX better message */
1595 PyErr_SetString(PyExc_TypeError,
1596 "wrong type");
1597 return NULL;
1600 static PyObject *
1601 c_void_p_from_param(PyObject *type, PyObject *value)
1603 StgDictObject *stgd;
1604 PyObject *as_parameter;
1605 #if (PYTHON_API_VERSION < 1012)
1606 # error not supported
1607 #endif
1609 /* None */
1610 if (value == Py_None) {
1611 Py_INCREF(Py_None);
1612 return Py_None;
1614 /* Should probably allow buffer interface as well */
1615 /* int, long */
1616 if (PyInt_Check(value) || PyLong_Check(value)) {
1617 PyCArgObject *parg;
1618 struct fielddesc *fd = _ctypes_get_fielddesc("P");
1620 parg = PyCArgObject_new();
1621 if (parg == NULL)
1622 return NULL;
1623 parg->pffi_type = &ffi_type_pointer;
1624 parg->tag = 'P';
1625 parg->obj = fd->setfunc(&parg->value, value, 0);
1626 if (parg->obj == NULL) {
1627 Py_DECREF(parg);
1628 return NULL;
1630 return (PyObject *)parg;
1632 /* string */
1633 if (PyString_Check(value)) {
1634 PyCArgObject *parg;
1635 struct fielddesc *fd = _ctypes_get_fielddesc("z");
1637 parg = PyCArgObject_new();
1638 if (parg == NULL)
1639 return NULL;
1640 parg->pffi_type = &ffi_type_pointer;
1641 parg->tag = 'z';
1642 parg->obj = fd->setfunc(&parg->value, value, 0);
1643 if (parg->obj == NULL) {
1644 Py_DECREF(parg);
1645 return NULL;
1647 return (PyObject *)parg;
1649 /* unicode */
1650 if (PyUnicode_Check(value)) {
1651 PyCArgObject *parg;
1652 struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1654 parg = PyCArgObject_new();
1655 if (parg == NULL)
1656 return NULL;
1657 parg->pffi_type = &ffi_type_pointer;
1658 parg->tag = 'Z';
1659 parg->obj = fd->setfunc(&parg->value, value, 0);
1660 if (parg->obj == NULL) {
1661 Py_DECREF(parg);
1662 return NULL;
1664 return (PyObject *)parg;
1666 /* c_void_p instance (or subclass) */
1667 if (PyObject_IsInstance(value, type)) {
1668 /* c_void_p instances */
1669 Py_INCREF(value);
1670 return value;
1672 /* ctypes array or pointer instance */
1673 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1674 /* Any array or pointer is accepted */
1675 Py_INCREF(value);
1676 return value;
1678 /* byref(...) */
1679 if (PyCArg_CheckExact(value)) {
1680 /* byref(c_xxx()) */
1681 PyCArgObject *a = (PyCArgObject *)value;
1682 if (a->tag == 'P') {
1683 Py_INCREF(value);
1684 return value;
1687 /* function pointer */
1688 if (PyCFuncPtrObject_Check(value)) {
1689 PyCArgObject *parg;
1690 PyCFuncPtrObject *func;
1691 func = (PyCFuncPtrObject *)value;
1692 parg = PyCArgObject_new();
1693 if (parg == NULL)
1694 return NULL;
1695 parg->pffi_type = &ffi_type_pointer;
1696 parg->tag = 'P';
1697 Py_INCREF(value);
1698 parg->value.p = *(void **)func->b_ptr;
1699 parg->obj = value;
1700 return (PyObject *)parg;
1702 /* c_char_p, c_wchar_p */
1703 stgd = PyObject_stgdict(value);
1704 if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
1705 PyCArgObject *parg;
1707 switch (PyString_AS_STRING(stgd->proto)[0]) {
1708 case 'z': /* c_char_p */
1709 case 'Z': /* c_wchar_p */
1710 parg = PyCArgObject_new();
1711 if (parg == NULL)
1712 return NULL;
1713 parg->pffi_type = &ffi_type_pointer;
1714 parg->tag = 'Z';
1715 Py_INCREF(value);
1716 parg->obj = value;
1717 /* Remember: b_ptr points to where the pointer is stored! */
1718 parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
1719 return (PyObject *)parg;
1723 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1724 if (as_parameter) {
1725 value = c_void_p_from_param(type, as_parameter);
1726 Py_DECREF(as_parameter);
1727 return value;
1729 /* XXX better message */
1730 PyErr_SetString(PyExc_TypeError,
1731 "wrong type");
1732 return NULL;
1734 #if (PYTHON_API_VERSION >= 1012)
1736 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1737 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
1738 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1740 #else
1741 #error
1742 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_VARARGS };
1743 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_VARARGS };
1744 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_VARARGS };
1746 #endif
1748 static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
1749 PyObject *proto, struct fielddesc *fmt)
1751 PyTypeObject *result;
1752 StgDictObject *stgdict;
1753 PyObject *name = PyTuple_GET_ITEM(args, 0);
1754 PyObject *swapped_args;
1755 static PyObject *suffix;
1756 Py_ssize_t i;
1758 swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
1759 if (!swapped_args)
1760 return NULL;
1762 if (suffix == NULL)
1763 #ifdef WORDS_BIGENDIAN
1764 suffix = PyString_InternFromString("_le");
1765 #else
1766 suffix = PyString_InternFromString("_be");
1767 #endif
1769 Py_INCREF(name);
1770 PyString_Concat(&name, suffix);
1771 if (name == NULL)
1772 return NULL;
1774 PyTuple_SET_ITEM(swapped_args, 0, name);
1775 for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
1776 PyObject *v = PyTuple_GET_ITEM(args, i);
1777 Py_INCREF(v);
1778 PyTuple_SET_ITEM(swapped_args, i, v);
1781 /* create the new instance (which is a class,
1782 since we are a metatype!) */
1783 result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
1784 Py_DECREF(swapped_args);
1785 if (result == NULL)
1786 return NULL;
1788 stgdict = (StgDictObject *)PyObject_CallObject(
1789 (PyObject *)&PyCStgDict_Type, NULL);
1790 if (!stgdict) /* XXX leaks result! */
1791 return NULL;
1793 stgdict->ffi_type_pointer = *fmt->pffi_type;
1794 stgdict->align = fmt->pffi_type->alignment;
1795 stgdict->length = 0;
1796 stgdict->size = fmt->pffi_type->size;
1797 stgdict->setfunc = fmt->setfunc_swapped;
1798 stgdict->getfunc = fmt->getfunc_swapped;
1800 Py_INCREF(proto);
1801 stgdict->proto = proto;
1803 /* replace the class dict by our updated spam dict */
1804 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1805 Py_DECREF(result);
1806 Py_DECREF((PyObject *)stgdict);
1807 return NULL;
1809 Py_DECREF(result->tp_dict);
1810 result->tp_dict = (PyObject *)stgdict;
1812 return (PyObject *)result;
1815 static PyCArgObject *
1816 PyCSimpleType_paramfunc(CDataObject *self)
1818 StgDictObject *dict;
1819 char *fmt;
1820 PyCArgObject *parg;
1821 struct fielddesc *fd;
1823 dict = PyObject_stgdict((PyObject *)self);
1824 assert(dict); /* Cannot be NULL for CDataObject instances */
1825 fmt = PyString_AsString(dict->proto);
1826 assert(fmt);
1828 fd = _ctypes_get_fielddesc(fmt);
1829 assert(fd);
1831 parg = PyCArgObject_new();
1832 if (parg == NULL)
1833 return NULL;
1835 parg->tag = fmt[0];
1836 parg->pffi_type = fd->pffi_type;
1837 Py_INCREF(self);
1838 parg->obj = (PyObject *)self;
1839 memcpy(&parg->value, self->b_ptr, self->b_size);
1840 return parg;
1843 static PyObject *
1844 PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1846 PyTypeObject *result;
1847 StgDictObject *stgdict;
1848 PyObject *proto;
1849 const char *proto_str;
1850 Py_ssize_t proto_len;
1851 PyMethodDef *ml;
1852 struct fielddesc *fmt;
1854 /* create the new instance (which is a class,
1855 since we are a metatype!) */
1856 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1857 if (result == NULL)
1858 return NULL;
1860 proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
1861 if (!proto) {
1862 PyErr_SetString(PyExc_AttributeError,
1863 "class must define a '_type_' attribute");
1864 error:
1865 Py_XDECREF(proto);
1866 Py_XDECREF(result);
1867 return NULL;
1869 if (PyString_Check(proto)) {
1870 proto_str = PyString_AS_STRING(proto);
1871 proto_len = PyString_GET_SIZE(proto);
1872 } else {
1873 PyErr_SetString(PyExc_TypeError,
1874 "class must define a '_type_' string attribute");
1875 goto error;
1877 if (proto_len != 1) {
1878 PyErr_SetString(PyExc_ValueError,
1879 "class must define a '_type_' attribute "
1880 "which must be a string of length 1");
1881 goto error;
1883 if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
1884 PyErr_Format(PyExc_AttributeError,
1885 "class must define a '_type_' attribute which must be\n"
1886 "a single character string containing one of '%s'.",
1887 SIMPLE_TYPE_CHARS);
1888 goto error;
1890 fmt = _ctypes_get_fielddesc(PyString_AS_STRING(proto));
1891 if (fmt == NULL) {
1892 PyErr_Format(PyExc_ValueError,
1893 "_type_ '%s' not supported",
1894 PyString_AS_STRING(proto));
1895 goto error;
1898 stgdict = (StgDictObject *)PyObject_CallObject(
1899 (PyObject *)&PyCStgDict_Type, NULL);
1900 if (!stgdict)
1901 goto error;
1903 stgdict->ffi_type_pointer = *fmt->pffi_type;
1904 stgdict->align = fmt->pffi_type->alignment;
1905 stgdict->length = 0;
1906 stgdict->size = fmt->pffi_type->size;
1907 stgdict->setfunc = fmt->setfunc;
1908 stgdict->getfunc = fmt->getfunc;
1909 #ifdef WORDS_BIGENDIAN
1910 stgdict->format = _ctypes_alloc_format_string(">", proto_str);
1911 #else
1912 stgdict->format = _ctypes_alloc_format_string("<", proto_str);
1913 #endif
1914 if (stgdict->format == NULL) {
1915 Py_DECREF(result);
1916 Py_DECREF(proto);
1917 Py_DECREF((PyObject *)stgdict);
1918 return NULL;
1921 stgdict->paramfunc = PyCSimpleType_paramfunc;
1923 if (result->tp_base != &Simple_Type) {
1924 stgdict->setfunc = NULL;
1925 stgdict->getfunc = NULL;
1929 /* This consumes the refcount on proto which we have */
1930 stgdict->proto = proto;
1932 /* replace the class dict by our updated spam dict */
1933 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1934 Py_DECREF(result);
1935 Py_DECREF((PyObject *)stgdict);
1936 return NULL;
1938 Py_DECREF(result->tp_dict);
1939 result->tp_dict = (PyObject *)stgdict;
1941 /* Install from_param class methods in ctypes base classes.
1942 Overrides the PyCSimpleType_from_param generic method.
1944 if (result->tp_base == &Simple_Type) {
1945 switch (PyString_AS_STRING(proto)[0]) {
1946 case 'z': /* c_char_p */
1947 ml = &c_char_p_method;
1948 stgdict->flags |= TYPEFLAG_ISPOINTER;
1949 break;
1950 case 'Z': /* c_wchar_p */
1951 ml = &c_wchar_p_method;
1952 stgdict->flags |= TYPEFLAG_ISPOINTER;
1953 break;
1954 case 'P': /* c_void_p */
1955 ml = &c_void_p_method;
1956 stgdict->flags |= TYPEFLAG_ISPOINTER;
1957 break;
1958 case 's':
1959 case 'X':
1960 case 'O':
1961 ml = NULL;
1962 stgdict->flags |= TYPEFLAG_ISPOINTER;
1963 break;
1964 default:
1965 ml = NULL;
1966 break;
1969 if (ml) {
1970 #if (PYTHON_API_VERSION >= 1012)
1971 PyObject *meth;
1972 int x;
1973 meth = PyDescr_NewClassMethod(result, ml);
1974 if (!meth)
1975 return NULL;
1976 #else
1977 #error
1978 PyObject *meth, *func;
1979 int x;
1980 func = PyCFunction_New(ml, NULL);
1981 if (!func)
1982 return NULL;
1983 meth = PyObject_CallFunctionObjArgs(
1984 (PyObject *)&PyClassMethod_Type,
1985 func, NULL);
1986 Py_DECREF(func);
1987 if (!meth) {
1988 return NULL;
1990 #endif
1991 x = PyDict_SetItemString(result->tp_dict,
1992 ml->ml_name,
1993 meth);
1994 Py_DECREF(meth);
1995 if (x == -1) {
1996 Py_DECREF(result);
1997 return NULL;
2002 if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
2003 PyObject *swapped = CreateSwappedType(type, args, kwds,
2004 proto, fmt);
2005 StgDictObject *sw_dict;
2006 if (swapped == NULL) {
2007 Py_DECREF(result);
2008 return NULL;
2010 sw_dict = PyType_stgdict(swapped);
2011 #ifdef WORDS_BIGENDIAN
2012 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
2013 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
2014 PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
2015 PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
2016 /* We are creating the type for the OTHER endian */
2017 sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1);
2018 #else
2019 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
2020 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
2021 PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
2022 PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
2023 /* We are creating the type for the OTHER endian */
2024 sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1);
2025 #endif
2026 Py_DECREF(swapped);
2027 if (PyErr_Occurred()) {
2028 Py_DECREF(result);
2029 return NULL;
2033 return (PyObject *)result;
2037 * This is a *class method*.
2038 * Convert a parameter into something that ConvParam can handle.
2040 static PyObject *
2041 PyCSimpleType_from_param(PyObject *type, PyObject *value)
2043 StgDictObject *dict;
2044 char *fmt;
2045 PyCArgObject *parg;
2046 struct fielddesc *fd;
2047 PyObject *as_parameter;
2049 /* If the value is already an instance of the requested type,
2050 we can use it as is */
2051 if (1 == PyObject_IsInstance(value, type)) {
2052 Py_INCREF(value);
2053 return value;
2056 dict = PyType_stgdict(type);
2057 assert(dict);
2059 /* I think we can rely on this being a one-character string */
2060 fmt = PyString_AsString(dict->proto);
2061 assert(fmt);
2063 fd = _ctypes_get_fielddesc(fmt);
2064 assert(fd);
2066 parg = PyCArgObject_new();
2067 if (parg == NULL)
2068 return NULL;
2070 parg->tag = fmt[0];
2071 parg->pffi_type = fd->pffi_type;
2072 parg->obj = fd->setfunc(&parg->value, value, 0);
2073 if (parg->obj)
2074 return (PyObject *)parg;
2075 PyErr_Clear();
2076 Py_DECREF(parg);
2078 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
2079 if (as_parameter) {
2080 value = PyCSimpleType_from_param(type, as_parameter);
2081 Py_DECREF(as_parameter);
2082 return value;
2084 PyErr_SetString(PyExc_TypeError,
2085 "wrong type");
2086 return NULL;
2089 static PyMethodDef PyCSimpleType_methods[] = {
2090 { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc },
2091 { "from_address", CDataType_from_address, METH_O, from_address_doc },
2092 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
2093 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
2094 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
2095 { NULL, NULL },
2098 PyTypeObject PyCSimpleType_Type = {
2099 PyVarObject_HEAD_INIT(NULL, 0)
2100 "_ctypes.PyCSimpleType", /* tp_name */
2101 0, /* tp_basicsize */
2102 0, /* tp_itemsize */
2103 0, /* tp_dealloc */
2104 0, /* tp_print */
2105 0, /* tp_getattr */
2106 0, /* tp_setattr */
2107 0, /* tp_compare */
2108 0, /* tp_repr */
2109 0, /* tp_as_number */
2110 &CDataType_as_sequence, /* tp_as_sequence */
2111 0, /* tp_as_mapping */
2112 0, /* tp_hash */
2113 0, /* tp_call */
2114 0, /* tp_str */
2115 0, /* tp_getattro */
2116 0, /* tp_setattro */
2117 0, /* tp_as_buffer */
2118 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2119 "metatype for the PyCSimpleType Objects", /* tp_doc */
2120 0, /* tp_traverse */
2121 0, /* tp_clear */
2122 0, /* tp_richcompare */
2123 0, /* tp_weaklistoffset */
2124 0, /* tp_iter */
2125 0, /* tp_iternext */
2126 PyCSimpleType_methods, /* tp_methods */
2127 0, /* tp_members */
2128 0, /* tp_getset */
2129 0, /* tp_base */
2130 0, /* tp_dict */
2131 0, /* tp_descr_get */
2132 0, /* tp_descr_set */
2133 0, /* tp_dictoffset */
2134 0, /* tp_init */
2135 0, /* tp_alloc */
2136 PyCSimpleType_new, /* tp_new */
2137 0, /* tp_free */
2140 /******************************************************************/
2142 PyCFuncPtrType_Type
2145 static PyObject *
2146 converters_from_argtypes(PyObject *ob)
2148 PyObject *converters;
2149 Py_ssize_t i;
2150 Py_ssize_t nArgs;
2152 ob = PySequence_Tuple(ob); /* new reference */
2153 if (!ob) {
2154 PyErr_SetString(PyExc_TypeError,
2155 "_argtypes_ must be a sequence of types");
2156 return NULL;
2159 nArgs = PyTuple_GET_SIZE(ob);
2160 converters = PyTuple_New(nArgs);
2161 if (!converters)
2162 return NULL;
2164 /* I have to check if this is correct. Using c_char, which has a size
2165 of 1, will be assumed to be pushed as only one byte!
2166 Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
2169 for (i = 0; i < nArgs; ++i) {
2170 PyObject *tp = PyTuple_GET_ITEM(ob, i);
2171 PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
2172 if (!cnv)
2173 goto argtypes_error_1;
2174 PyTuple_SET_ITEM(converters, i, cnv);
2176 Py_DECREF(ob);
2177 return converters;
2179 argtypes_error_1:
2180 Py_XDECREF(converters);
2181 Py_DECREF(ob);
2182 PyErr_Format(PyExc_TypeError,
2183 #if (PY_VERSION_HEX < 0x02050000)
2184 "item %d in _argtypes_ has no from_param method",
2185 #else
2186 "item %zd in _argtypes_ has no from_param method",
2187 #endif
2188 i+1);
2189 return NULL;
2192 static int
2193 make_funcptrtype_dict(StgDictObject *stgdict)
2195 PyObject *ob;
2196 PyObject *converters = NULL;
2198 stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
2199 stgdict->length = 1;
2200 stgdict->size = sizeof(void *);
2201 stgdict->setfunc = NULL;
2202 stgdict->getfunc = NULL;
2203 stgdict->ffi_type_pointer = ffi_type_pointer;
2205 ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
2206 if (!ob || !PyInt_Check(ob)) {
2207 PyErr_SetString(PyExc_TypeError,
2208 "class must define _flags_ which must be an integer");
2209 return -1;
2211 stgdict->flags = PyInt_AS_LONG(ob) | TYPEFLAG_ISPOINTER;
2213 /* _argtypes_ is optional... */
2214 ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
2215 if (ob) {
2216 converters = converters_from_argtypes(ob);
2217 if (!converters)
2218 goto error;
2219 Py_INCREF(ob);
2220 stgdict->argtypes = ob;
2221 stgdict->converters = converters;
2224 ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
2225 if (ob) {
2226 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2227 PyErr_SetString(PyExc_TypeError,
2228 "_restype_ must be a type, a callable, or None");
2229 return -1;
2231 Py_INCREF(ob);
2232 stgdict->restype = ob;
2233 stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
2234 if (stgdict->checker == NULL)
2235 PyErr_Clear();
2237 /* XXX later, maybe.
2238 ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
2239 if (ob) {
2240 if (!PyCallable_Check(ob)) {
2241 PyErr_SetString(PyExc_TypeError,
2242 "_errcheck_ must be callable");
2243 return -1;
2245 Py_INCREF(ob);
2246 stgdict->errcheck = ob;
2249 return 0;
2251 error:
2252 Py_XDECREF(converters);
2253 return -1;
2257 static PyCArgObject *
2258 PyCFuncPtrType_paramfunc(CDataObject *self)
2260 PyCArgObject *parg;
2262 parg = PyCArgObject_new();
2263 if (parg == NULL)
2264 return NULL;
2266 parg->tag = 'P';
2267 parg->pffi_type = &ffi_type_pointer;
2268 Py_INCREF(self);
2269 parg->obj = (PyObject *)self;
2270 parg->value.p = *(void **)self->b_ptr;
2271 return parg;
2274 static PyObject *
2275 PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2277 PyTypeObject *result;
2278 StgDictObject *stgdict;
2280 stgdict = (StgDictObject *)PyObject_CallObject(
2281 (PyObject *)&PyCStgDict_Type, NULL);
2282 if (!stgdict)
2283 return NULL;
2285 stgdict->paramfunc = PyCFuncPtrType_paramfunc;
2286 /* We do NOT expose the function signature in the format string. It
2287 is impossible, generally, because the only requirement for the
2288 argtypes items is that they have a .from_param method - we do not
2289 know the types of the arguments (although, in practice, most
2290 argtypes would be a ctypes type).
2292 stgdict->format = _ctypes_alloc_format_string(NULL, "X{}");
2293 stgdict->flags |= TYPEFLAG_ISPOINTER;
2295 /* create the new instance (which is a class,
2296 since we are a metatype!) */
2297 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2298 if (result == NULL) {
2299 Py_DECREF((PyObject *)stgdict);
2300 return NULL;
2303 /* replace the class dict by our updated storage dict */
2304 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2305 Py_DECREF(result);
2306 Py_DECREF((PyObject *)stgdict);
2307 return NULL;
2309 Py_DECREF(result->tp_dict);
2310 result->tp_dict = (PyObject *)stgdict;
2312 if (-1 == make_funcptrtype_dict(stgdict)) {
2313 Py_DECREF(result);
2314 return NULL;
2317 return (PyObject *)result;
2320 PyTypeObject PyCFuncPtrType_Type = {
2321 PyVarObject_HEAD_INIT(NULL, 0)
2322 "_ctypes.PyCFuncPtrType", /* tp_name */
2323 0, /* tp_basicsize */
2324 0, /* tp_itemsize */
2325 0, /* tp_dealloc */
2326 0, /* tp_print */
2327 0, /* tp_getattr */
2328 0, /* tp_setattr */
2329 0, /* tp_compare */
2330 0, /* tp_repr */
2331 0, /* tp_as_number */
2332 &CDataType_as_sequence, /* tp_as_sequence */
2333 0, /* tp_as_mapping */
2334 0, /* tp_hash */
2335 0, /* tp_call */
2336 0, /* tp_str */
2337 0, /* tp_getattro */
2338 0, /* tp_setattro */
2339 0, /* tp_as_buffer */
2340 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2341 "metatype for C function pointers", /* tp_doc */
2342 (traverseproc)CDataType_traverse, /* tp_traverse */
2343 (inquiry)CDataType_clear, /* tp_clear */
2344 0, /* tp_richcompare */
2345 0, /* tp_weaklistoffset */
2346 0, /* tp_iter */
2347 0, /* tp_iternext */
2348 CDataType_methods, /* tp_methods */
2349 0, /* tp_members */
2350 0, /* tp_getset */
2351 0, /* tp_base */
2352 0, /* tp_dict */
2353 0, /* tp_descr_get */
2354 0, /* tp_descr_set */
2355 0, /* tp_dictoffset */
2356 0, /* tp_init */
2357 0, /* tp_alloc */
2358 PyCFuncPtrType_new, /* tp_new */
2359 0, /* tp_free */
2363 /*****************************************************************
2364 * Code to keep needed objects alive
2367 static CDataObject *
2368 PyCData_GetContainer(CDataObject *self)
2370 while (self->b_base)
2371 self = self->b_base;
2372 if (self->b_objects == NULL) {
2373 if (self->b_length) {
2374 self->b_objects = PyDict_New();
2375 } else {
2376 Py_INCREF(Py_None);
2377 self->b_objects = Py_None;
2380 return self;
2383 static PyObject *
2384 GetKeepedObjects(CDataObject *target)
2386 return PyCData_GetContainer(target)->b_objects;
2389 static PyObject *
2390 unique_key(CDataObject *target, Py_ssize_t index)
2392 char string[256];
2393 char *cp = string;
2394 size_t bytes_left;
2396 assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
2397 #if (PY_VERSION_HEX < 0x02050000)
2398 cp += sprintf(cp, "%x", index);
2399 #else
2400 cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2401 #endif
2402 while (target->b_base) {
2403 bytes_left = sizeof(string) - (cp - string) - 1;
2404 /* Hex format needs 2 characters per byte */
2405 if (bytes_left < sizeof(Py_ssize_t) * 2) {
2406 PyErr_SetString(PyExc_ValueError,
2407 "ctypes object structure too deep");
2408 return NULL;
2410 #if (PY_VERSION_HEX < 0x02050000)
2411 cp += sprintf(cp, ":%x", (int)target->b_index);
2412 #else
2413 cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
2414 #endif
2415 target = target->b_base;
2417 return PyString_FromStringAndSize(string, cp-string);
2421 * Keep a reference to 'keep' in the 'target', at index 'index'.
2423 * If 'keep' is None, do nothing.
2425 * Otherwise create a dictionary (if it does not yet exist) id the root
2426 * objects 'b_objects' item, which will store the 'keep' object under a unique
2427 * key.
2429 * The unique_key helper travels the target's b_base pointer down to the root,
2430 * building a string containing hex-formatted indexes found during traversal,
2431 * separated by colons.
2433 * The index tuple is used as a key into the root object's b_objects dict.
2435 * Note: This function steals a refcount of the third argument, even if it
2436 * fails!
2438 static int
2439 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
2441 int result;
2442 CDataObject *ob;
2443 PyObject *key;
2445 /* Optimization: no need to store None */
2446 if (keep == Py_None) {
2447 Py_DECREF(Py_None);
2448 return 0;
2450 ob = PyCData_GetContainer(target);
2451 if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
2452 Py_XDECREF(ob->b_objects);
2453 ob->b_objects = keep; /* refcount consumed */
2454 return 0;
2456 key = unique_key(target, index);
2457 if (key == NULL) {
2458 Py_DECREF(keep);
2459 return -1;
2461 result = PyDict_SetItem(ob->b_objects, key, keep);
2462 Py_DECREF(key);
2463 Py_DECREF(keep);
2464 return result;
2467 /******************************************************************/
2469 PyCData_Type
2471 static int
2472 PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
2474 Py_VISIT(self->b_objects);
2475 Py_VISIT((PyObject *)self->b_base);
2476 return 0;
2479 static int
2480 PyCData_clear(CDataObject *self)
2482 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
2483 assert(dict); /* Cannot be NULL for CDataObject instances */
2484 Py_CLEAR(self->b_objects);
2485 if ((self->b_needsfree)
2486 && ((size_t)dict->size > sizeof(self->b_value)))
2487 PyMem_Free(self->b_ptr);
2488 self->b_ptr = NULL;
2489 Py_CLEAR(self->b_base);
2490 return 0;
2493 static void
2494 PyCData_dealloc(PyObject *self)
2496 PyCData_clear((CDataObject *)self);
2497 Py_TYPE(self)->tp_free(self);
2500 static PyMemberDef PyCData_members[] = {
2501 { "_b_base_", T_OBJECT,
2502 offsetof(CDataObject, b_base), READONLY,
2503 "the base object" },
2504 { "_b_needsfree_", T_INT,
2505 offsetof(CDataObject, b_needsfree), READONLY,
2506 "whether the object owns the memory or not" },
2507 { "_objects", T_OBJECT,
2508 offsetof(CDataObject, b_objects), READONLY,
2509 "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2510 { NULL },
2513 #if (PY_VERSION_HEX >= 0x02060000)
2514 static int PyCData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags)
2516 CDataObject *self = (CDataObject *)_self;
2517 StgDictObject *dict = PyObject_stgdict(_self);
2518 Py_ssize_t i;
2520 if (view == NULL) return 0;
2522 view->buf = self->b_ptr;
2523 view->obj = _self;
2524 Py_INCREF(_self);
2525 view->len = self->b_size;
2526 view->readonly = 0;
2527 /* use default format character if not set */
2528 view->format = dict->format ? dict->format : "B";
2529 view->ndim = dict->ndim;
2530 view->shape = dict->shape;
2531 view->itemsize = self->b_size;
2532 for (i = 0; i < view->ndim; ++i) {
2533 view->itemsize /= dict->shape[i];
2535 view->strides = NULL;
2536 view->suboffsets = NULL;
2537 view->internal = NULL;
2538 return 0;
2540 #endif
2542 static Py_ssize_t PyCData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
2544 if (lenp)
2545 *lenp = 1;
2546 return 1;
2549 static Py_ssize_t PyCData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr)
2551 CDataObject *self = (CDataObject *)_self;
2552 if (seg != 0) {
2553 /* Hm. Must this set an exception? */
2554 return -1;
2556 *pptr = self->b_ptr;
2557 return self->b_size;
2560 static PyBufferProcs PyCData_as_buffer = {
2561 (readbufferproc)PyCData_GetBuffer,
2562 (writebufferproc)PyCData_GetBuffer,
2563 (segcountproc)PyCData_GetSegcount,
2564 (charbufferproc)NULL,
2565 #if (PY_VERSION_HEX >= 0x02060000)
2566 (getbufferproc)PyCData_NewGetBuffer,
2567 (releasebufferproc)NULL,
2568 #endif
2572 * CData objects are mutable, so they cannot be hashable!
2574 static long
2575 PyCData_nohash(PyObject *self)
2577 PyErr_SetString(PyExc_TypeError, "unhashable type");
2578 return -1;
2581 static PyObject *
2582 PyCData_reduce(PyObject *_self, PyObject *args)
2584 CDataObject *self = (CDataObject *)_self;
2586 if (PyObject_stgdict(_self)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
2587 PyErr_SetString(PyExc_ValueError,
2588 "ctypes objects containing pointers cannot be pickled");
2589 return NULL;
2591 return Py_BuildValue("O(O(NN))",
2592 _unpickle,
2593 Py_TYPE(_self),
2594 PyObject_GetAttrString(_self, "__dict__"),
2595 PyString_FromStringAndSize(self->b_ptr, self->b_size));
2598 static PyObject *
2599 PyCData_setstate(PyObject *_self, PyObject *args)
2601 void *data;
2602 Py_ssize_t len;
2603 int res;
2604 PyObject *dict, *mydict;
2605 CDataObject *self = (CDataObject *)_self;
2606 if (!PyArg_ParseTuple(args, "Os#", &dict, &data, &len))
2607 return NULL;
2608 if (len > self->b_size)
2609 len = self->b_size;
2610 memmove(self->b_ptr, data, len);
2611 mydict = PyObject_GetAttrString(_self, "__dict__");
2612 res = PyDict_Update(mydict, dict);
2613 Py_DECREF(mydict);
2614 if (res == -1)
2615 return NULL;
2616 Py_INCREF(Py_None);
2617 return Py_None;
2621 * default __ctypes_from_outparam__ method returns self.
2623 static PyObject *
2624 PyCData_from_outparam(PyObject *self, PyObject *args)
2626 Py_INCREF(self);
2627 return self;
2630 static PyMethodDef PyCData_methods[] = {
2631 { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
2632 { "__reduce__", PyCData_reduce, METH_NOARGS, },
2633 { "__setstate__", PyCData_setstate, METH_VARARGS, },
2634 { NULL, NULL },
2637 PyTypeObject PyCData_Type = {
2638 PyVarObject_HEAD_INIT(NULL, 0)
2639 "_ctypes._CData",
2640 sizeof(CDataObject), /* tp_basicsize */
2641 0, /* tp_itemsize */
2642 PyCData_dealloc, /* tp_dealloc */
2643 0, /* tp_print */
2644 0, /* tp_getattr */
2645 0, /* tp_setattr */
2646 0, /* tp_compare */
2647 0, /* tp_repr */
2648 0, /* tp_as_number */
2649 0, /* tp_as_sequence */
2650 0, /* tp_as_mapping */
2651 PyCData_nohash, /* tp_hash */
2652 0, /* tp_call */
2653 0, /* tp_str */
2654 0, /* tp_getattro */
2655 0, /* tp_setattro */
2656 &PyCData_as_buffer, /* tp_as_buffer */
2657 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
2658 "XXX to be provided", /* tp_doc */
2659 (traverseproc)PyCData_traverse, /* tp_traverse */
2660 (inquiry)PyCData_clear, /* tp_clear */
2661 0, /* tp_richcompare */
2662 0, /* tp_weaklistoffset */
2663 0, /* tp_iter */
2664 0, /* tp_iternext */
2665 PyCData_methods, /* tp_methods */
2666 PyCData_members, /* tp_members */
2667 0, /* tp_getset */
2668 0, /* tp_base */
2669 0, /* tp_dict */
2670 0, /* tp_descr_get */
2671 0, /* tp_descr_set */
2672 0, /* tp_dictoffset */
2673 0, /* tp_init */
2674 0, /* tp_alloc */
2675 0, /* tp_new */
2676 0, /* tp_free */
2679 static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
2681 if ((size_t)dict->size <= sizeof(obj->b_value)) {
2682 /* No need to call malloc, can use the default buffer */
2683 obj->b_ptr = (char *)&obj->b_value;
2684 /* The b_needsfree flag does not mean that we actually did
2685 call PyMem_Malloc to allocate the memory block; instead it
2686 means we are the *owner* of the memory and are responsible
2687 for freeing resources associated with the memory. This is
2688 also the reason that b_needsfree is exposed to Python.
2690 obj->b_needsfree = 1;
2691 } else {
2692 /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2693 33% of the creation time for c_int().
2695 obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2696 if (obj->b_ptr == NULL) {
2697 PyErr_NoMemory();
2698 return -1;
2700 obj->b_needsfree = 1;
2701 memset(obj->b_ptr, 0, dict->size);
2703 obj->b_size = dict->size;
2704 return 0;
2707 PyObject *
2708 PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
2710 CDataObject *cmem;
2711 StgDictObject *dict;
2713 assert(PyType_Check(type));
2714 dict = PyType_stgdict(type);
2715 if (!dict) {
2716 PyErr_SetString(PyExc_TypeError,
2717 "abstract class");
2718 return NULL;
2720 dict->flags |= DICTFLAG_FINAL;
2721 cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2722 if (cmem == NULL)
2723 return NULL;
2724 assert(CDataObject_Check(cmem));
2726 cmem->b_length = dict->length;
2727 cmem->b_size = dict->size;
2728 if (base) { /* use base's buffer */
2729 assert(CDataObject_Check(base));
2730 cmem->b_ptr = adr;
2731 cmem->b_needsfree = 0;
2732 Py_INCREF(base);
2733 cmem->b_base = (CDataObject *)base;
2734 cmem->b_index = index;
2735 } else { /* copy contents of adr */
2736 if (-1 == PyCData_MallocBuffer(cmem, dict)) {
2737 return NULL;
2738 Py_DECREF(cmem);
2740 memcpy(cmem->b_ptr, adr, dict->size);
2741 cmem->b_index = index;
2743 return (PyObject *)cmem;
2747 Box a memory block into a CData instance.
2749 PyObject *
2750 PyCData_AtAddress(PyObject *type, void *buf)
2752 CDataObject *pd;
2753 StgDictObject *dict;
2755 assert(PyType_Check(type));
2756 dict = PyType_stgdict(type);
2757 if (!dict) {
2758 PyErr_SetString(PyExc_TypeError,
2759 "abstract class");
2760 return NULL;
2762 dict->flags |= DICTFLAG_FINAL;
2764 pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2765 if (!pd)
2766 return NULL;
2767 assert(CDataObject_Check(pd));
2768 pd->b_ptr = (char *)buf;
2769 pd->b_length = dict->length;
2770 pd->b_size = dict->size;
2771 return (PyObject *)pd;
2775 This function returns TRUE for c_int, c_void_p, and these kind of
2776 classes. FALSE otherwise FALSE also for subclasses of c_int and
2777 such.
2779 int _ctypes_simple_instance(PyObject *obj)
2781 PyTypeObject *type = (PyTypeObject *)obj;
2783 if (PyCSimpleTypeObject_Check(type))
2784 return type->tp_base != &Simple_Type;
2785 return 0;
2788 PyObject *
2789 PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
2790 Py_ssize_t index, Py_ssize_t size, char *adr)
2792 StgDictObject *dict;
2793 if (getfunc)
2794 return getfunc(adr, size);
2795 assert(type);
2796 dict = PyType_stgdict(type);
2797 if (dict && dict->getfunc && !_ctypes_simple_instance(type))
2798 return dict->getfunc(adr, size);
2799 return PyCData_FromBaseObj(type, src, index, adr);
2803 Helper function for PyCData_set below.
2805 static PyObject *
2806 _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2807 Py_ssize_t size, char *ptr)
2809 CDataObject *src;
2811 if (setfunc)
2812 return setfunc(ptr, value, size);
2814 if (!CDataObject_Check(value)) {
2815 StgDictObject *dict = PyType_stgdict(type);
2816 if (dict && dict->setfunc)
2817 return dict->setfunc(ptr, value, size);
2819 If value is a tuple, we try to call the type with the tuple
2820 and use the result!
2822 assert(PyType_Check(type));
2823 if (PyTuple_Check(value)) {
2824 PyObject *ob;
2825 PyObject *result;
2826 ob = PyObject_CallObject(type, value);
2827 if (ob == NULL) {
2828 _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
2829 ((PyTypeObject *)type)->tp_name);
2830 return NULL;
2832 result = _PyCData_set(dst, type, setfunc, ob,
2833 size, ptr);
2834 Py_DECREF(ob);
2835 return result;
2836 } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
2837 *(void **)ptr = NULL;
2838 Py_INCREF(Py_None);
2839 return Py_None;
2840 } else {
2841 PyErr_Format(PyExc_TypeError,
2842 "expected %s instance, got %s",
2843 ((PyTypeObject *)type)->tp_name,
2844 Py_TYPE(value)->tp_name);
2845 return NULL;
2848 src = (CDataObject *)value;
2850 if (PyObject_IsInstance(value, type)) {
2851 memcpy(ptr,
2852 src->b_ptr,
2853 size);
2855 if (PyCPointerTypeObject_Check(type))
2856 /* XXX */;
2858 value = GetKeepedObjects(src);
2859 Py_INCREF(value);
2860 return value;
2863 if (PyCPointerTypeObject_Check(type)
2864 && ArrayObject_Check(value)) {
2865 StgDictObject *p1, *p2;
2866 PyObject *keep;
2867 p1 = PyObject_stgdict(value);
2868 assert(p1); /* Cannot be NULL for array instances */
2869 p2 = PyType_stgdict(type);
2870 assert(p2); /* Cannot be NULL for pointer types */
2872 if (p1->proto != p2->proto) {
2873 PyErr_Format(PyExc_TypeError,
2874 "incompatible types, %s instance instead of %s instance",
2875 Py_TYPE(value)->tp_name,
2876 ((PyTypeObject *)type)->tp_name);
2877 return NULL;
2879 *(void **)ptr = src->b_ptr;
2881 keep = GetKeepedObjects(src);
2883 We are assigning an array object to a field which represents
2884 a pointer. This has the same effect as converting an array
2885 into a pointer. So, again, we have to keep the whole object
2886 pointed to (which is the array in this case) alive, and not
2887 only it's object list. So we create a tuple, containing
2888 b_objects list PLUS the array itself, and return that!
2890 return PyTuple_Pack(2, keep, value);
2892 PyErr_Format(PyExc_TypeError,
2893 "incompatible types, %s instance instead of %s instance",
2894 Py_TYPE(value)->tp_name,
2895 ((PyTypeObject *)type)->tp_name);
2896 return NULL;
2900 * Set a slice in object 'dst', which has the type 'type',
2901 * to the value 'value'.
2904 PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2905 Py_ssize_t index, Py_ssize_t size, char *ptr)
2907 CDataObject *mem = (CDataObject *)dst;
2908 PyObject *result;
2910 if (!CDataObject_Check(dst)) {
2911 PyErr_SetString(PyExc_TypeError,
2912 "not a ctype instance");
2913 return -1;
2916 result = _PyCData_set(mem, type, setfunc, value,
2917 size, ptr);
2918 if (result == NULL)
2919 return -1;
2921 /* KeepRef steals a refcount from it's last argument */
2922 /* If KeepRef fails, we are stumped. The dst memory block has already
2923 been changed */
2924 return KeepRef(mem, index, result);
2928 /******************************************************************/
2929 static PyObject *
2930 GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2932 CDataObject *obj;
2933 StgDictObject *dict;
2935 dict = PyType_stgdict((PyObject *)type);
2936 if (!dict) {
2937 PyErr_SetString(PyExc_TypeError,
2938 "abstract class");
2939 return NULL;
2941 dict->flags |= DICTFLAG_FINAL;
2943 obj = (CDataObject *)type->tp_alloc(type, 0);
2944 if (!obj)
2945 return NULL;
2947 obj->b_base = NULL;
2948 obj->b_index = 0;
2949 obj->b_objects = NULL;
2950 obj->b_length = dict->length;
2952 if (-1 == PyCData_MallocBuffer(obj, dict)) {
2953 Py_DECREF(obj);
2954 return NULL;
2956 return (PyObject *)obj;
2958 /*****************************************************************/
2960 PyCFuncPtr_Type
2963 static int
2964 PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob)
2966 if (ob && !PyCallable_Check(ob)) {
2967 PyErr_SetString(PyExc_TypeError,
2968 "the errcheck attribute must be callable");
2969 return -1;
2971 Py_XDECREF(self->errcheck);
2972 Py_XINCREF(ob);
2973 self->errcheck = ob;
2974 return 0;
2977 static PyObject *
2978 PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self)
2980 if (self->errcheck) {
2981 Py_INCREF(self->errcheck);
2982 return self->errcheck;
2984 Py_INCREF(Py_None);
2985 return Py_None;
2988 static int
2989 PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob)
2991 if (ob == NULL) {
2992 Py_XDECREF(self->restype);
2993 self->restype = NULL;
2994 Py_XDECREF(self->checker);
2995 self->checker = NULL;
2996 return 0;
2998 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2999 PyErr_SetString(PyExc_TypeError,
3000 "restype must be a type, a callable, or None");
3001 return -1;
3003 Py_XDECREF(self->checker);
3004 Py_XDECREF(self->restype);
3005 Py_INCREF(ob);
3006 self->restype = ob;
3007 self->checker = PyObject_GetAttrString(ob, "_check_retval_");
3008 if (self->checker == NULL)
3009 PyErr_Clear();
3010 return 0;
3013 static PyObject *
3014 PyCFuncPtr_get_restype(PyCFuncPtrObject *self)
3016 StgDictObject *dict;
3017 if (self->restype) {
3018 Py_INCREF(self->restype);
3019 return self->restype;
3021 dict = PyObject_stgdict((PyObject *)self);
3022 assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3023 if (dict->restype) {
3024 Py_INCREF(dict->restype);
3025 return dict->restype;
3026 } else {
3027 Py_INCREF(Py_None);
3028 return Py_None;
3032 static int
3033 PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob)
3035 PyObject *converters;
3037 if (ob == NULL || ob == Py_None) {
3038 Py_XDECREF(self->converters);
3039 self->converters = NULL;
3040 Py_XDECREF(self->argtypes);
3041 self->argtypes = NULL;
3042 } else {
3043 converters = converters_from_argtypes(ob);
3044 if (!converters)
3045 return -1;
3046 Py_XDECREF(self->converters);
3047 self->converters = converters;
3048 Py_XDECREF(self->argtypes);
3049 Py_INCREF(ob);
3050 self->argtypes = ob;
3052 return 0;
3055 static PyObject *
3056 PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self)
3058 StgDictObject *dict;
3059 if (self->argtypes) {
3060 Py_INCREF(self->argtypes);
3061 return self->argtypes;
3063 dict = PyObject_stgdict((PyObject *)self);
3064 assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3065 if (dict->argtypes) {
3066 Py_INCREF(dict->argtypes);
3067 return dict->argtypes;
3068 } else {
3069 Py_INCREF(Py_None);
3070 return Py_None;
3074 static PyGetSetDef PyCFuncPtr_getsets[] = {
3075 { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
3076 "a function to check for errors", NULL },
3077 { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
3078 "specify the result type", NULL },
3079 { "argtypes", (getter)PyCFuncPtr_get_argtypes,
3080 (setter)PyCFuncPtr_set_argtypes,
3081 "specify the argument types", NULL },
3082 { NULL, NULL }
3085 #ifdef MS_WIN32
3086 static PPROC FindAddress(void *handle, char *name, PyObject *type)
3088 #ifdef MS_WIN64
3089 /* win64 has no stdcall calling conv, so it should
3090 also not have the name mangling of it.
3092 return (PPROC)GetProcAddress(handle, name);
3093 #else
3094 PPROC address;
3095 char *mangled_name;
3096 int i;
3097 StgDictObject *dict;
3099 address = (PPROC)GetProcAddress(handle, name);
3100 if (address)
3101 return address;
3102 if (((size_t)name & ~0xFFFF) == 0) {
3103 return NULL;
3106 dict = PyType_stgdict((PyObject *)type);
3107 /* It should not happen that dict is NULL, but better be safe */
3108 if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
3109 return address;
3111 /* for stdcall, try mangled names:
3112 funcname -> _funcname@<n>
3113 where n is 0, 4, 8, 12, ..., 128
3115 mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
3116 if (!mangled_name)
3117 return NULL;
3118 for (i = 0; i < 32; ++i) {
3119 sprintf(mangled_name, "_%s@%d", name, i*4);
3120 address = (PPROC)GetProcAddress(handle, mangled_name);
3121 if (address)
3122 return address;
3124 return NULL;
3125 #endif
3127 #endif
3129 /* Return 1 if usable, 0 else and exception set. */
3130 static int
3131 _check_outarg_type(PyObject *arg, Py_ssize_t index)
3133 StgDictObject *dict;
3135 if (PyCPointerTypeObject_Check(arg))
3136 return 1;
3138 if (PyCArrayTypeObject_Check(arg))
3139 return 1;
3141 dict = PyType_stgdict(arg);
3142 if (dict
3143 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
3144 && PyString_Check(dict->proto)
3145 /* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
3146 && (strchr("PzZ", PyString_AS_STRING(dict->proto)[0]))) {
3147 return 1;
3150 PyErr_Format(PyExc_TypeError,
3151 "'out' parameter %d must be a pointer type, not %s",
3152 Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
3153 PyType_Check(arg) ?
3154 ((PyTypeObject *)arg)->tp_name :
3155 Py_TYPE(arg)->tp_name);
3156 return 0;
3159 /* Returns 1 on success, 0 on error */
3160 static int
3161 _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
3163 Py_ssize_t i, len;
3164 StgDictObject *dict;
3165 PyObject *argtypes;
3167 dict = PyType_stgdict((PyObject *)type);
3168 assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */
3169 argtypes = dict->argtypes;
3171 if (paramflags == NULL || dict->argtypes == NULL)
3172 return 1;
3174 if (!PyTuple_Check(paramflags)) {
3175 PyErr_SetString(PyExc_TypeError,
3176 "paramflags must be a tuple or None");
3177 return 0;
3180 len = PyTuple_GET_SIZE(paramflags);
3181 if (len != PyTuple_GET_SIZE(dict->argtypes)) {
3182 PyErr_SetString(PyExc_ValueError,
3183 "paramflags must have the same length as argtypes");
3184 return 0;
3187 for (i = 0; i < len; ++i) {
3188 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3189 int flag;
3190 char *name;
3191 PyObject *defval;
3192 PyObject *typ;
3193 if (!PyArg_ParseTuple(item, "i|zO", &flag, &name, &defval)) {
3194 PyErr_SetString(PyExc_TypeError,
3195 "paramflags must be a sequence of (int [,string [,value]]) tuples");
3196 return 0;
3198 typ = PyTuple_GET_ITEM(argtypes, i);
3199 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3200 case 0:
3201 case PARAMFLAG_FIN:
3202 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3203 case PARAMFLAG_FIN | PARAMFLAG_FOUT:
3204 break;
3205 case PARAMFLAG_FOUT:
3206 if (!_check_outarg_type(typ, i+1))
3207 return 0;
3208 break;
3209 default:
3210 PyErr_Format(PyExc_TypeError,
3211 "paramflag value %d not supported",
3212 flag);
3213 return 0;
3216 return 1;
3219 static int
3220 _get_name(PyObject *obj, char **pname)
3222 #ifdef MS_WIN32
3223 if (PyInt_Check(obj) || PyLong_Check(obj)) {
3224 /* We have to use MAKEINTRESOURCEA for Windows CE.
3225 Works on Windows as well, of course.
3227 *pname = MAKEINTRESOURCEA(PyInt_AsUnsignedLongMask(obj) & 0xFFFF);
3228 return 1;
3230 #endif
3231 if (PyString_Check(obj) || PyUnicode_Check(obj)) {
3232 *pname = PyString_AsString(obj);
3233 return *pname ? 1 : 0;
3235 PyErr_SetString(PyExc_TypeError,
3236 "function name must be string or integer");
3237 return 0;
3241 static PyObject *
3242 PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
3244 char *name;
3245 int (* address)(void);
3246 PyObject *dll;
3247 PyObject *obj;
3248 PyCFuncPtrObject *self;
3249 void *handle;
3250 PyObject *paramflags = NULL;
3252 if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
3253 return NULL;
3254 if (paramflags == Py_None)
3255 paramflags = NULL;
3257 obj = PyObject_GetAttrString(dll, "_handle");
3258 if (!obj)
3259 return NULL;
3260 if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
3261 PyErr_SetString(PyExc_TypeError,
3262 "the _handle attribute of the second argument must be an integer");
3263 Py_DECREF(obj);
3264 return NULL;
3266 handle = (void *)PyLong_AsVoidPtr(obj);
3267 Py_DECREF(obj);
3268 if (PyErr_Occurred()) {
3269 PyErr_SetString(PyExc_ValueError,
3270 "could not convert the _handle attribute to a pointer");
3271 return NULL;
3274 #ifdef MS_WIN32
3275 address = FindAddress(handle, name, (PyObject *)type);
3276 if (!address) {
3277 if (!IS_INTRESOURCE(name))
3278 PyErr_Format(PyExc_AttributeError,
3279 "function '%s' not found",
3280 name);
3281 else
3282 PyErr_Format(PyExc_AttributeError,
3283 "function ordinal %d not found",
3284 (WORD)(size_t)name);
3285 return NULL;
3287 #else
3288 address = (PPROC)ctypes_dlsym(handle, name);
3289 if (!address) {
3290 #ifdef __CYGWIN__
3291 /* dlerror() isn't very helpful on cygwin */
3292 PyErr_Format(PyExc_AttributeError,
3293 "function '%s' not found (%s) ",
3294 name);
3295 #else
3296 PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
3297 #endif
3298 return NULL;
3300 #endif
3301 if (!_validate_paramflags(type, paramflags))
3302 return NULL;
3304 self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3305 if (!self)
3306 return NULL;
3308 Py_XINCREF(paramflags);
3309 self->paramflags = paramflags;
3311 *(void **)self->b_ptr = address;
3313 Py_INCREF((PyObject *)dll); /* for KeepRef */
3314 if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
3315 Py_DECREF((PyObject *)self);
3316 return NULL;
3319 Py_INCREF(self);
3320 self->callable = (PyObject *)self;
3321 return (PyObject *)self;
3324 #ifdef MS_WIN32
3325 static PyObject *
3326 PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
3328 PyCFuncPtrObject *self;
3329 int index;
3330 char *name = NULL;
3331 PyObject *paramflags = NULL;
3332 GUID *iid = NULL;
3333 Py_ssize_t iid_len = 0;
3335 if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
3336 return NULL;
3337 if (paramflags == Py_None)
3338 paramflags = NULL;
3340 if (!_validate_paramflags(type, paramflags))
3341 return NULL;
3343 self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3344 self->index = index + 0x1000;
3345 Py_XINCREF(paramflags);
3346 self->paramflags = paramflags;
3347 if (iid_len == sizeof(GUID))
3348 self->iid = iid;
3349 return (PyObject *)self;
3351 #endif
3354 PyCFuncPtr_new accepts different argument lists in addition to the standard
3355 _basespec_ keyword arg:
3357 one argument form
3358 "i" - function address
3359 "O" - must be a callable, creates a C callable function
3361 two or more argument forms (the third argument is a paramflags tuple)
3362 "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
3363 "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
3364 "is|..." - vtable index, method name, creates callable calling COM vtbl
3366 static PyObject *
3367 PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3369 PyCFuncPtrObject *self;
3370 PyObject *callable;
3371 StgDictObject *dict;
3372 CThunkObject *thunk;
3374 if (PyTuple_GET_SIZE(args) == 0)
3375 return GenericPyCData_new(type, args, kwds);
3377 if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
3378 return PyCFuncPtr_FromDll(type, args, kwds);
3380 #ifdef MS_WIN32
3381 if (2 <= PyTuple_GET_SIZE(args) && PyInt_Check(PyTuple_GET_ITEM(args, 0)))
3382 return PyCFuncPtr_FromVtblIndex(type, args, kwds);
3383 #endif
3385 if (1 == PyTuple_GET_SIZE(args)
3386 && (PyInt_Check(PyTuple_GET_ITEM(args, 0))
3387 || PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
3388 CDataObject *ob;
3389 void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
3390 if (ptr == NULL && PyErr_Occurred())
3391 return NULL;
3392 ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
3393 if (ob == NULL)
3394 return NULL;
3395 *(void **)ob->b_ptr = ptr;
3396 return (PyObject *)ob;
3399 if (!PyArg_ParseTuple(args, "O", &callable))
3400 return NULL;
3401 if (!PyCallable_Check(callable)) {
3402 PyErr_SetString(PyExc_TypeError,
3403 "argument must be callable or integer function address");
3404 return NULL;
3407 /* XXX XXX This would allow to pass additional options. For COM
3408 method *implementations*, we would probably want different
3409 behaviour than in 'normal' callback functions: return a HRESULT if
3410 an exception occurrs in the callback, and print the traceback not
3411 only on the console, but also to OutputDebugString() or something
3412 like that.
3415 if (kwds && PyDict_GetItemString(kwds, "options")) {
3420 dict = PyType_stgdict((PyObject *)type);
3421 /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
3422 if (!dict || !dict->argtypes) {
3423 PyErr_SetString(PyExc_TypeError,
3424 "cannot construct instance of this class:"
3425 " no argtypes");
3426 return NULL;
3429 thunk = _ctypes_alloc_callback(callable,
3430 dict->argtypes,
3431 dict->restype,
3432 dict->flags);
3433 if (!thunk)
3434 return NULL;
3436 self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3437 if (self == NULL) {
3438 Py_DECREF(thunk);
3439 return NULL;
3442 Py_INCREF(callable);
3443 self->callable = callable;
3445 self->thunk = thunk;
3446 *(void **)self->b_ptr = (void *)thunk->pcl;
3448 Py_INCREF((PyObject *)thunk); /* for KeepRef */
3449 if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3450 Py_DECREF((PyObject *)self);
3451 return NULL;
3453 return (PyObject *)self;
3458 _byref consumes a refcount to its argument
3460 static PyObject *
3461 _byref(PyObject *obj)
3463 PyCArgObject *parg;
3464 if (!CDataObject_Check(obj)) {
3465 PyErr_SetString(PyExc_TypeError,
3466 "expected CData instance");
3467 return NULL;
3470 parg = PyCArgObject_new();
3471 if (parg == NULL) {
3472 Py_DECREF(obj);
3473 return NULL;
3476 parg->tag = 'P';
3477 parg->pffi_type = &ffi_type_pointer;
3478 parg->obj = obj;
3479 parg->value.p = ((CDataObject *)obj)->b_ptr;
3480 return (PyObject *)parg;
3483 static PyObject *
3484 _get_arg(int *pindex, char *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
3486 PyObject *v;
3488 if (*pindex < PyTuple_GET_SIZE(inargs)) {
3489 v = PyTuple_GET_ITEM(inargs, *pindex);
3490 ++*pindex;
3491 Py_INCREF(v);
3492 return v;
3494 if (kwds && (v = PyDict_GetItemString(kwds, name))) {
3495 ++*pindex;
3496 Py_INCREF(v);
3497 return v;
3499 if (defval) {
3500 Py_INCREF(defval);
3501 return defval;
3503 /* we can't currently emit a better error message */
3504 if (name)
3505 PyErr_Format(PyExc_TypeError,
3506 "required argument '%s' missing", name);
3507 else
3508 PyErr_Format(PyExc_TypeError,
3509 "not enough arguments");
3510 return NULL;
3514 This function implements higher level functionality plus the ability to call
3515 functions with keyword arguments by looking at parameter flags. parameter
3516 flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer
3517 specifying the direction of the data transfer for this parameter - 'in',
3518 'out' or 'inout' (zero means the same as 'in'). The second entry is the
3519 parameter name, and the third is the default value if the parameter is
3520 missing in the function call.
3522 This function builds and returns a new tuple 'callargs' which contains the
3523 parameters to use in the call. Items on this tuple are copied from the
3524 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
3525 'argtypes' tuple for 'out' parameters. It also calculates numretvals which
3526 is the number of return values for the function, outmask/inoutmask are
3527 bitmasks containing indexes into the callargs tuple specifying which
3528 parameters have to be returned. _build_result builds the return value of the
3529 function.
3531 static PyObject *
3532 _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
3533 PyObject *inargs, PyObject *kwds,
3534 int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
3536 PyObject *paramflags = self->paramflags;
3537 PyObject *callargs;
3538 StgDictObject *dict;
3539 Py_ssize_t i, len;
3540 int inargs_index = 0;
3541 /* It's a little bit difficult to determine how many arguments the
3542 function call requires/accepts. For simplicity, we count the consumed
3543 args and compare this to the number of supplied args. */
3544 Py_ssize_t actual_args;
3546 *poutmask = 0;
3547 *pinoutmask = 0;
3548 *pnumretvals = 0;
3550 /* Trivial cases, where we either return inargs itself, or a slice of it. */
3551 if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
3552 #ifdef MS_WIN32
3553 if (self->index)
3554 return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
3555 #endif
3556 Py_INCREF(inargs);
3557 return inargs;
3560 len = PyTuple_GET_SIZE(argtypes);
3561 callargs = PyTuple_New(len); /* the argument tuple we build */
3562 if (callargs == NULL)
3563 return NULL;
3565 #ifdef MS_WIN32
3566 /* For a COM method, skip the first arg */
3567 if (self->index) {
3568 inargs_index = 1;
3570 #endif
3571 for (i = 0; i < len; ++i) {
3572 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3573 PyObject *ob;
3574 int flag;
3575 char *name = NULL;
3576 PyObject *defval = NULL;
3578 /* This way seems to be ~2 us faster than the PyArg_ParseTuple
3579 calls below. */
3580 /* We HAVE already checked that the tuple can be parsed with "i|zO", so... */
3581 Py_ssize_t tsize = PyTuple_GET_SIZE(item);
3582 flag = PyInt_AS_LONG(PyTuple_GET_ITEM(item, 0));
3583 name = tsize > 1 ? PyString_AS_STRING(PyTuple_GET_ITEM(item, 1)) : NULL;
3584 defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
3586 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3587 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3588 /* ['in', 'lcid'] parameter. Always taken from defval,
3589 if given, else the integer 0. */
3590 if (defval == NULL) {
3591 defval = PyInt_FromLong(0);
3592 if (defval == NULL)
3593 goto error;
3594 } else
3595 Py_INCREF(defval);
3596 PyTuple_SET_ITEM(callargs, i, defval);
3597 break;
3598 case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
3599 *pinoutmask |= (1 << i); /* mark as inout arg */
3600 (*pnumretvals)++;
3601 /* fall through to PARAMFLAG_FIN... */
3602 case 0:
3603 case PARAMFLAG_FIN:
3604 /* 'in' parameter. Copy it from inargs. */
3605 ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
3606 if (ob == NULL)
3607 goto error;
3608 PyTuple_SET_ITEM(callargs, i, ob);
3609 break;
3610 case PARAMFLAG_FOUT:
3611 /* XXX Refactor this code into a separate function. */
3612 /* 'out' parameter.
3613 argtypes[i] must be a POINTER to a c type.
3615 Cannot by supplied in inargs, but a defval will be used
3616 if available. XXX Should we support getting it from kwds?
3618 if (defval) {
3619 /* XXX Using mutable objects as defval will
3620 make the function non-threadsafe, unless we
3621 copy the object in each invocation */
3622 Py_INCREF(defval);
3623 PyTuple_SET_ITEM(callargs, i, defval);
3624 *poutmask |= (1 << i); /* mark as out arg */
3625 (*pnumretvals)++;
3626 break;
3628 ob = PyTuple_GET_ITEM(argtypes, i);
3629 dict = PyType_stgdict(ob);
3630 if (dict == NULL) {
3631 /* Cannot happen: _validate_paramflags()
3632 would not accept such an object */
3633 PyErr_Format(PyExc_RuntimeError,
3634 "NULL stgdict unexpected");
3635 goto error;
3637 if (PyString_Check(dict->proto)) {
3638 PyErr_Format(
3639 PyExc_TypeError,
3640 "%s 'out' parameter must be passed as default value",
3641 ((PyTypeObject *)ob)->tp_name);
3642 goto error;
3644 if (PyCArrayTypeObject_Check(ob))
3645 ob = PyObject_CallObject(ob, NULL);
3646 else
3647 /* Create an instance of the pointed-to type */
3648 ob = PyObject_CallObject(dict->proto, NULL);
3650 XXX Is the following correct any longer?
3651 We must not pass a byref() to the array then but
3652 the array instance itself. Then, we cannot retrive
3653 the result from the PyCArgObject.
3655 if (ob == NULL)
3656 goto error;
3657 /* The .from_param call that will ocurr later will pass this
3658 as a byref parameter. */
3659 PyTuple_SET_ITEM(callargs, i, ob);
3660 *poutmask |= (1 << i); /* mark as out arg */
3661 (*pnumretvals)++;
3662 break;
3663 default:
3664 PyErr_Format(PyExc_ValueError,
3665 "paramflag %d not yet implemented", flag);
3666 goto error;
3667 break;
3671 /* We have counted the arguments we have consumed in 'inargs_index'. This
3672 must be the same as len(inargs) + len(kwds), otherwise we have
3673 either too much or not enough arguments. */
3675 actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
3676 if (actual_args != inargs_index) {
3677 /* When we have default values or named parameters, this error
3678 message is misleading. See unittests/test_paramflags.py
3680 PyErr_Format(PyExc_TypeError,
3681 #if (PY_VERSION_HEX < 0x02050000)
3682 "call takes exactly %d arguments (%d given)",
3683 #else
3684 "call takes exactly %d arguments (%zd given)",
3685 #endif
3686 inargs_index, actual_args);
3687 goto error;
3690 /* outmask is a bitmask containing indexes into callargs. Items at
3691 these indexes contain values to return.
3693 return callargs;
3694 error:
3695 Py_DECREF(callargs);
3696 return NULL;
3699 /* See also:
3700 http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
3703 Build return value of a function.
3705 Consumes the refcount on result and callargs.
3707 static PyObject *
3708 _build_result(PyObject *result, PyObject *callargs,
3709 int outmask, int inoutmask, unsigned int numretvals)
3711 unsigned int i, index;
3712 int bit;
3713 PyObject *tup = NULL;
3715 if (callargs == NULL)
3716 return result;
3717 if (result == NULL || numretvals == 0) {
3718 Py_DECREF(callargs);
3719 return result;
3721 Py_DECREF(result);
3723 /* tup will not be allocated if numretvals == 1 */
3724 /* allocate tuple to hold the result */
3725 if (numretvals > 1) {
3726 tup = PyTuple_New(numretvals);
3727 if (tup == NULL) {
3728 Py_DECREF(callargs);
3729 return NULL;
3733 index = 0;
3734 for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
3735 PyObject *v;
3736 if (bit & inoutmask) {
3737 v = PyTuple_GET_ITEM(callargs, i);
3738 Py_INCREF(v);
3739 if (numretvals == 1) {
3740 Py_DECREF(callargs);
3741 return v;
3743 PyTuple_SET_ITEM(tup, index, v);
3744 index++;
3745 } else if (bit & outmask) {
3746 v = PyTuple_GET_ITEM(callargs, i);
3747 v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
3748 if (v == NULL || numretvals == 1) {
3749 Py_DECREF(callargs);
3750 return v;
3752 PyTuple_SET_ITEM(tup, index, v);
3753 index++;
3755 if (index == numretvals)
3756 break;
3759 Py_DECREF(callargs);
3760 return tup;
3763 static PyObject *
3764 PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
3766 PyObject *restype;
3767 PyObject *converters;
3768 PyObject *checker;
3769 PyObject *argtypes;
3770 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3771 PyObject *result;
3772 PyObject *callargs;
3773 PyObject *errcheck;
3774 #ifdef MS_WIN32
3775 IUnknown *piunk = NULL;
3776 #endif
3777 void *pProc = NULL;
3779 int inoutmask;
3780 int outmask;
3781 unsigned int numretvals;
3783 assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3784 restype = self->restype ? self->restype : dict->restype;
3785 converters = self->converters ? self->converters : dict->converters;
3786 checker = self->checker ? self->checker : dict->checker;
3787 argtypes = self->argtypes ? self->argtypes : dict->argtypes;
3788 /* later, we probably want to have an errcheck field in stgdict */
3789 errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
3792 pProc = *(void **)self->b_ptr;
3793 #ifdef MS_WIN32
3794 if (self->index) {
3795 /* It's a COM method */
3796 CDataObject *this;
3797 this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
3798 if (!this) {
3799 PyErr_SetString(PyExc_ValueError,
3800 "native com method call without 'this' parameter");
3801 return NULL;
3803 if (!CDataObject_Check(this)) {
3804 PyErr_SetString(PyExc_TypeError,
3805 "Expected a COM this pointer as first argument");
3806 return NULL;
3808 /* there should be more checks? No, in Python */
3809 /* First arg is an pointer to an interface instance */
3810 if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
3811 PyErr_SetString(PyExc_ValueError,
3812 "NULL COM pointer access");
3813 return NULL;
3815 piunk = *(IUnknown **)this->b_ptr;
3816 if (NULL == piunk->lpVtbl) {
3817 PyErr_SetString(PyExc_ValueError,
3818 "COM method call without VTable");
3819 return NULL;
3821 pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
3823 #endif
3824 callargs = _build_callargs(self, argtypes,
3825 inargs, kwds,
3826 &outmask, &inoutmask, &numretvals);
3827 if (callargs == NULL)
3828 return NULL;
3830 if (converters) {
3831 int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
3832 Py_ssize_t, int);
3833 int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
3834 Py_ssize_t, int);
3836 if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
3837 /* For cdecl functions, we allow more actual arguments
3838 than the length of the argtypes tuple.
3840 if (required > actual) {
3841 Py_DECREF(callargs);
3842 PyErr_Format(PyExc_TypeError,
3843 "this function takes at least %d argument%s (%d given)",
3844 required,
3845 required == 1 ? "" : "s",
3846 actual);
3847 return NULL;
3849 } else if (required != actual) {
3850 Py_DECREF(callargs);
3851 PyErr_Format(PyExc_TypeError,
3852 "this function takes %d argument%s (%d given)",
3853 required,
3854 required == 1 ? "" : "s",
3855 actual);
3856 return NULL;
3860 result = _ctypes_callproc(pProc,
3861 callargs,
3862 #ifdef MS_WIN32
3863 piunk,
3864 self->iid,
3865 #endif
3866 dict->flags,
3867 converters,
3868 restype,
3869 checker);
3870 /* The 'errcheck' protocol */
3871 if (result != NULL && errcheck) {
3872 PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
3873 result,
3874 self,
3875 callargs,
3876 NULL);
3877 /* If the errcheck funtion failed, return NULL.
3878 If the errcheck function returned callargs unchanged,
3879 continue normal processing.
3880 If the errcheck function returned something else,
3881 use that as result.
3883 if (v == NULL || v != callargs) {
3884 Py_DECREF(result);
3885 Py_DECREF(callargs);
3886 return v;
3888 Py_DECREF(v);
3891 return _build_result(result, callargs,
3892 outmask, inoutmask, numretvals);
3895 static int
3896 PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
3898 Py_VISIT(self->callable);
3899 Py_VISIT(self->restype);
3900 Py_VISIT(self->checker);
3901 Py_VISIT(self->errcheck);
3902 Py_VISIT(self->argtypes);
3903 Py_VISIT(self->converters);
3904 Py_VISIT(self->paramflags);
3905 Py_VISIT(self->thunk);
3906 return PyCData_traverse((CDataObject *)self, visit, arg);
3909 static int
3910 PyCFuncPtr_clear(PyCFuncPtrObject *self)
3912 Py_CLEAR(self->callable);
3913 Py_CLEAR(self->restype);
3914 Py_CLEAR(self->checker);
3915 Py_CLEAR(self->errcheck);
3916 Py_CLEAR(self->argtypes);
3917 Py_CLEAR(self->converters);
3918 Py_CLEAR(self->paramflags);
3919 Py_CLEAR(self->thunk);
3920 return PyCData_clear((CDataObject *)self);
3923 static void
3924 PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
3926 PyCFuncPtr_clear(self);
3927 Py_TYPE(self)->tp_free((PyObject *)self);
3930 static PyObject *
3931 PyCFuncPtr_repr(PyCFuncPtrObject *self)
3933 #ifdef MS_WIN32
3934 if (self->index)
3935 return PyString_FromFormat("<COM method offset %d: %s at %p>",
3936 self->index - 0x1000,
3937 Py_TYPE(self)->tp_name,
3938 self);
3939 #endif
3940 return PyString_FromFormat("<%s object at %p>",
3941 Py_TYPE(self)->tp_name,
3942 self);
3945 static int
3946 PyCFuncPtr_nonzero(PyCFuncPtrObject *self)
3948 return ((*(void **)self->b_ptr != NULL)
3949 #ifdef MS_WIN32
3950 || (self->index != 0)
3951 #endif
3955 static PyNumberMethods PyCFuncPtr_as_number = {
3956 0, /* nb_add */
3957 0, /* nb_subtract */
3958 0, /* nb_multiply */
3959 0, /* nb_divide */
3960 0, /* nb_remainder */
3961 0, /* nb_divmod */
3962 0, /* nb_power */
3963 0, /* nb_negative */
3964 0, /* nb_positive */
3965 0, /* nb_absolute */
3966 (inquiry)PyCFuncPtr_nonzero, /* nb_nonzero */
3969 PyTypeObject PyCFuncPtr_Type = {
3970 PyVarObject_HEAD_INIT(NULL, 0)
3971 "_ctypes.PyCFuncPtr",
3972 sizeof(PyCFuncPtrObject), /* tp_basicsize */
3973 0, /* tp_itemsize */
3974 (destructor)PyCFuncPtr_dealloc, /* tp_dealloc */
3975 0, /* tp_print */
3976 0, /* tp_getattr */
3977 0, /* tp_setattr */
3978 0, /* tp_compare */
3979 (reprfunc)PyCFuncPtr_repr, /* tp_repr */
3980 &PyCFuncPtr_as_number, /* tp_as_number */
3981 0, /* tp_as_sequence */
3982 0, /* tp_as_mapping */
3983 0, /* tp_hash */
3984 (ternaryfunc)PyCFuncPtr_call, /* tp_call */
3985 0, /* tp_str */
3986 0, /* tp_getattro */
3987 0, /* tp_setattro */
3988 &PyCData_as_buffer, /* tp_as_buffer */
3989 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
3990 "Function Pointer", /* tp_doc */
3991 (traverseproc)PyCFuncPtr_traverse, /* tp_traverse */
3992 (inquiry)PyCFuncPtr_clear, /* tp_clear */
3993 0, /* tp_richcompare */
3994 0, /* tp_weaklistoffset */
3995 0, /* tp_iter */
3996 0, /* tp_iternext */
3997 0, /* tp_methods */
3998 0, /* tp_members */
3999 PyCFuncPtr_getsets, /* tp_getset */
4000 0, /* tp_base */
4001 0, /* tp_dict */
4002 0, /* tp_descr_get */
4003 0, /* tp_descr_set */
4004 0, /* tp_dictoffset */
4005 0, /* tp_init */
4006 0, /* tp_alloc */
4007 PyCFuncPtr_new, /* tp_new */
4008 0, /* tp_free */
4011 /*****************************************************************/
4013 Struct_Type
4016 This function is called to initialize a Structure or Union with positional
4017 arguments. It calls itself recursively for all Structure or Union base
4018 classes, then retrieves the _fields_ member to associate the argument
4019 position with the correct field name.
4021 Returns -1 on error, or the index of next argument on success.
4023 static int
4024 _init_pos_args(PyObject *self, PyTypeObject *type,
4025 PyObject *args, PyObject *kwds,
4026 int index)
4028 StgDictObject *dict;
4029 PyObject *fields;
4030 int i;
4032 if (PyType_stgdict((PyObject *)type->tp_base)) {
4033 index = _init_pos_args(self, type->tp_base,
4034 args, kwds,
4035 index);
4036 if (index == -1)
4037 return -1;
4040 dict = PyType_stgdict((PyObject *)type);
4041 fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
4042 if (fields == NULL)
4043 return index;
4045 for (i = 0;
4046 i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
4047 ++i) {
4048 PyObject *pair = PySequence_GetItem(fields, i);
4049 PyObject *name, *val;
4050 int res;
4051 if (!pair)
4052 return -1;
4053 name = PySequence_GetItem(pair, 0);
4054 if (!name) {
4055 Py_DECREF(pair);
4056 return -1;
4058 val = PyTuple_GET_ITEM(args, i + index);
4059 if (kwds && PyDict_GetItem(kwds, name)) {
4060 char *field = PyString_AsString(name);
4061 if (field == NULL) {
4062 PyErr_Clear();
4063 field = "???";
4065 PyErr_Format(PyExc_TypeError,
4066 "duplicate values for field '%s'",
4067 field);
4068 Py_DECREF(pair);
4069 Py_DECREF(name);
4070 return -1;
4073 res = PyObject_SetAttr(self, name, val);
4074 Py_DECREF(pair);
4075 Py_DECREF(name);
4076 if (res == -1)
4077 return -1;
4079 return index + dict->length;
4082 static int
4083 Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
4085 /* Optimization possible: Store the attribute names _fields_[x][0]
4086 * in C accessible fields somewhere ?
4088 if (!PyTuple_Check(args)) {
4089 PyErr_SetString(PyExc_TypeError,
4090 "args not a tuple?");
4091 return -1;
4093 if (PyTuple_GET_SIZE(args)) {
4094 int res = _init_pos_args(self, Py_TYPE(self),
4095 args, kwds, 0);
4096 if (res == -1)
4097 return -1;
4098 if (res < PyTuple_GET_SIZE(args)) {
4099 PyErr_SetString(PyExc_TypeError,
4100 "too many initializers");
4101 return -1;
4105 if (kwds) {
4106 PyObject *key, *value;
4107 Py_ssize_t pos = 0;
4108 while(PyDict_Next(kwds, &pos, &key, &value)) {
4109 if (-1 == PyObject_SetAttr(self, key, value))
4110 return -1;
4113 return 0;
4116 static PyTypeObject Struct_Type = {
4117 PyVarObject_HEAD_INIT(NULL, 0)
4118 "_ctypes.Structure",
4119 sizeof(CDataObject), /* tp_basicsize */
4120 0, /* tp_itemsize */
4121 0, /* tp_dealloc */
4122 0, /* tp_print */
4123 0, /* tp_getattr */
4124 0, /* tp_setattr */
4125 0, /* tp_compare */
4126 0, /* tp_repr */
4127 0, /* tp_as_number */
4128 0, /* tp_as_sequence */
4129 0, /* tp_as_mapping */
4130 0, /* tp_hash */
4131 0, /* tp_call */
4132 0, /* tp_str */
4133 0, /* tp_getattro */
4134 0, /* tp_setattro */
4135 &PyCData_as_buffer, /* tp_as_buffer */
4136 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4137 "Structure base class", /* tp_doc */
4138 (traverseproc)PyCData_traverse, /* tp_traverse */
4139 (inquiry)PyCData_clear, /* tp_clear */
4140 0, /* tp_richcompare */
4141 0, /* tp_weaklistoffset */
4142 0, /* tp_iter */
4143 0, /* tp_iternext */
4144 0, /* tp_methods */
4145 0, /* tp_members */
4146 0, /* tp_getset */
4147 0, /* tp_base */
4148 0, /* tp_dict */
4149 0, /* tp_descr_get */
4150 0, /* tp_descr_set */
4151 0, /* tp_dictoffset */
4152 Struct_init, /* tp_init */
4153 0, /* tp_alloc */
4154 GenericPyCData_new, /* tp_new */
4155 0, /* tp_free */
4158 static PyTypeObject Union_Type = {
4159 PyVarObject_HEAD_INIT(NULL, 0)
4160 "_ctypes.Union",
4161 sizeof(CDataObject), /* tp_basicsize */
4162 0, /* tp_itemsize */
4163 0, /* tp_dealloc */
4164 0, /* tp_print */
4165 0, /* tp_getattr */
4166 0, /* tp_setattr */
4167 0, /* tp_compare */
4168 0, /* tp_repr */
4169 0, /* tp_as_number */
4170 0, /* tp_as_sequence */
4171 0, /* tp_as_mapping */
4172 0, /* tp_hash */
4173 0, /* tp_call */
4174 0, /* tp_str */
4175 0, /* tp_getattro */
4176 0, /* tp_setattro */
4177 &PyCData_as_buffer, /* tp_as_buffer */
4178 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4179 "Union base class", /* tp_doc */
4180 (traverseproc)PyCData_traverse, /* tp_traverse */
4181 (inquiry)PyCData_clear, /* tp_clear */
4182 0, /* tp_richcompare */
4183 0, /* tp_weaklistoffset */
4184 0, /* tp_iter */
4185 0, /* tp_iternext */
4186 0, /* tp_methods */
4187 0, /* tp_members */
4188 0, /* tp_getset */
4189 0, /* tp_base */
4190 0, /* tp_dict */
4191 0, /* tp_descr_get */
4192 0, /* tp_descr_set */
4193 0, /* tp_dictoffset */
4194 Struct_init, /* tp_init */
4195 0, /* tp_alloc */
4196 GenericPyCData_new, /* tp_new */
4197 0, /* tp_free */
4201 /******************************************************************/
4203 PyCArray_Type
4205 static int
4206 Array_init(CDataObject *self, PyObject *args, PyObject *kw)
4208 Py_ssize_t i;
4209 Py_ssize_t n;
4211 if (!PyTuple_Check(args)) {
4212 PyErr_SetString(PyExc_TypeError,
4213 "args not a tuple?");
4214 return -1;
4216 n = PyTuple_GET_SIZE(args);
4217 for (i = 0; i < n; ++i) {
4218 PyObject *v;
4219 v = PyTuple_GET_ITEM(args, i);
4220 if (-1 == PySequence_SetItem((PyObject *)self, i, v))
4221 return -1;
4223 return 0;
4226 static PyObject *
4227 Array_item(PyObject *_self, Py_ssize_t index)
4229 CDataObject *self = (CDataObject *)_self;
4230 Py_ssize_t offset, size;
4231 StgDictObject *stgdict;
4234 if (index < 0 || index >= self->b_length) {
4235 PyErr_SetString(PyExc_IndexError,
4236 "invalid index");
4237 return NULL;
4240 stgdict = PyObject_stgdict((PyObject *)self);
4241 assert(stgdict); /* Cannot be NULL for array instances */
4242 /* Would it be clearer if we got the item size from
4243 stgdict->proto's stgdict?
4245 size = stgdict->size / stgdict->length;
4246 offset = index * size;
4248 return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
4249 index, size, self->b_ptr + offset);
4252 static PyObject *
4253 Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
4255 CDataObject *self = (CDataObject *)_self;
4256 StgDictObject *stgdict, *itemdict;
4257 PyObject *proto;
4258 PyListObject *np;
4259 Py_ssize_t i, len;
4261 if (ilow < 0)
4262 ilow = 0;
4263 else if (ilow > self->b_length)
4264 ilow = self->b_length;
4265 if (ihigh < ilow)
4266 ihigh = ilow;
4267 else if (ihigh > self->b_length)
4268 ihigh = self->b_length;
4269 len = ihigh - ilow;
4271 stgdict = PyObject_stgdict((PyObject *)self);
4272 assert(stgdict); /* Cannot be NULL for array object instances */
4273 proto = stgdict->proto;
4274 itemdict = PyType_stgdict(proto);
4275 assert(itemdict); /* proto is the item type of the array, a ctypes
4276 type, so this cannot be NULL */
4277 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4278 char *ptr = (char *)self->b_ptr;
4279 return PyString_FromStringAndSize(ptr + ilow, len);
4280 #ifdef CTYPES_UNICODE
4281 } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4282 wchar_t *ptr = (wchar_t *)self->b_ptr;
4283 return PyUnicode_FromWideChar(ptr + ilow, len);
4284 #endif
4287 np = (PyListObject *) PyList_New(len);
4288 if (np == NULL)
4289 return NULL;
4291 for (i = 0; i < len; i++) {
4292 PyObject *v = Array_item(_self, i+ilow);
4293 PyList_SET_ITEM(np, i, v);
4295 return (PyObject *)np;
4298 static PyObject *
4299 Array_subscript(PyObject *_self, PyObject *item)
4301 CDataObject *self = (CDataObject *)_self;
4303 if (PyIndex_Check(item)) {
4304 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4306 if (i == -1 && PyErr_Occurred())
4307 return NULL;
4308 if (i < 0)
4309 i += self->b_length;
4310 return Array_item(_self, i);
4312 else if PySlice_Check(item) {
4313 StgDictObject *stgdict, *itemdict;
4314 PyObject *proto;
4315 PyObject *np;
4316 Py_ssize_t start, stop, step, slicelen, cur, i;
4318 if (PySlice_GetIndicesEx((PySliceObject *)item,
4319 self->b_length, &start, &stop,
4320 &step, &slicelen) < 0) {
4321 return NULL;
4324 stgdict = PyObject_stgdict((PyObject *)self);
4325 assert(stgdict); /* Cannot be NULL for array object instances */
4326 proto = stgdict->proto;
4327 itemdict = PyType_stgdict(proto);
4328 assert(itemdict); /* proto is the item type of the array, a
4329 ctypes type, so this cannot be NULL */
4331 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4332 char *ptr = (char *)self->b_ptr;
4333 char *dest;
4335 if (slicelen <= 0)
4336 return PyString_FromString("");
4337 if (step == 1) {
4338 return PyString_FromStringAndSize(ptr + start,
4339 slicelen);
4341 dest = (char *)PyMem_Malloc(slicelen);
4343 if (dest == NULL)
4344 return PyErr_NoMemory();
4346 for (cur = start, i = 0; i < slicelen;
4347 cur += step, i++) {
4348 dest[i] = ptr[cur];
4351 np = PyString_FromStringAndSize(dest, slicelen);
4352 PyMem_Free(dest);
4353 return np;
4355 #ifdef CTYPES_UNICODE
4356 if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4357 wchar_t *ptr = (wchar_t *)self->b_ptr;
4358 wchar_t *dest;
4360 if (slicelen <= 0)
4361 return PyUnicode_FromUnicode(NULL, 0);
4362 if (step == 1) {
4363 return PyUnicode_FromWideChar(ptr + start,
4364 slicelen);
4367 dest = (wchar_t *)PyMem_Malloc(
4368 slicelen * sizeof(wchar_t));
4370 for (cur = start, i = 0; i < slicelen;
4371 cur += step, i++) {
4372 dest[i] = ptr[cur];
4375 np = PyUnicode_FromWideChar(dest, slicelen);
4376 PyMem_Free(dest);
4377 return np;
4379 #endif
4381 np = PyList_New(slicelen);
4382 if (np == NULL)
4383 return NULL;
4385 for (cur = start, i = 0; i < slicelen;
4386 cur += step, i++) {
4387 PyObject *v = Array_item(_self, cur);
4388 PyList_SET_ITEM(np, i, v);
4390 return np;
4392 else {
4393 PyErr_SetString(PyExc_TypeError,
4394 "indices must be integers");
4395 return NULL;
4400 static int
4401 Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4403 CDataObject *self = (CDataObject *)_self;
4404 Py_ssize_t size, offset;
4405 StgDictObject *stgdict;
4406 char *ptr;
4408 if (value == NULL) {
4409 PyErr_SetString(PyExc_TypeError,
4410 "Array does not support item deletion");
4411 return -1;
4414 stgdict = PyObject_stgdict((PyObject *)self);
4415 assert(stgdict); /* Cannot be NULL for array object instances */
4416 if (index < 0 || index >= stgdict->length) {
4417 PyErr_SetString(PyExc_IndexError,
4418 "invalid index");
4419 return -1;
4421 size = stgdict->size / stgdict->length;
4422 offset = index * size;
4423 ptr = self->b_ptr + offset;
4425 return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
4426 index, size, ptr);
4429 static int
4430 Array_ass_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *value)
4432 CDataObject *self = (CDataObject *)_self;
4433 Py_ssize_t i, len;
4435 if (value == NULL) {
4436 PyErr_SetString(PyExc_TypeError,
4437 "Array does not support item deletion");
4438 return -1;
4441 if (ilow < 0)
4442 ilow = 0;
4443 else if (ilow > self->b_length)
4444 ilow = self->b_length;
4445 if (ihigh < 0)
4446 ihigh = 0;
4447 if (ihigh < ilow)
4448 ihigh = ilow;
4449 else if (ihigh > self->b_length)
4450 ihigh = self->b_length;
4452 len = PySequence_Length(value);
4453 if (len != ihigh - ilow) {
4454 PyErr_SetString(PyExc_ValueError,
4455 "Can only assign sequence of same size");
4456 return -1;
4458 for (i = 0; i < len; i++) {
4459 PyObject *item = PySequence_GetItem(value, i);
4460 int result;
4461 if (item == NULL)
4462 return -1;
4463 result = Array_ass_item(_self, i+ilow, item);
4464 Py_DECREF(item);
4465 if (result == -1)
4466 return -1;
4468 return 0;
4471 static int
4472 Array_ass_subscript(PyObject *_self, PyObject *item, PyObject *value)
4474 CDataObject *self = (CDataObject *)_self;
4476 if (value == NULL) {
4477 PyErr_SetString(PyExc_TypeError,
4478 "Array does not support item deletion");
4479 return -1;
4482 if (PyIndex_Check(item)) {
4483 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4485 if (i == -1 && PyErr_Occurred())
4486 return -1;
4487 if (i < 0)
4488 i += self->b_length;
4489 return Array_ass_item(_self, i, value);
4491 else if (PySlice_Check(item)) {
4492 Py_ssize_t start, stop, step, slicelen, otherlen, i, cur;
4494 if (PySlice_GetIndicesEx((PySliceObject *)item,
4495 self->b_length, &start, &stop,
4496 &step, &slicelen) < 0) {
4497 return -1;
4499 if ((step < 0 && start < stop) ||
4500 (step > 0 && start > stop))
4501 stop = start;
4503 otherlen = PySequence_Length(value);
4504 if (otherlen != slicelen) {
4505 PyErr_SetString(PyExc_ValueError,
4506 "Can only assign sequence of same size");
4507 return -1;
4509 for (cur = start, i = 0; i < otherlen; cur += step, i++) {
4510 PyObject *item = PySequence_GetItem(value, i);
4511 int result;
4512 if (item == NULL)
4513 return -1;
4514 result = Array_ass_item(_self, cur, item);
4515 Py_DECREF(item);
4516 if (result == -1)
4517 return -1;
4519 return 0;
4521 else {
4522 PyErr_SetString(PyExc_TypeError,
4523 "indices must be integer");
4524 return -1;
4528 static Py_ssize_t
4529 Array_length(PyObject *_self)
4531 CDataObject *self = (CDataObject *)_self;
4532 return self->b_length;
4535 static PySequenceMethods Array_as_sequence = {
4536 Array_length, /* sq_length; */
4537 0, /* sq_concat; */
4538 0, /* sq_repeat; */
4539 Array_item, /* sq_item; */
4540 Array_slice, /* sq_slice; */
4541 Array_ass_item, /* sq_ass_item; */
4542 Array_ass_slice, /* sq_ass_slice; */
4543 0, /* sq_contains; */
4545 0, /* sq_inplace_concat; */
4546 0, /* sq_inplace_repeat; */
4549 static PyMappingMethods Array_as_mapping = {
4550 Array_length,
4551 Array_subscript,
4552 Array_ass_subscript,
4555 PyTypeObject PyCArray_Type = {
4556 PyVarObject_HEAD_INIT(NULL, 0)
4557 "_ctypes.Array",
4558 sizeof(CDataObject), /* tp_basicsize */
4559 0, /* tp_itemsize */
4560 0, /* tp_dealloc */
4561 0, /* tp_print */
4562 0, /* tp_getattr */
4563 0, /* tp_setattr */
4564 0, /* tp_compare */
4565 0, /* tp_repr */
4566 0, /* tp_as_number */
4567 &Array_as_sequence, /* tp_as_sequence */
4568 &Array_as_mapping, /* tp_as_mapping */
4569 0, /* tp_hash */
4570 0, /* tp_call */
4571 0, /* tp_str */
4572 0, /* tp_getattro */
4573 0, /* tp_setattro */
4574 &PyCData_as_buffer, /* tp_as_buffer */
4575 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4576 "XXX to be provided", /* tp_doc */
4577 (traverseproc)PyCData_traverse, /* tp_traverse */
4578 (inquiry)PyCData_clear, /* tp_clear */
4579 0, /* tp_richcompare */
4580 0, /* tp_weaklistoffset */
4581 0, /* tp_iter */
4582 0, /* tp_iternext */
4583 0, /* tp_methods */
4584 0, /* tp_members */
4585 0, /* tp_getset */
4586 0, /* tp_base */
4587 0, /* tp_dict */
4588 0, /* tp_descr_get */
4589 0, /* tp_descr_set */
4590 0, /* tp_dictoffset */
4591 (initproc)Array_init, /* tp_init */
4592 0, /* tp_alloc */
4593 GenericPyCData_new, /* tp_new */
4594 0, /* tp_free */
4597 PyObject *
4598 PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
4600 static PyObject *cache;
4601 PyObject *key;
4602 PyObject *result;
4603 char name[256];
4604 PyObject *len;
4606 if (cache == NULL) {
4607 cache = PyDict_New();
4608 if (cache == NULL)
4609 return NULL;
4611 len = PyInt_FromSsize_t(length);
4612 if (len == NULL)
4613 return NULL;
4614 key = PyTuple_Pack(2, itemtype, len);
4615 Py_DECREF(len);
4616 if (!key)
4617 return NULL;
4618 result = PyDict_GetItemProxy(cache, key);
4619 if (result) {
4620 Py_INCREF(result);
4621 Py_DECREF(key);
4622 return result;
4625 if (!PyType_Check(itemtype)) {
4626 PyErr_SetString(PyExc_TypeError,
4627 "Expected a type object");
4628 return NULL;
4630 #ifdef MS_WIN64
4631 sprintf(name, "%.200s_Array_%Id",
4632 ((PyTypeObject *)itemtype)->tp_name, length);
4633 #else
4634 sprintf(name, "%.200s_Array_%ld",
4635 ((PyTypeObject *)itemtype)->tp_name, (long)length);
4636 #endif
4638 result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type,
4639 #if (PY_VERSION_HEX < 0x02050000)
4640 "s(O){s:i,s:O}",
4641 #else
4642 "s(O){s:n,s:O}",
4643 #endif
4644 name,
4645 &PyCArray_Type,
4646 "_length_",
4647 length,
4648 "_type_",
4649 itemtype
4651 if (result == NULL) {
4652 Py_DECREF(key);
4653 return NULL;
4655 if (-1 == PyDict_SetItemProxy(cache, key, result)) {
4656 Py_DECREF(key);
4657 Py_DECREF(result);
4658 return NULL;
4660 Py_DECREF(key);
4661 return result;
4665 /******************************************************************/
4667 Simple_Type
4670 static int
4671 Simple_set_value(CDataObject *self, PyObject *value)
4673 PyObject *result;
4674 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
4676 if (value == NULL) {
4677 PyErr_SetString(PyExc_TypeError,
4678 "can't delete attribute");
4679 return -1;
4681 assert(dict); /* Cannot be NULL for CDataObject instances */
4682 assert(dict->setfunc);
4683 result = dict->setfunc(self->b_ptr, value, dict->size);
4684 if (!result)
4685 return -1;
4687 /* consumes the refcount the setfunc returns */
4688 return KeepRef(self, 0, result);
4691 static int
4692 Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
4694 PyObject *value = NULL;
4695 if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
4696 return -1;
4697 if (value)
4698 return Simple_set_value(self, value);
4699 return 0;
4702 static PyObject *
4703 Simple_get_value(CDataObject *self)
4705 StgDictObject *dict;
4706 dict = PyObject_stgdict((PyObject *)self);
4707 assert(dict); /* Cannot be NULL for CDataObject instances */
4708 assert(dict->getfunc);
4709 return dict->getfunc(self->b_ptr, self->b_size);
4712 static PyGetSetDef Simple_getsets[] = {
4713 { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4714 "current value", NULL },
4715 { NULL, NULL }
4718 static PyObject *
4719 Simple_from_outparm(PyObject *self, PyObject *args)
4721 if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) {
4722 Py_INCREF(self);
4723 return self;
4725 /* call stgdict->getfunc */
4726 return Simple_get_value((CDataObject *)self);
4729 static PyMethodDef Simple_methods[] = {
4730 { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
4731 { NULL, NULL },
4734 static int Simple_nonzero(CDataObject *self)
4736 return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
4739 static PyNumberMethods Simple_as_number = {
4740 0, /* nb_add */
4741 0, /* nb_subtract */
4742 0, /* nb_multiply */
4743 0, /* nb_divide */
4744 0, /* nb_remainder */
4745 0, /* nb_divmod */
4746 0, /* nb_power */
4747 0, /* nb_negative */
4748 0, /* nb_positive */
4749 0, /* nb_absolute */
4750 (inquiry)Simple_nonzero, /* nb_nonzero */
4753 /* "%s(%s)" % (self.__class__.__name__, self.value) */
4754 static PyObject *
4755 Simple_repr(CDataObject *self)
4757 PyObject *val, *name, *args, *result;
4758 static PyObject *format;
4760 if (Py_TYPE(self)->tp_base != &Simple_Type) {
4761 return PyString_FromFormat("<%s object at %p>",
4762 Py_TYPE(self)->tp_name, self);
4765 if (format == NULL) {
4766 format = PyString_InternFromString("%s(%r)");
4767 if (format == NULL)
4768 return NULL;
4771 val = Simple_get_value(self);
4772 if (val == NULL)
4773 return NULL;
4775 name = PyString_FromString(Py_TYPE(self)->tp_name);
4776 if (name == NULL) {
4777 Py_DECREF(val);
4778 return NULL;
4781 args = PyTuple_Pack(2, name, val);
4782 Py_DECREF(name);
4783 Py_DECREF(val);
4784 if (args == NULL)
4785 return NULL;
4787 result = PyString_Format(format, args);
4788 Py_DECREF(args);
4789 return result;
4792 static PyTypeObject Simple_Type = {
4793 PyVarObject_HEAD_INIT(NULL, 0)
4794 "_ctypes._SimpleCData",
4795 sizeof(CDataObject), /* tp_basicsize */
4796 0, /* tp_itemsize */
4797 0, /* tp_dealloc */
4798 0, /* tp_print */
4799 0, /* tp_getattr */
4800 0, /* tp_setattr */
4801 0, /* tp_compare */
4802 (reprfunc)&Simple_repr, /* tp_repr */
4803 &Simple_as_number, /* tp_as_number */
4804 0, /* tp_as_sequence */
4805 0, /* tp_as_mapping */
4806 0, /* tp_hash */
4807 0, /* tp_call */
4808 0, /* tp_str */
4809 0, /* tp_getattro */
4810 0, /* tp_setattro */
4811 &PyCData_as_buffer, /* tp_as_buffer */
4812 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4813 "XXX to be provided", /* tp_doc */
4814 (traverseproc)PyCData_traverse, /* tp_traverse */
4815 (inquiry)PyCData_clear, /* tp_clear */
4816 0, /* tp_richcompare */
4817 0, /* tp_weaklistoffset */
4818 0, /* tp_iter */
4819 0, /* tp_iternext */
4820 Simple_methods, /* tp_methods */
4821 0, /* tp_members */
4822 Simple_getsets, /* tp_getset */
4823 0, /* tp_base */
4824 0, /* tp_dict */
4825 0, /* tp_descr_get */
4826 0, /* tp_descr_set */
4827 0, /* tp_dictoffset */
4828 (initproc)Simple_init, /* tp_init */
4829 0, /* tp_alloc */
4830 GenericPyCData_new, /* tp_new */
4831 0, /* tp_free */
4834 /******************************************************************/
4836 PyCPointer_Type
4838 static PyObject *
4839 Pointer_item(PyObject *_self, Py_ssize_t index)
4841 CDataObject *self = (CDataObject *)_self;
4842 Py_ssize_t size;
4843 Py_ssize_t offset;
4844 StgDictObject *stgdict, *itemdict;
4845 PyObject *proto;
4847 if (*(void **)self->b_ptr == NULL) {
4848 PyErr_SetString(PyExc_ValueError,
4849 "NULL pointer access");
4850 return NULL;
4853 stgdict = PyObject_stgdict((PyObject *)self);
4854 assert(stgdict); /* Cannot be NULL for pointer object instances */
4856 proto = stgdict->proto;
4857 assert(proto);
4858 itemdict = PyType_stgdict(proto);
4859 assert(itemdict); /* proto is the item type of the pointer, a ctypes
4860 type, so this cannot be NULL */
4862 size = itemdict->size;
4863 offset = index * itemdict->size;
4865 return PyCData_get(proto, stgdict->getfunc, (PyObject *)self,
4866 index, size, (*(char **)self->b_ptr) + offset);
4869 static int
4870 Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4872 CDataObject *self = (CDataObject *)_self;
4873 Py_ssize_t size;
4874 Py_ssize_t offset;
4875 StgDictObject *stgdict, *itemdict;
4876 PyObject *proto;
4878 if (value == NULL) {
4879 PyErr_SetString(PyExc_TypeError,
4880 "Pointer does not support item deletion");
4881 return -1;
4884 if (*(void **)self->b_ptr == NULL) {
4885 PyErr_SetString(PyExc_ValueError,
4886 "NULL pointer access");
4887 return -1;
4890 stgdict = PyObject_stgdict((PyObject *)self);
4891 assert(stgdict); /* Cannot be NULL fr pointer instances */
4893 proto = stgdict->proto;
4894 assert(proto);
4896 itemdict = PyType_stgdict(proto);
4897 assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
4898 is always a ctypes type */
4900 size = itemdict->size;
4901 offset = index * itemdict->size;
4903 return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value,
4904 index, size, (*(char **)self->b_ptr) + offset);
4907 static PyObject *
4908 Pointer_get_contents(CDataObject *self, void *closure)
4910 StgDictObject *stgdict;
4912 if (*(void **)self->b_ptr == NULL) {
4913 PyErr_SetString(PyExc_ValueError,
4914 "NULL pointer access");
4915 return NULL;
4918 stgdict = PyObject_stgdict((PyObject *)self);
4919 assert(stgdict); /* Cannot be NULL fr pointer instances */
4920 return PyCData_FromBaseObj(stgdict->proto,
4921 (PyObject *)self, 0,
4922 *(void **)self->b_ptr);
4925 static int
4926 Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
4928 StgDictObject *stgdict;
4929 CDataObject *dst;
4930 PyObject *keep;
4932 if (value == NULL) {
4933 PyErr_SetString(PyExc_TypeError,
4934 "Pointer does not support item deletion");
4935 return -1;
4937 stgdict = PyObject_stgdict((PyObject *)self);
4938 assert(stgdict); /* Cannot be NULL fr pointer instances */
4939 assert(stgdict->proto);
4940 if (!CDataObject_Check(value)
4941 || 0 == PyObject_IsInstance(value, stgdict->proto)) {
4942 /* XXX PyObject_IsInstance could return -1! */
4943 PyErr_Format(PyExc_TypeError,
4944 "expected %s instead of %s",
4945 ((PyTypeObject *)(stgdict->proto))->tp_name,
4946 Py_TYPE(value)->tp_name);
4947 return -1;
4950 dst = (CDataObject *)value;
4951 *(void **)self->b_ptr = dst->b_ptr;
4954 A Pointer instance must keep a the value it points to alive. So, a
4955 pointer instance has b_length set to 2 instead of 1, and we set
4956 'value' itself as the second item of the b_objects list, additionally.
4958 Py_INCREF(value);
4959 if (-1 == KeepRef(self, 1, value))
4960 return -1;
4962 keep = GetKeepedObjects(dst);
4963 Py_INCREF(keep);
4964 return KeepRef(self, 0, keep);
4967 static PyGetSetDef Pointer_getsets[] = {
4968 { "contents", (getter)Pointer_get_contents,
4969 (setter)Pointer_set_contents,
4970 "the object this pointer points to (read-write)", NULL },
4971 { NULL, NULL }
4974 static int
4975 Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
4977 PyObject *value = NULL;
4979 if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
4980 return -1;
4981 if (value == NULL)
4982 return 0;
4983 return Pointer_set_contents(self, value, NULL);
4986 static PyObject *
4987 Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4989 StgDictObject *dict = PyType_stgdict((PyObject *)type);
4990 if (!dict || !dict->proto) {
4991 PyErr_SetString(PyExc_TypeError,
4992 "Cannot create instance: has no _type_");
4993 return NULL;
4995 return GenericPyCData_new(type, args, kw);
4998 static PyObject *
4999 Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
5001 CDataObject *self = (CDataObject *)_self;
5002 PyListObject *np;
5003 StgDictObject *stgdict, *itemdict;
5004 PyObject *proto;
5005 Py_ssize_t i, len;
5007 if (ilow < 0)
5008 ilow = 0;
5009 if (ihigh < ilow)
5010 ihigh = ilow;
5011 len = ihigh - ilow;
5013 stgdict = PyObject_stgdict((PyObject *)self);
5014 assert(stgdict); /* Cannot be NULL fr pointer instances */
5015 proto = stgdict->proto;
5016 assert(proto);
5017 itemdict = PyType_stgdict(proto);
5018 assert(itemdict);
5019 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
5020 char *ptr = *(char **)self->b_ptr;
5021 return PyString_FromStringAndSize(ptr + ilow, len);
5022 #ifdef CTYPES_UNICODE
5023 } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
5024 wchar_t *ptr = *(wchar_t **)self->b_ptr;
5025 return PyUnicode_FromWideChar(ptr + ilow, len);
5026 #endif
5029 np = (PyListObject *) PyList_New(len);
5030 if (np == NULL)
5031 return NULL;
5033 for (i = 0; i < len; i++) {
5034 PyObject *v = Pointer_item(_self, i+ilow);
5035 PyList_SET_ITEM(np, i, v);
5037 return (PyObject *)np;
5040 static PyObject *
5041 Pointer_subscript(PyObject *_self, PyObject *item)
5043 CDataObject *self = (CDataObject *)_self;
5044 if (PyIndex_Check(item)) {
5045 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
5046 if (i == -1 && PyErr_Occurred())
5047 return NULL;
5048 return Pointer_item(_self, i);
5050 else if (PySlice_Check(item)) {
5051 PySliceObject *slice = (PySliceObject *)item;
5052 Py_ssize_t start, stop, step;
5053 PyObject *np;
5054 StgDictObject *stgdict, *itemdict;
5055 PyObject *proto;
5056 Py_ssize_t i, len, cur;
5058 /* Since pointers have no length, and we want to apply
5059 different semantics to negative indices than normal
5060 slicing, we have to dissect the slice object ourselves.*/
5061 if (slice->step == Py_None) {
5062 step = 1;
5064 else {
5065 step = PyNumber_AsSsize_t(slice->step,
5066 PyExc_ValueError);
5067 if (step == -1 && PyErr_Occurred())
5068 return NULL;
5069 if (step == 0) {
5070 PyErr_SetString(PyExc_ValueError,
5071 "slice step cannot be zero");
5072 return NULL;
5075 if (slice->start == Py_None) {
5076 if (step < 0) {
5077 PyErr_SetString(PyExc_ValueError,
5078 "slice start is required "
5079 "for step < 0");
5080 return NULL;
5082 start = 0;
5084 else {
5085 start = PyNumber_AsSsize_t(slice->start,
5086 PyExc_ValueError);
5087 if (start == -1 && PyErr_Occurred())
5088 return NULL;
5090 if (slice->stop == Py_None) {
5091 PyErr_SetString(PyExc_ValueError,
5092 "slice stop is required");
5093 return NULL;
5095 stop = PyNumber_AsSsize_t(slice->stop,
5096 PyExc_ValueError);
5097 if (stop == -1 && PyErr_Occurred())
5098 return NULL;
5099 if ((step > 0 && start > stop) ||
5100 (step < 0 && start < stop))
5101 len = 0;
5102 else if (step > 0)
5103 len = (stop - start - 1) / step + 1;
5104 else
5105 len = (stop - start + 1) / step + 1;
5107 stgdict = PyObject_stgdict((PyObject *)self);
5108 assert(stgdict); /* Cannot be NULL for pointer instances */
5109 proto = stgdict->proto;
5110 assert(proto);
5111 itemdict = PyType_stgdict(proto);
5112 assert(itemdict);
5113 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
5114 char *ptr = *(char **)self->b_ptr;
5115 char *dest;
5117 if (len <= 0)
5118 return PyString_FromString("");
5119 if (step == 1) {
5120 return PyString_FromStringAndSize(ptr + start,
5121 len);
5123 dest = (char *)PyMem_Malloc(len);
5124 if (dest == NULL)
5125 return PyErr_NoMemory();
5126 for (cur = start, i = 0; i < len; cur += step, i++) {
5127 dest[i] = ptr[cur];
5129 np = PyString_FromStringAndSize(dest, len);
5130 PyMem_Free(dest);
5131 return np;
5133 #ifdef CTYPES_UNICODE
5134 if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
5135 wchar_t *ptr = *(wchar_t **)self->b_ptr;
5136 wchar_t *dest;
5138 if (len <= 0)
5139 return PyUnicode_FromUnicode(NULL, 0);
5140 if (step == 1) {
5141 return PyUnicode_FromWideChar(ptr + start,
5142 len);
5144 dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t));
5145 if (dest == NULL)
5146 return PyErr_NoMemory();
5147 for (cur = start, i = 0; i < len; cur += step, i++) {
5148 dest[i] = ptr[cur];
5150 np = PyUnicode_FromWideChar(dest, len);
5151 PyMem_Free(dest);
5152 return np;
5154 #endif
5156 np = PyList_New(len);
5157 if (np == NULL)
5158 return NULL;
5160 for (cur = start, i = 0; i < len; cur += step, i++) {
5161 PyObject *v = Pointer_item(_self, cur);
5162 PyList_SET_ITEM(np, i, v);
5164 return np;
5166 else {
5167 PyErr_SetString(PyExc_TypeError,
5168 "Pointer indices must be integer");
5169 return NULL;
5173 static PySequenceMethods Pointer_as_sequence = {
5174 0, /* inquiry sq_length; */
5175 0, /* binaryfunc sq_concat; */
5176 0, /* intargfunc sq_repeat; */
5177 Pointer_item, /* intargfunc sq_item; */
5178 Pointer_slice, /* intintargfunc sq_slice; */
5179 Pointer_ass_item, /* intobjargproc sq_ass_item; */
5180 0, /* intintobjargproc sq_ass_slice; */
5181 0, /* objobjproc sq_contains; */
5182 /* Added in release 2.0 */
5183 0, /* binaryfunc sq_inplace_concat; */
5184 0, /* intargfunc sq_inplace_repeat; */
5187 static PyMappingMethods Pointer_as_mapping = {
5189 Pointer_subscript,
5192 static int
5193 Pointer_nonzero(CDataObject *self)
5195 return (*(void **)self->b_ptr != NULL);
5198 static PyNumberMethods Pointer_as_number = {
5199 0, /* nb_add */
5200 0, /* nb_subtract */
5201 0, /* nb_multiply */
5202 0, /* nb_divide */
5203 0, /* nb_remainder */
5204 0, /* nb_divmod */
5205 0, /* nb_power */
5206 0, /* nb_negative */
5207 0, /* nb_positive */
5208 0, /* nb_absolute */
5209 (inquiry)Pointer_nonzero, /* nb_nonzero */
5212 PyTypeObject PyCPointer_Type = {
5213 PyVarObject_HEAD_INIT(NULL, 0)
5214 "_ctypes._Pointer",
5215 sizeof(CDataObject), /* tp_basicsize */
5216 0, /* tp_itemsize */
5217 0, /* tp_dealloc */
5218 0, /* tp_print */
5219 0, /* tp_getattr */
5220 0, /* tp_setattr */
5221 0, /* tp_compare */
5222 0, /* tp_repr */
5223 &Pointer_as_number, /* tp_as_number */
5224 &Pointer_as_sequence, /* tp_as_sequence */
5225 &Pointer_as_mapping, /* tp_as_mapping */
5226 0, /* tp_hash */
5227 0, /* tp_call */
5228 0, /* tp_str */
5229 0, /* tp_getattro */
5230 0, /* tp_setattro */
5231 &PyCData_as_buffer, /* tp_as_buffer */
5232 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
5233 "XXX to be provided", /* tp_doc */
5234 (traverseproc)PyCData_traverse, /* tp_traverse */
5235 (inquiry)PyCData_clear, /* tp_clear */
5236 0, /* tp_richcompare */
5237 0, /* tp_weaklistoffset */
5238 0, /* tp_iter */
5239 0, /* tp_iternext */
5240 0, /* tp_methods */
5241 0, /* tp_members */
5242 Pointer_getsets, /* tp_getset */
5243 0, /* tp_base */
5244 0, /* tp_dict */
5245 0, /* tp_descr_get */
5246 0, /* tp_descr_set */
5247 0, /* tp_dictoffset */
5248 (initproc)Pointer_init, /* tp_init */
5249 0, /* tp_alloc */
5250 Pointer_new, /* tp_new */
5251 0, /* tp_free */
5255 /******************************************************************/
5257 * Module initialization.
5260 static char *module_docs =
5261 "Create and manipulate C compatible data types in Python.";
5263 #ifdef MS_WIN32
5265 static char comerror_doc[] = "Raised when a COM method call failed.";
5267 static PyObject *
5268 comerror_init(PyObject *self, PyObject *args)
5270 PyObject *hresult, *text, *details;
5271 PyObject *a;
5272 int status;
5274 if (!PyArg_ParseTuple(args, "OOOO:COMError", &self, &hresult, &text, &details))
5275 return NULL;
5277 a = PySequence_GetSlice(args, 1, PySequence_Size(args));
5278 if (!a)
5279 return NULL;
5280 status = PyObject_SetAttrString(self, "args", a);
5281 Py_DECREF(a);
5282 if (status < 0)
5283 return NULL;
5285 if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
5286 return NULL;
5288 if (PyObject_SetAttrString(self, "text", text) < 0)
5289 return NULL;
5291 if (PyObject_SetAttrString(self, "details", details) < 0)
5292 return NULL;
5294 Py_INCREF(Py_None);
5295 return Py_None;
5298 static PyMethodDef comerror_methods[] = {
5299 { "__init__", comerror_init, METH_VARARGS },
5300 { NULL, NULL },
5303 static int
5304 create_comerror(void)
5306 PyObject *dict = PyDict_New();
5307 PyMethodDef *methods = comerror_methods;
5308 PyObject *s;
5309 int status;
5311 if (dict == NULL)
5312 return -1;
5314 while (methods->ml_name) {
5315 /* get a wrapper for the built-in function */
5316 PyObject *func = PyCFunction_New(methods, NULL);
5317 PyObject *meth;
5318 if (func == NULL)
5319 goto error;
5320 meth = PyMethod_New(func, NULL, ComError);
5321 Py_DECREF(func);
5322 if (meth == NULL)
5323 goto error;
5324 PyDict_SetItemString(dict, methods->ml_name, meth);
5325 Py_DECREF(meth);
5326 ++methods;
5329 s = PyString_FromString(comerror_doc);
5330 if (s == NULL)
5331 goto error;
5332 status = PyDict_SetItemString(dict, "__doc__", s);
5333 Py_DECREF(s);
5334 if (status == -1)
5335 goto error;
5337 ComError = PyErr_NewException("_ctypes.COMError",
5338 NULL,
5339 dict);
5340 if (ComError == NULL)
5341 goto error;
5343 return 0;
5344 error:
5345 Py_DECREF(dict);
5346 return -1;
5349 #endif
5351 static PyObject *
5352 string_at(const char *ptr, int size)
5354 if (size == -1)
5355 return PyString_FromString(ptr);
5356 return PyString_FromStringAndSize(ptr, size);
5359 static int
5360 cast_check_pointertype(PyObject *arg)
5362 StgDictObject *dict;
5364 if (PyCPointerTypeObject_Check(arg))
5365 return 1;
5366 if (PyCFuncPtrTypeObject_Check(arg))
5367 return 1;
5368 dict = PyType_stgdict(arg);
5369 if (dict) {
5370 if (PyString_Check(dict->proto)
5371 && (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) {
5372 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
5373 return 1;
5376 PyErr_Format(PyExc_TypeError,
5377 "cast() argument 2 must be a pointer type, not %s",
5378 PyType_Check(arg)
5379 ? ((PyTypeObject *)arg)->tp_name
5380 : Py_TYPE(arg)->tp_name);
5381 return 0;
5384 static PyObject *
5385 cast(void *ptr, PyObject *src, PyObject *ctype)
5387 CDataObject *result;
5388 if (0 == cast_check_pointertype(ctype))
5389 return NULL;
5390 result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
5391 if (result == NULL)
5392 return NULL;
5395 The casted objects '_objects' member:
5397 It must certainly contain the source objects one.
5398 It must contain the source object itself.
5400 if (CDataObject_Check(src)) {
5401 CDataObject *obj = (CDataObject *)src;
5402 /* PyCData_GetContainer will initialize src.b_objects, we need
5403 this so it can be shared */
5404 PyCData_GetContainer(obj);
5405 /* But we need a dictionary! */
5406 if (obj->b_objects == Py_None) {
5407 Py_DECREF(Py_None);
5408 obj->b_objects = PyDict_New();
5409 if (obj->b_objects == NULL)
5410 goto failed;
5412 Py_XINCREF(obj->b_objects);
5413 result->b_objects = obj->b_objects;
5414 if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
5415 PyObject *index;
5416 int rc;
5417 index = PyLong_FromVoidPtr((void *)src);
5418 if (index == NULL)
5419 goto failed;
5420 rc = PyDict_SetItem(result->b_objects, index, src);
5421 Py_DECREF(index);
5422 if (rc == -1)
5423 goto failed;
5426 /* Should we assert that result is a pointer type? */
5427 memcpy(result->b_ptr, &ptr, sizeof(void *));
5428 return (PyObject *)result;
5430 failed:
5431 Py_DECREF(result);
5432 return NULL;
5435 #ifdef CTYPES_UNICODE
5436 static PyObject *
5437 wstring_at(const wchar_t *ptr, int size)
5439 Py_ssize_t ssize = size;
5440 if (ssize == -1)
5441 ssize = wcslen(ptr);
5442 return PyUnicode_FromWideChar(ptr, ssize);
5444 #endif
5446 PyMODINIT_FUNC
5447 init_ctypes(void)
5449 PyObject *m;
5451 /* Note:
5452 ob_type is the metatype (the 'type'), defaults to PyType_Type,
5453 tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
5455 #ifdef WITH_THREAD
5456 PyEval_InitThreads();
5457 #endif
5458 m = Py_InitModule3("_ctypes", _ctypes_module_methods, module_docs);
5459 if (!m)
5460 return;
5462 _ctypes_ptrtype_cache = PyDict_New();
5463 if (_ctypes_ptrtype_cache == NULL)
5464 return;
5466 PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache);
5468 _unpickle = PyObject_GetAttrString(m, "_unpickle");
5469 if (_unpickle == NULL)
5470 return;
5472 if (PyType_Ready(&PyCArg_Type) < 0)
5473 return;
5475 if (PyType_Ready(&PyCThunk_Type) < 0)
5476 return;
5478 /* StgDict is derived from PyDict_Type */
5479 PyCStgDict_Type.tp_base = &PyDict_Type;
5480 if (PyType_Ready(&PyCStgDict_Type) < 0)
5481 return;
5483 /*************************************************
5485 * Metaclasses
5488 PyCStructType_Type.tp_base = &PyType_Type;
5489 if (PyType_Ready(&PyCStructType_Type) < 0)
5490 return;
5492 UnionType_Type.tp_base = &PyType_Type;
5493 if (PyType_Ready(&UnionType_Type) < 0)
5494 return;
5496 PyCPointerType_Type.tp_base = &PyType_Type;
5497 if (PyType_Ready(&PyCPointerType_Type) < 0)
5498 return;
5500 PyCArrayType_Type.tp_base = &PyType_Type;
5501 if (PyType_Ready(&PyCArrayType_Type) < 0)
5502 return;
5504 PyCSimpleType_Type.tp_base = &PyType_Type;
5505 if (PyType_Ready(&PyCSimpleType_Type) < 0)
5506 return;
5508 PyCFuncPtrType_Type.tp_base = &PyType_Type;
5509 if (PyType_Ready(&PyCFuncPtrType_Type) < 0)
5510 return;
5512 /*************************************************
5514 * Classes using a custom metaclass
5517 if (PyType_Ready(&PyCData_Type) < 0)
5518 return;
5520 Py_TYPE(&Struct_Type) = &PyCStructType_Type;
5521 Struct_Type.tp_base = &PyCData_Type;
5522 if (PyType_Ready(&Struct_Type) < 0)
5523 return;
5524 PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
5526 Py_TYPE(&Union_Type) = &UnionType_Type;
5527 Union_Type.tp_base = &PyCData_Type;
5528 if (PyType_Ready(&Union_Type) < 0)
5529 return;
5530 PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
5532 Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type;
5533 PyCPointer_Type.tp_base = &PyCData_Type;
5534 if (PyType_Ready(&PyCPointer_Type) < 0)
5535 return;
5536 PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);
5538 Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type;
5539 PyCArray_Type.tp_base = &PyCData_Type;
5540 if (PyType_Ready(&PyCArray_Type) < 0)
5541 return;
5542 PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);
5544 Py_TYPE(&Simple_Type) = &PyCSimpleType_Type;
5545 Simple_Type.tp_base = &PyCData_Type;
5546 if (PyType_Ready(&Simple_Type) < 0)
5547 return;
5548 PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
5550 Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type;
5551 PyCFuncPtr_Type.tp_base = &PyCData_Type;
5552 if (PyType_Ready(&PyCFuncPtr_Type) < 0)
5553 return;
5554 PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);
5556 /*************************************************
5558 * Simple classes
5561 /* PyCField_Type is derived from PyBaseObject_Type */
5562 if (PyType_Ready(&PyCField_Type) < 0)
5563 return;
5565 /*************************************************
5567 * Other stuff
5570 DictRemover_Type.tp_new = PyType_GenericNew;
5571 if (PyType_Ready(&DictRemover_Type) < 0)
5572 return;
5574 #ifdef MS_WIN32
5575 if (create_comerror() < 0)
5576 return;
5577 PyModule_AddObject(m, "COMError", ComError);
5579 PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyInt_FromLong(FUNCFLAG_HRESULT));
5580 PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyInt_FromLong(FUNCFLAG_STDCALL));
5581 #endif
5582 PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
5583 PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyInt_FromLong(FUNCFLAG_USE_ERRNO));
5584 PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyInt_FromLong(FUNCFLAG_USE_LASTERROR));
5585 PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
5586 PyModule_AddStringConstant(m, "__version__", "1.1.0");
5588 PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
5589 PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
5590 PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
5591 PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
5592 #ifdef CTYPES_UNICODE
5593 PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
5594 #endif
5596 /* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
5597 #ifndef RTLD_LOCAL
5598 #define RTLD_LOCAL 0
5599 #endif
5601 /* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
5602 RTLD_LOCAL.
5604 #ifndef RTLD_GLOBAL
5605 #define RTLD_GLOBAL RTLD_LOCAL
5606 #endif
5608 PyModule_AddObject(m, "RTLD_LOCAL", PyInt_FromLong(RTLD_LOCAL));
5609 PyModule_AddObject(m, "RTLD_GLOBAL", PyInt_FromLong(RTLD_GLOBAL));
5611 PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5612 if (PyExc_ArgError) {
5613 Py_INCREF(PyExc_ArgError);
5614 PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
5618 /*****************************************************************
5619 * replacements for broken Python api functions (in Python 2.3).
5620 * See #1047269 Buffer overwrite in PyUnicode_AsWideChar
5623 #if (PY_VERSION_HEX < 0x02040000)
5624 #ifdef HAVE_WCHAR_H
5626 PyObject *My_PyUnicode_FromWideChar(register const wchar_t *w,
5627 Py_ssize_t size)
5629 PyUnicodeObject *unicode;
5631 if (w == NULL) {
5632 PyErr_BadInternalCall();
5633 return NULL;
5636 unicode = (PyUnicodeObject *)PyUnicode_FromUnicode(NULL, size);
5637 if (!unicode)
5638 return NULL;
5640 /* Copy the wchar_t data into the new object */
5641 #ifdef HAVE_USABLE_WCHAR_T
5642 memcpy(unicode->str, w, size * sizeof(wchar_t));
5643 #else
5645 register Py_UNICODE *u;
5646 register int i;
5647 u = PyUnicode_AS_UNICODE(unicode);
5648 /* In Python, the following line has a one-off error */
5649 for (i = size; i > 0; i--)
5650 *u++ = *w++;
5652 #endif
5654 return (PyObject *)unicode;
5657 Py_ssize_t My_PyUnicode_AsWideChar(PyUnicodeObject *unicode,
5658 register wchar_t *w,
5659 Py_ssize_t size)
5661 if (unicode == NULL) {
5662 PyErr_BadInternalCall();
5663 return -1;
5665 if (size > PyUnicode_GET_SIZE(unicode))
5666 size = PyUnicode_GET_SIZE(unicode);
5667 #ifdef HAVE_USABLE_WCHAR_T
5668 memcpy(w, unicode->str, size * sizeof(wchar_t));
5669 #else
5671 register Py_UNICODE *u;
5672 register int i;
5673 u = PyUnicode_AS_UNICODE(unicode);
5674 /* In Python, the following line has a one-off error */
5675 for (i = size; i > 0; i--)
5676 *w++ = *u++;
5678 #endif
5680 return size;
5682 #endif
5683 #endif
5686 Local Variables:
5687 compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
5688 End: