blob: 751630654602d96ba950cf49af821be193ba3fa2 [file] [log] [blame]
Thomas Hellerd4c93202006-03-08 19:35:11 +00001/*
2 ToDo:
3
Thomas Heller34596a92009-04-24 20:50:00 +00004 Get rid of the checker (and also the converters) field in PyCFuncPtrObject and
Thomas Hellerd4c93202006-03-08 19:35:11 +00005 StgDictObject, and replace them by slot functions in StgDictObject.
6
7 think about a buffer-like object (memory? bytes?)
8
9 Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
10 What about c_char and c_wchar arrays then?
11
12 Add from_mmap, from_file, from_string metaclass methods.
13
14 Maybe we can get away with from_file (calls read) and with a from_buffer
15 method?
16
17 And what about the to_mmap, to_file, to_str(?) methods? They would clobber
18 the namespace, probably. So, functions instead? And we already have memmove...
19*/
20
21/*
22
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000023Name methods, members, getsets
Thomas Hellerd4c93202006-03-08 19:35:11 +000024==============================================================================
25
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000026PyCStructType_Type __new__(), from_address(), __mul__(), from_param()
27UnionType_Type __new__(), from_address(), __mul__(), from_param()
28PyCPointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type()
29PyCArrayType_Type __new__(), from_address(), __mul__(), from_param()
30PyCSimpleType_Type __new__(), from_address(), __mul__(), from_param()
Thomas Hellerd4c93202006-03-08 19:35:11 +000031
Thomas Heller34596a92009-04-24 20:50:00 +000032PyCData_Type
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033 Struct_Type __new__(), __init__()
34 PyCPointer_Type __new__(), __init__(), _as_parameter_, contents
35 PyCArray_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
36 Simple_Type __new__(), __init__(), _as_parameter_
Thomas Hellerd4c93202006-03-08 19:35:11 +000037
Thomas Heller34596a92009-04-24 20:50:00 +000038PyCField_Type
39PyCStgDict_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +000040
41==============================================================================
42
43class methods
44-------------
45
46It has some similarity to the byref() construct compared to pointer()
47from_address(addr)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000048 - construct an instance from a given memory block (sharing this memory block)
Thomas Hellerd4c93202006-03-08 19:35:11 +000049
50from_param(obj)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 - typecheck and convert a Python object into a C function call parameter
52 the result may be an instance of the type, or an integer or tuple
53 (typecode, value[, obj])
Thomas Hellerd4c93202006-03-08 19:35:11 +000054
55instance methods/properties
56---------------------------
57
58_as_parameter_
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 - convert self into a C function call parameter
60 This is either an integer, or a 3-tuple (typecode, value, obj)
Thomas Hellerd4c93202006-03-08 19:35:11 +000061
62functions
63---------
64
65sizeof(cdata)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 - return the number of bytes the buffer contains
Thomas Hellerd4c93202006-03-08 19:35:11 +000067
68sizeof(ctype)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 - return the number of bytes the buffer of an instance would contain
Thomas Hellerd4c93202006-03-08 19:35:11 +000070
71byref(cdata)
72
73addressof(cdata)
74
75pointer(cdata)
76
77POINTER(ctype)
78
79bytes(cdata)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 - return the buffer contents as a sequence of bytes (which is currently a string)
Thomas Hellerd4c93202006-03-08 19:35:11 +000081
82*/
83
84/*
Thomas Heller34596a92009-04-24 20:50:00 +000085 * PyCStgDict_Type
86 * PyCStructType_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +000087 * UnionType_Type
Thomas Heller34596a92009-04-24 20:50:00 +000088 * PyCPointerType_Type
89 * PyCArrayType_Type
90 * PyCSimpleType_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +000091 *
Thomas Heller34596a92009-04-24 20:50:00 +000092 * PyCData_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +000093 * Struct_Type
94 * Union_Type
Thomas Heller34596a92009-04-24 20:50:00 +000095 * PyCArray_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +000096 * Simple_Type
Thomas Heller34596a92009-04-24 20:50:00 +000097 * PyCPointer_Type
98 * PyCField_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +000099 *
100 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101
Christian Heimesf6cd9672008-03-26 13:45:42 +0000102#define PY_SSIZE_T_CLEAN
103
Thomas Hellerd4c93202006-03-08 19:35:11 +0000104#include "Python.h"
105#include "structmember.h"
106
107#include <ffi.h>
108#ifdef MS_WIN32
109#include <windows.h>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000110#include <malloc.h>
111#ifndef IS_INTRESOURCE
112#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
113#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000114# ifdef _WIN32_WCE
115/* Unlike desktop Windows, WinCE has both W and A variants of
116 GetProcAddress, but the default W version is not what we want */
117# undef GetProcAddress
118# define GetProcAddress GetProcAddressA
119# endif
120#else
121#include "ctypes_dlfcn.h"
122#endif
123#include "ctypes.h"
124
125PyObject *PyExc_ArgError;
Thomas Heller3071f812008-04-14 16:17:33 +0000126
127/* This dict maps ctypes types to POINTER types */
Thomas Heller34596a92009-04-24 20:50:00 +0000128PyObject *_ctypes_ptrtype_cache;
Thomas Heller3071f812008-04-14 16:17:33 +0000129
Thomas Hellerd4c93202006-03-08 19:35:11 +0000130static PyTypeObject Simple_Type;
131
Thomas Heller13394e92008-02-13 20:40:44 +0000132/* a callable object used for unpickling */
133static PyObject *_unpickle;
134
Thomas Hellerd4c93202006-03-08 19:35:11 +0000135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136
Christian Heimes969fe572008-01-25 11:23:10 +0000137/****************************************************************/
138
139typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 PyObject_HEAD
141 PyObject *key;
142 PyObject *dict;
Christian Heimes969fe572008-01-25 11:23:10 +0000143} DictRemoverObject;
144
145static void
146_DictRemover_dealloc(PyObject *_self)
147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 DictRemoverObject *self = (DictRemoverObject *)_self;
149 Py_XDECREF(self->key);
150 Py_XDECREF(self->dict);
151 Py_TYPE(self)->tp_free(_self);
Christian Heimes969fe572008-01-25 11:23:10 +0000152}
153
154static PyObject *
155_DictRemover_call(PyObject *_self, PyObject *args, PyObject *kw)
156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 DictRemoverObject *self = (DictRemoverObject *)_self;
158 if (self->key && self->dict) {
159 if (-1 == PyDict_DelItem(self->dict, self->key))
160 /* XXX Error context */
161 PyErr_WriteUnraisable(Py_None);
162 Py_DECREF(self->key);
163 self->key = NULL;
164 Py_DECREF(self->dict);
165 self->dict = NULL;
166 }
167 Py_INCREF(Py_None);
168 return Py_None;
Christian Heimes969fe572008-01-25 11:23:10 +0000169}
170
171static PyTypeObject DictRemover_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 PyVarObject_HEAD_INIT(NULL, 0)
173 "_ctypes.DictRemover", /* tp_name */
174 sizeof(DictRemoverObject), /* tp_basicsize */
175 0, /* tp_itemsize */
176 _DictRemover_dealloc, /* tp_dealloc */
177 0, /* tp_print */
178 0, /* tp_getattr */
179 0, /* tp_setattr */
180 0, /* tp_reserved */
181 0, /* tp_repr */
182 0, /* tp_as_number */
183 0, /* tp_as_sequence */
184 0, /* tp_as_mapping */
185 0, /* tp_hash */
186 _DictRemover_call, /* tp_call */
187 0, /* tp_str */
188 0, /* tp_getattro */
189 0, /* tp_setattro */
190 0, /* tp_as_buffer */
Christian Heimes969fe572008-01-25 11:23:10 +0000191/* XXX should participate in GC? */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 Py_TPFLAGS_DEFAULT, /* tp_flags */
193 "deletes a key from a dictionary", /* tp_doc */
194 0, /* tp_traverse */
195 0, /* tp_clear */
196 0, /* tp_richcompare */
197 0, /* tp_weaklistoffset */
198 0, /* tp_iter */
199 0, /* tp_iternext */
200 0, /* tp_methods */
201 0, /* tp_members */
202 0, /* tp_getset */
203 0, /* tp_base */
204 0, /* tp_dict */
205 0, /* tp_descr_get */
206 0, /* tp_descr_set */
207 0, /* tp_dictoffset */
208 0, /* tp_init */
209 0, /* tp_alloc */
210 0, /* tp_new */
211 0, /* tp_free */
Christian Heimes969fe572008-01-25 11:23:10 +0000212};
213
214int
215PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item)
216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 PyObject *obj;
218 DictRemoverObject *remover;
219 PyObject *proxy;
220 int result;
Christian Heimes969fe572008-01-25 11:23:10 +0000221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 obj = PyObject_CallObject((PyObject *)&DictRemover_Type, NULL);
223 if (obj == NULL)
224 return -1;
Christian Heimes969fe572008-01-25 11:23:10 +0000225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 remover = (DictRemoverObject *)obj;
227 assert(remover->key == NULL);
228 assert(remover->dict == NULL);
229 Py_INCREF(key);
230 remover->key = key;
231 Py_INCREF(dict);
232 remover->dict = dict;
Christian Heimes969fe572008-01-25 11:23:10 +0000233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 proxy = PyWeakref_NewProxy(item, obj);
235 Py_DECREF(obj);
236 if (proxy == NULL)
237 return -1;
Christian Heimes969fe572008-01-25 11:23:10 +0000238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 result = PyDict_SetItem(dict, key, proxy);
240 Py_DECREF(proxy);
241 return result;
Christian Heimes969fe572008-01-25 11:23:10 +0000242}
243
244PyObject *
245PyDict_GetItemProxy(PyObject *dict, PyObject *key)
246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 PyObject *result;
248 PyObject *item = PyDict_GetItem(dict, key);
Christian Heimes969fe572008-01-25 11:23:10 +0000249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 if (item == NULL)
251 return NULL;
252 if (!PyWeakref_CheckProxy(item))
253 return item;
254 result = PyWeakref_GET_OBJECT(item);
255 if (result == Py_None)
256 return NULL;
257 return result;
Christian Heimes969fe572008-01-25 11:23:10 +0000258}
259
Thomas Hellerd4c93202006-03-08 19:35:11 +0000260/******************************************************************/
261/*
Thomas Hellerb041fda2008-04-30 17:11:46 +0000262 Allocate a memory block for a pep3118 format string, copy prefix (if
263 non-null) and suffix into it. Returns NULL on failure, with the error
264 indicator set. If called with a suffix of NULL the error indicator must
265 already be set.
266 */
267char *
Thomas Heller34596a92009-04-24 20:50:00 +0000268_ctypes_alloc_format_string(const char *prefix, const char *suffix)
Thomas Hellerb041fda2008-04-30 17:11:46 +0000269{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 size_t len;
271 char *result;
Thomas Hellerb041fda2008-04-30 17:11:46 +0000272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 if (suffix == NULL) {
274 assert(PyErr_Occurred());
275 return NULL;
276 }
277 len = strlen(suffix);
278 if (prefix)
279 len += strlen(prefix);
280 result = PyMem_Malloc(len + 1);
281 if (result == NULL)
282 return NULL;
283 if (prefix)
284 strcpy(result, prefix);
285 else
286 result[0] = '\0';
287 strcat(result, suffix);
288 return result;
Thomas Hellerb041fda2008-04-30 17:11:46 +0000289}
290
291/*
Thomas Heller34596a92009-04-24 20:50:00 +0000292 PyCStructType_Type - a meta type/class. Creating a new class using this one as
Thomas Hellerd4c93202006-03-08 19:35:11 +0000293 __metaclass__ will call the contructor StructUnionType_new. It replaces the
294 tp_dict member with a new instance of StgDict, and initializes the C
295 accessible fields somehow.
296*/
297
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000298static PyCArgObject *
299StructUnionType_paramfunc(CDataObject *self)
300{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 PyCArgObject *parg;
302 StgDictObject *stgdict;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 parg = PyCArgObject_new();
305 if (parg == NULL)
306 return NULL;
307
308 parg->tag = 'V';
309 stgdict = PyObject_stgdict((PyObject *)self);
310 assert(stgdict); /* Cannot be NULL for structure/union instances */
311 parg->pffi_type = &stgdict->ffi_type_pointer;
312 /* For structure parameters (by value), parg->value doesn't contain the structure
313 data itself, instead parg->value.p *points* to the structure's data
314 See also _ctypes.c, function _call_function_pointer().
315 */
316 parg->value.p = self->b_ptr;
317 parg->size = self->b_size;
318 Py_INCREF(self);
319 parg->obj = (PyObject *)self;
320 return parg;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000321}
322
Thomas Hellerd4c93202006-03-08 19:35:11 +0000323static PyObject *
324StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 PyTypeObject *result;
327 PyObject *fields;
328 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 /* create the new instance (which is a class,
331 since we are a metatype!) */
332 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
333 if (!result)
334 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 /* keep this for bw compatibility */
337 if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
338 return (PyObject *)result;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 dict = (StgDictObject *)PyObject_CallObject((PyObject *)&PyCStgDict_Type, NULL);
341 if (!dict) {
342 Py_DECREF(result);
343 return NULL;
344 }
345 /* replace the class dict by our updated stgdict, which holds info
346 about storage requirements of the instances */
347 if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
348 Py_DECREF(result);
349 Py_DECREF((PyObject *)dict);
350 return NULL;
351 }
352 Py_DECREF(result->tp_dict);
353 result->tp_dict = (PyObject *)dict;
354 dict->format = _ctypes_alloc_format_string(NULL, "B");
355 if (dict->format == NULL) {
356 Py_DECREF(result);
357 return NULL;
358 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 dict->paramfunc = StructUnionType_paramfunc;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
363 if (!fields) {
364 StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 if (basedict == NULL)
367 return (PyObject *)result;
368 /* copy base dict */
369 if (-1 == PyCStgDict_clone(dict, basedict)) {
370 Py_DECREF(result);
371 return NULL;
372 }
373 dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
374 basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
375 return (PyObject *)result;
376 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
379 Py_DECREF(result);
380 return NULL;
381 }
382 return (PyObject *)result;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000383}
384
385static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000386PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 return StructUnionType_new(type, args, kwds, 1);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000389}
390
391static PyObject *
392UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 return StructUnionType_new(type, args, kwds, 0);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000395}
396
397static char from_address_doc[] =
398"C.from_address(integer) -> C instance\naccess a C instance at the specified address";
399
400static PyObject *
401CDataType_from_address(PyObject *type, PyObject *value)
402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 void *buf;
404 if (!PyLong_Check(value)) {
405 PyErr_SetString(PyExc_TypeError,
406 "integer expected");
407 return NULL;
408 }
409 buf = (void *)PyLong_AsVoidPtr(value);
410 if (PyErr_Occurred())
411 return NULL;
412 return PyCData_AtAddress(type, buf);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000413}
414
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000415static char from_buffer_doc[] =
416"C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer";
417
418static int
419KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);
420
421static PyObject *
422CDataType_from_buffer(PyObject *type, PyObject *args)
423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 void *buffer;
425 Py_ssize_t buffer_len;
426 Py_ssize_t offset = 0;
427 PyObject *obj, *result;
428 StgDictObject *dict = PyType_stgdict(type);
429 assert (dict);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 if (!PyArg_ParseTuple(args,
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000432#if (PY_VERSION_HEX < 0x02050000)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 "O|i:from_buffer",
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000434#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 "O|n:from_buffer",
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000436#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 &obj, &offset))
438 return NULL;
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len))
441 return NULL;
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 if (offset < 0) {
444 PyErr_SetString(PyExc_ValueError,
445 "offset cannot be negative");
446 return NULL;
447 }
448 if (dict->size > buffer_len - offset) {
449 PyErr_Format(PyExc_ValueError,
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000450#if (PY_VERSION_HEX < 0x02050000)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 "Buffer size too small (%d instead of at least %d bytes)",
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000452#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 "Buffer size too small (%zd instead of at least %zd bytes)",
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000454#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 buffer_len, dict->size + offset);
456 return NULL;
457 }
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 result = PyCData_AtAddress(type, (char *)buffer + offset);
460 if (result == NULL)
461 return NULL;
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 Py_INCREF(obj);
464 if (-1 == KeepRef((CDataObject *)result, -1, obj)) {
465 Py_DECREF(result);
466 return NULL;
467 }
468 return result;
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000469}
470
471static char from_buffer_copy_doc[] =
472"C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer";
473
474static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000475GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000476
477static PyObject *
478CDataType_from_buffer_copy(PyObject *type, PyObject *args)
479{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 const void *buffer;
481 Py_ssize_t buffer_len;
482 Py_ssize_t offset = 0;
483 PyObject *obj, *result;
484 StgDictObject *dict = PyType_stgdict(type);
485 assert (dict);
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 if (!PyArg_ParseTuple(args,
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000488#if (PY_VERSION_HEX < 0x02050000)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 "O|i:from_buffer",
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000490#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 "O|n:from_buffer",
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000492#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 &obj, &offset))
494 return NULL;
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 if (-1 == PyObject_AsReadBuffer(obj, (const void**)&buffer, &buffer_len))
497 return NULL;
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 if (offset < 0) {
500 PyErr_SetString(PyExc_ValueError,
501 "offset cannot be negative");
502 return NULL;
503 }
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 if (dict->size > buffer_len - offset) {
506 PyErr_Format(PyExc_ValueError,
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000507#if (PY_VERSION_HEX < 0x02050000)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 "Buffer size too small (%d instead of at least %d bytes)",
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000509#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 "Buffer size too small (%zd instead of at least %zd bytes)",
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000511#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 buffer_len, dict->size + offset);
513 return NULL;
514 }
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL);
517 if (result == NULL)
518 return NULL;
519 memcpy(((CDataObject *)result)->b_ptr,
520 (char *)buffer+offset, dict->size);
521 return result;
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000522}
523
Thomas Hellerd4c93202006-03-08 19:35:11 +0000524static char in_dll_doc[] =
525"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
526
527static PyObject *
528CDataType_in_dll(PyObject *type, PyObject *args)
529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 PyObject *dll;
531 char *name;
532 PyObject *obj;
533 void *handle;
534 void *address;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
537 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 obj = PyObject_GetAttrString(dll, "_handle");
540 if (!obj)
541 return NULL;
542 if (!PyLong_Check(obj)) {
543 PyErr_SetString(PyExc_TypeError,
544 "the _handle attribute of the second argument must be an integer");
545 Py_DECREF(obj);
546 return NULL;
547 }
548 handle = (void *)PyLong_AsVoidPtr(obj);
549 Py_DECREF(obj);
550 if (PyErr_Occurred()) {
551 PyErr_SetString(PyExc_ValueError,
552 "could not convert the _handle attribute to a pointer");
553 return NULL;
554 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000555
556#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000557 address = (void *)GetProcAddress(handle, name);
558 if (!address) {
559 PyErr_Format(PyExc_ValueError,
560 "symbol '%s' not found",
561 name);
562 return NULL;
563 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000564#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 address = (void *)ctypes_dlsym(handle, name);
566 if (!address) {
Thomas Hellerd4c93202006-03-08 19:35:11 +0000567#ifdef __CYGWIN__
568/* dlerror() isn't very helpful on cygwin */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 PyErr_Format(PyExc_ValueError,
570 "symbol '%s' not found (%s) ",
571 name);
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000572#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 PyErr_SetString(PyExc_ValueError, ctypes_dlerror());
Thomas Hellerd4c93202006-03-08 19:35:11 +0000574#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 return NULL;
576 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000577#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 return PyCData_AtAddress(type, address);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000579}
580
581static char from_param_doc[] =
582"Convert a Python object into a function call parameter.";
583
584static PyObject *
585CDataType_from_param(PyObject *type, PyObject *value)
586{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 PyObject *as_parameter;
Benjamin Peterson39530f82011-03-26 18:04:09 -0500588 int res = PyObject_IsInstance(value, type);
589 if (res == -1)
590 return NULL;
591 if (res) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 Py_INCREF(value);
593 return value;
594 }
595 if (PyCArg_CheckExact(value)) {
596 PyCArgObject *p = (PyCArgObject *)value;
597 PyObject *ob = p->obj;
598 const char *ob_name;
599 StgDictObject *dict;
600 dict = PyType_stgdict(type);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000601
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 /* If we got a PyCArgObject, we must check if the object packed in it
603 is an instance of the type's dict->proto */
Benjamin Peterson39530f82011-03-26 18:04:09 -0500604 if(dict && ob) {
605 res = PyObject_IsInstance(ob, dict->proto);
606 if (res == -1)
607 return NULL;
608 if (res) {
609 Py_INCREF(value);
610 return value;
611 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 }
613 ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
614 PyErr_Format(PyExc_TypeError,
615 "expected %s instance instead of pointer to %s",
616 ((PyTypeObject *)type)->tp_name, ob_name);
617 return NULL;
618 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000619
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
621 if (as_parameter) {
622 value = CDataType_from_param(type, as_parameter);
623 Py_DECREF(as_parameter);
624 return value;
625 }
626 PyErr_Format(PyExc_TypeError,
627 "expected %s instance instead of %s",
628 ((PyTypeObject *)type)->tp_name,
629 Py_TYPE(value)->tp_name);
630 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000631}
632
633static PyMethodDef CDataType_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 { "from_param", CDataType_from_param, METH_O, from_param_doc },
635 { "from_address", CDataType_from_address, METH_O, from_address_doc },
636 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
637 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
638 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
639 { NULL, NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +0000640};
641
642static PyObject *
Thomas Hellerfe8f8622006-03-14 19:53:09 +0000643CDataType_repeat(PyObject *self, Py_ssize_t length)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 if (length < 0)
646 return PyErr_Format(PyExc_ValueError,
647 "Array length must be >= 0, not %zd",
648 length);
649 return PyCArrayType_from_ctype(self, length);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000650}
651
652static PySequenceMethods CDataType_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 0, /* inquiry sq_length; */
654 0, /* binaryfunc sq_concat; */
655 CDataType_repeat, /* intargfunc sq_repeat; */
656 0, /* intargfunc sq_item; */
657 0, /* intintargfunc sq_slice; */
658 0, /* intobjargproc sq_ass_item; */
659 0, /* intintobjargproc sq_ass_slice; */
660 0, /* objobjproc sq_contains; */
661
662 0, /* binaryfunc sq_inplace_concat; */
663 0, /* intargfunc sq_inplace_repeat; */
Thomas Hellerd4c93202006-03-08 19:35:11 +0000664};
665
666static int
667CDataType_clear(PyTypeObject *self)
668{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000669 StgDictObject *dict = PyType_stgdict((PyObject *)self);
670 if (dict)
671 Py_CLEAR(dict->proto);
672 return PyType_Type.tp_clear((PyObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000673}
674
675static int
676CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
677{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000678 StgDictObject *dict = PyType_stgdict((PyObject *)self);
679 if (dict)
680 Py_VISIT(dict->proto);
681 return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000682}
683
684static int
Thomas Heller34596a92009-04-24 20:50:00 +0000685PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 /* XXX Should we disallow deleting _fields_? */
688 if (-1 == PyType_Type.tp_setattro(self, key, value))
689 return -1;
690
691 if (value && PyUnicode_Check(key) &&
692 /* XXX struni _PyUnicode_AsString can fail (also in other places)! */
693 0 == strcmp(_PyUnicode_AsString(key), "_fields_"))
694 return PyCStructUnionType_update_stgdict(self, value, 1);
695 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000696}
697
698
699static int
700UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
701{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 /* XXX Should we disallow deleting _fields_? */
703 if (-1 == PyObject_GenericSetAttr(self, key, value))
704 return -1;
705
706 if (PyUnicode_Check(key) &&
707 0 == strcmp(_PyUnicode_AsString(key), "_fields_"))
708 return PyCStructUnionType_update_stgdict(self, value, 0);
709 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000710}
711
712
Thomas Heller34596a92009-04-24 20:50:00 +0000713PyTypeObject PyCStructType_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 PyVarObject_HEAD_INIT(NULL, 0)
715 "_ctypes.PyCStructType", /* tp_name */
716 0, /* tp_basicsize */
717 0, /* tp_itemsize */
718 0, /* tp_dealloc */
719 0, /* tp_print */
720 0, /* tp_getattr */
721 0, /* tp_setattr */
722 0, /* tp_reserved */
723 0, /* tp_repr */
724 0, /* tp_as_number */
725 &CDataType_as_sequence, /* tp_as_sequence */
726 0, /* tp_as_mapping */
727 0, /* tp_hash */
728 0, /* tp_call */
729 0, /* tp_str */
730 0, /* tp_getattro */
731 PyCStructType_setattro, /* tp_setattro */
732 0, /* tp_as_buffer */
733 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
734 "metatype for the CData Objects", /* tp_doc */
735 (traverseproc)CDataType_traverse, /* tp_traverse */
736 (inquiry)CDataType_clear, /* tp_clear */
737 0, /* tp_richcompare */
738 0, /* tp_weaklistoffset */
739 0, /* tp_iter */
740 0, /* tp_iternext */
741 CDataType_methods, /* tp_methods */
742 0, /* tp_members */
743 0, /* tp_getset */
744 0, /* tp_base */
745 0, /* tp_dict */
746 0, /* tp_descr_get */
747 0, /* tp_descr_set */
748 0, /* tp_dictoffset */
749 0, /* tp_init */
750 0, /* tp_alloc */
751 PyCStructType_new, /* tp_new */
752 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +0000753};
754
755static PyTypeObject UnionType_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 PyVarObject_HEAD_INIT(NULL, 0)
757 "_ctypes.UnionType", /* tp_name */
758 0, /* tp_basicsize */
759 0, /* tp_itemsize */
760 0, /* tp_dealloc */
761 0, /* tp_print */
762 0, /* tp_getattr */
763 0, /* tp_setattr */
764 0, /* tp_reserved */
765 0, /* tp_repr */
766 0, /* tp_as_number */
767 &CDataType_as_sequence, /* tp_as_sequence */
768 0, /* tp_as_mapping */
769 0, /* tp_hash */
770 0, /* tp_call */
771 0, /* tp_str */
772 0, /* tp_getattro */
773 UnionType_setattro, /* tp_setattro */
774 0, /* tp_as_buffer */
775 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
776 "metatype for the CData Objects", /* tp_doc */
777 (traverseproc)CDataType_traverse, /* tp_traverse */
778 (inquiry)CDataType_clear, /* tp_clear */
779 0, /* tp_richcompare */
780 0, /* tp_weaklistoffset */
781 0, /* tp_iter */
782 0, /* tp_iternext */
783 CDataType_methods, /* tp_methods */
784 0, /* tp_members */
785 0, /* tp_getset */
786 0, /* tp_base */
787 0, /* tp_dict */
788 0, /* tp_descr_get */
789 0, /* tp_descr_set */
790 0, /* tp_dictoffset */
791 0, /* tp_init */
792 0, /* tp_alloc */
793 UnionType_new, /* tp_new */
794 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +0000795};
796
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797
Thomas Hellerd4c93202006-03-08 19:35:11 +0000798/******************************************************************/
799
800/*
801
Thomas Heller34596a92009-04-24 20:50:00 +0000802The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be
Thomas Hellerd4c93202006-03-08 19:35:11 +0000803created. It must check for a _type_ attribute in the class. Since are no
804runtime created properties, a CField is probably *not* needed ?
805
806class IntPointer(Pointer):
807 _type_ = "i"
808
Thomas Heller34596a92009-04-24 20:50:00 +0000809The PyCPointer_Type provides the functionality: a contents method/property, a
Thomas Hellerd4c93202006-03-08 19:35:11 +0000810size property/method, and the sequence protocol.
811
812*/
813
814static int
Thomas Heller34596a92009-04-24 20:50:00 +0000815PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000816{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 if (!proto || !PyType_Check(proto)) {
818 PyErr_SetString(PyExc_TypeError,
819 "_type_ must be a type");
820 return -1;
821 }
822 if (!PyType_stgdict(proto)) {
823 PyErr_SetString(PyExc_TypeError,
824 "_type_ must have storage info");
825 return -1;
826 }
827 Py_INCREF(proto);
828 Py_XDECREF(stgdict->proto);
829 stgdict->proto = proto;
830 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000831}
832
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000833static PyCArgObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000834PyCPointerType_paramfunc(CDataObject *self)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 PyCArgObject *parg;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 parg = PyCArgObject_new();
839 if (parg == NULL)
840 return NULL;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 parg->tag = 'P';
843 parg->pffi_type = &ffi_type_pointer;
844 Py_INCREF(self);
845 parg->obj = (PyObject *)self;
846 parg->value.p = *(void **)self->b_ptr;
847 return parg;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000848}
849
Thomas Hellerd4c93202006-03-08 19:35:11 +0000850static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000851PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000852{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 PyTypeObject *result;
854 StgDictObject *stgdict;
855 PyObject *proto;
856 PyObject *typedict;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 typedict = PyTuple_GetItem(args, 2);
859 if (!typedict)
860 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000861/*
862 stgdict items size, align, length contain info about pointers itself,
863 stgdict->proto has info about the pointed to type!
864*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 stgdict = (StgDictObject *)PyObject_CallObject(
866 (PyObject *)&PyCStgDict_Type, NULL);
867 if (!stgdict)
868 return NULL;
869 stgdict->size = sizeof(void *);
870 stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
871 stgdict->length = 1;
872 stgdict->ffi_type_pointer = ffi_type_pointer;
873 stgdict->paramfunc = PyCPointerType_paramfunc;
874 stgdict->flags |= TYPEFLAG_ISPOINTER;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
877 if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) {
878 Py_DECREF((PyObject *)stgdict);
879 return NULL;
880 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000881
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000882 if (proto) {
883 StgDictObject *itemdict = PyType_stgdict(proto);
884 assert(itemdict);
885 /* If itemdict->format is NULL, then this is a pointer to an
886 incomplete type. We create a generic format string
887 'pointer to bytes' in this case. XXX Better would be to
888 fix the format string later...
889 */
890 stgdict->format = _ctypes_alloc_format_string("&",
891 itemdict->format ? itemdict->format : "B");
892 if (stgdict->format == NULL) {
893 Py_DECREF((PyObject *)stgdict);
894 return NULL;
895 }
896 }
Thomas Hellerb041fda2008-04-30 17:11:46 +0000897
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 /* create the new instance (which is a class,
899 since we are a metatype!) */
900 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
901 if (result == NULL) {
902 Py_DECREF((PyObject *)stgdict);
903 return NULL;
904 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 /* replace the class dict by our updated spam dict */
907 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
908 Py_DECREF(result);
909 Py_DECREF((PyObject *)stgdict);
910 return NULL;
911 }
912 Py_DECREF(result->tp_dict);
913 result->tp_dict = (PyObject *)stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000914
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 return (PyObject *)result;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000916}
917
918
919static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000920PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 dict = PyType_stgdict((PyObject *)self);
925 assert(dict);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 if (-1 == PyCPointerType_SetProto(dict, type))
928 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
931 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 Py_INCREF(Py_None);
934 return Py_None;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000935}
936
Neal Norwitz227b5332006-03-22 09:28:35 +0000937static PyObject *_byref(PyObject *);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000938
939static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000940PyCPointerType_from_param(PyObject *type, PyObject *value)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000941{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 StgDictObject *typedict;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 if (value == Py_None) {
945 /* ConvParam will convert to a NULL pointer later */
946 Py_INCREF(value);
947 return value;
948 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 typedict = PyType_stgdict(type);
951 assert(typedict); /* Cannot be NULL for pointer types */
Thomas Hellerd4c93202006-03-08 19:35:11 +0000952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 /* If we expect POINTER(<type>), but receive a <type> instance, accept
954 it by calling byref(<type>).
955 */
956 switch (PyObject_IsInstance(value, typedict->proto)) {
957 case 1:
958 Py_INCREF(value); /* _byref steals a refcount */
959 return _byref(value);
960 case -1:
Benjamin Peterson39530f82011-03-26 18:04:09 -0500961 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 default:
963 break;
964 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 if (PointerObject_Check(value) || ArrayObject_Check(value)) {
967 /* Array instances are also pointers when
968 the item types are the same.
969 */
970 StgDictObject *v = PyObject_stgdict(value);
971 assert(v); /* Cannot be NULL for pointer or array objects */
972 if (PyObject_IsSubclass(v->proto, typedict->proto)) {
973 Py_INCREF(value);
974 return value;
975 }
976 }
977 return CDataType_from_param(type, value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000978}
979
Thomas Heller34596a92009-04-24 20:50:00 +0000980static PyMethodDef PyCPointerType_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 { "from_address", CDataType_from_address, METH_O, from_address_doc },
982 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
983 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
984 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
985 { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc},
986 { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O },
987 { NULL, NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +0000988};
989
Thomas Heller34596a92009-04-24 20:50:00 +0000990PyTypeObject PyCPointerType_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 PyVarObject_HEAD_INIT(NULL, 0)
992 "_ctypes.PyCPointerType", /* tp_name */
993 0, /* tp_basicsize */
994 0, /* tp_itemsize */
995 0, /* tp_dealloc */
996 0, /* tp_print */
997 0, /* tp_getattr */
998 0, /* tp_setattr */
999 0, /* tp_reserved */
1000 0, /* tp_repr */
1001 0, /* tp_as_number */
1002 &CDataType_as_sequence, /* tp_as_sequence */
1003 0, /* tp_as_mapping */
1004 0, /* tp_hash */
1005 0, /* tp_call */
1006 0, /* tp_str */
1007 0, /* tp_getattro */
1008 0, /* tp_setattro */
1009 0, /* tp_as_buffer */
1010 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1011 "metatype for the Pointer Objects", /* tp_doc */
1012 (traverseproc)CDataType_traverse, /* tp_traverse */
1013 (inquiry)CDataType_clear, /* tp_clear */
1014 0, /* tp_richcompare */
1015 0, /* tp_weaklistoffset */
1016 0, /* tp_iter */
1017 0, /* tp_iternext */
1018 PyCPointerType_methods, /* tp_methods */
1019 0, /* tp_members */
1020 0, /* tp_getset */
1021 0, /* tp_base */
1022 0, /* tp_dict */
1023 0, /* tp_descr_get */
1024 0, /* tp_descr_set */
1025 0, /* tp_dictoffset */
1026 0, /* tp_init */
1027 0, /* tp_alloc */
1028 PyCPointerType_new, /* tp_new */
1029 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00001030};
1031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032
Thomas Hellerd4c93202006-03-08 19:35:11 +00001033/******************************************************************/
1034/*
Thomas Heller34596a92009-04-24 20:50:00 +00001035 PyCArrayType_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00001036*/
1037/*
Thomas Heller34596a92009-04-24 20:50:00 +00001038 PyCArrayType_new ensures that the new Array subclass created has a _length_
Thomas Hellerd4c93202006-03-08 19:35:11 +00001039 attribute, and a _type_ attribute.
1040*/
1041
1042static int
1043CharArray_set_raw(CDataObject *self, PyObject *value)
1044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 char *ptr;
1046 Py_ssize_t size;
1047 Py_buffer view;
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
Travis E. Oliphantb99f7622007-08-18 11:21:56 +00001050 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 size = view.len;
1052 ptr = view.buf;
1053 if (size > self->b_size) {
1054 PyErr_SetString(PyExc_ValueError,
1055 "string too long");
1056 goto fail;
1057 }
1058
1059 memcpy(self->b_ptr, ptr, size);
1060
1061 PyBuffer_Release(&view);
1062 return 0;
1063 fail:
1064 PyBuffer_Release(&view);
1065 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001066}
1067
1068static PyObject *
1069CharArray_get_raw(CDataObject *self)
1070{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 return PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001072}
1073
1074static PyObject *
1075CharArray_get_value(CDataObject *self)
1076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 int i;
1078 char *ptr = self->b_ptr;
1079 for (i = 0; i < self->b_size; ++i)
1080 if (*ptr++ == '\0')
1081 break;
1082 return PyBytes_FromStringAndSize(self->b_ptr, i);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001083}
1084
1085static int
1086CharArray_set_value(CDataObject *self, PyObject *value)
1087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 char *ptr;
1089 Py_ssize_t size;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 if (value == NULL) {
1092 PyErr_SetString(PyExc_TypeError,
1093 "can't delete attribute");
1094 return -1;
1095 }
Christian Heimes99170a52007-12-19 02:07:34 +00001096
Victor Stinnercf448832010-07-28 00:15:03 +00001097 if (!PyBytes_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 PyErr_Format(PyExc_TypeError,
Meador Inge65992c12012-01-26 08:44:00 -06001099 "bytes expected instead of %s instance",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 Py_TYPE(value)->tp_name);
1101 return -1;
1102 } else
1103 Py_INCREF(value);
1104 size = PyBytes_GET_SIZE(value);
1105 if (size > self->b_size) {
1106 PyErr_SetString(PyExc_ValueError,
1107 "string too long");
1108 Py_DECREF(value);
1109 return -1;
1110 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 ptr = PyBytes_AS_STRING(value);
1113 memcpy(self->b_ptr, ptr, size);
1114 if (size < self->b_size)
1115 self->b_ptr[size] = '\0';
1116 Py_DECREF(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001117
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001119}
1120
1121static PyGetSetDef CharArray_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
1123 "value", NULL },
1124 { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
1125 "string value"},
1126 { NULL, NULL }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001127};
1128
1129#ifdef CTYPES_UNICODE
1130static PyObject *
1131WCharArray_get_value(CDataObject *self)
1132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 unsigned int i;
1134 wchar_t *ptr = (wchar_t *)self->b_ptr;
1135 for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
1136 if (*ptr++ == (wchar_t)0)
1137 break;
1138 return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001139}
1140
1141static int
1142WCharArray_set_value(CDataObject *self, PyObject *value)
1143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 Py_ssize_t result = 0;
Victor Stinnerea90e0f2011-11-21 02:11:26 +01001145 Py_UNICODE *wstr;
1146 Py_ssize_t len;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 if (value == NULL) {
1149 PyErr_SetString(PyExc_TypeError,
1150 "can't delete attribute");
1151 return -1;
1152 }
Victor Stinnercf448832010-07-28 00:15:03 +00001153 if (!PyUnicode_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001154 PyErr_Format(PyExc_TypeError,
1155 "unicode string expected instead of %s instance",
1156 Py_TYPE(value)->tp_name);
1157 return -1;
1158 } else
1159 Py_INCREF(value);
Victor Stinnerea90e0f2011-11-21 02:11:26 +01001160
1161 wstr = PyUnicode_AsUnicodeAndSize(value, &len);
1162 if (wstr == NULL)
1163 return -1;
1164 if ((unsigned)len > self->b_size/sizeof(wchar_t)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 PyErr_SetString(PyExc_ValueError,
1166 "string too long");
1167 result = -1;
1168 goto done;
1169 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001170 result = PyUnicode_AsWideChar(value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 (wchar_t *)self->b_ptr,
1172 self->b_size/sizeof(wchar_t));
1173 if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
1174 ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001175 done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 Py_DECREF(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 return result >= 0 ? 0 : -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001179}
1180
1181static PyGetSetDef WCharArray_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
1183 "string value"},
1184 { NULL, NULL }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001185};
1186#endif
1187
1188/*
1189 The next three functions copied from Python's typeobject.c.
1190
1191 They are used to attach methods, members, or getsets to a type *after* it
1192 has been created: Arrays of characters have additional getsets to treat them
1193 as strings.
1194 */
1195/*
1196static int
1197add_methods(PyTypeObject *type, PyMethodDef *meth)
1198{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 PyObject *dict = type->tp_dict;
1200 for (; meth->ml_name != NULL; meth++) {
1201 PyObject *descr;
1202 descr = PyDescr_NewMethod(type, meth);
1203 if (descr == NULL)
1204 return -1;
1205 if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
1206 return -1;
1207 Py_DECREF(descr);
1208 }
1209 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001210}
1211
1212static int
1213add_members(PyTypeObject *type, PyMemberDef *memb)
1214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 PyObject *dict = type->tp_dict;
1216 for (; memb->name != NULL; memb++) {
1217 PyObject *descr;
1218 descr = PyDescr_NewMember(type, memb);
1219 if (descr == NULL)
1220 return -1;
1221 if (PyDict_SetItemString(dict, memb->name, descr) < 0)
1222 return -1;
1223 Py_DECREF(descr);
1224 }
1225 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001226}
1227*/
1228
1229static int
1230add_getset(PyTypeObject *type, PyGetSetDef *gsp)
1231{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 PyObject *dict = type->tp_dict;
1233 for (; gsp->name != NULL; gsp++) {
1234 PyObject *descr;
1235 descr = PyDescr_NewGetSet(type, gsp);
1236 if (descr == NULL)
1237 return -1;
1238 if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
1239 return -1;
1240 Py_DECREF(descr);
1241 }
1242 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001243}
1244
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001245static PyCArgObject *
Thomas Heller34596a92009-04-24 20:50:00 +00001246PyCArrayType_paramfunc(CDataObject *self)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 PyCArgObject *p = PyCArgObject_new();
1249 if (p == NULL)
1250 return NULL;
1251 p->tag = 'P';
1252 p->pffi_type = &ffi_type_pointer;
1253 p->value.p = (char *)self->b_ptr;
1254 Py_INCREF(self);
1255 p->obj = (PyObject *)self;
1256 return p;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001257}
Thomas Hellerd4c93202006-03-08 19:35:11 +00001258
1259static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00001260PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 PyTypeObject *result;
1263 StgDictObject *stgdict;
1264 StgDictObject *itemdict;
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001265 PyObject *length_attr, *type_attr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 long length;
1267 int overflow;
1268 Py_ssize_t itemsize, itemalign;
1269 char buf[32];
Thomas Hellerd4c93202006-03-08 19:35:11 +00001270
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001271 /* create the new instance (which is a class,
1272 since we are a metatype!) */
1273 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1274 if (result == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001275 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001276
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001277 /* Initialize these variables to NULL so that we can simplify error
1278 handling by using Py_XDECREF. */
1279 stgdict = NULL;
1280 type_attr = NULL;
1281
1282 length_attr = PyObject_GetAttrString((PyObject *)result, "_length_");
1283 if (!length_attr || !PyLong_Check(length_attr)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 PyErr_SetString(PyExc_AttributeError,
1285 "class must define a '_length_' attribute, "
1286 "which must be a positive integer");
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001287 Py_XDECREF(length_attr);
1288 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 }
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001290 length = PyLong_AsLongAndOverflow(length_attr, &overflow);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 if (overflow) {
1292 PyErr_SetString(PyExc_OverflowError,
1293 "The '_length_' attribute is too large");
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001294 Py_DECREF(length_attr);
1295 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 }
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001297 Py_DECREF(length_attr);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001298
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001299 type_attr = PyObject_GetAttrString((PyObject *)result, "_type_");
1300 if (!type_attr) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 PyErr_SetString(PyExc_AttributeError,
1302 "class must define a '_type_' attribute");
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001303 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 stgdict = (StgDictObject *)PyObject_CallObject(
1307 (PyObject *)&PyCStgDict_Type, NULL);
1308 if (!stgdict)
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001309 goto error;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001310
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001311 itemdict = PyType_stgdict(type_attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 if (!itemdict) {
1313 PyErr_SetString(PyExc_TypeError,
1314 "_type_ must have storage info");
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001315 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 assert(itemdict->format);
1319 if (itemdict->format[0] == '(') {
1320 sprintf(buf, "(%ld,", length);
1321 stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1);
1322 } else {
1323 sprintf(buf, "(%ld)", length);
1324 stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format);
1325 }
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001326 if (stgdict->format == NULL)
1327 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 stgdict->ndim = itemdict->ndim + 1;
1329 stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t *) * stgdict->ndim);
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001330 if (stgdict->shape == NULL)
1331 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 stgdict->shape[0] = length;
1333 memmove(&stgdict->shape[1], itemdict->shape,
1334 sizeof(Py_ssize_t) * (stgdict->ndim - 1));
Thomas Hellerb041fda2008-04-30 17:11:46 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 itemsize = itemdict->size;
1337 if (length * itemsize < 0) {
1338 PyErr_SetString(PyExc_OverflowError,
1339 "array too large");
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001340 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 }
Guido van Rossumd8faa362007-04-27 19:54:29 +00001342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 itemalign = itemdict->align;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
1346 stgdict->flags |= TYPEFLAG_HASPOINTER;
Thomas Heller13394e92008-02-13 20:40:44 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 stgdict->size = itemsize * length;
1349 stgdict->align = itemalign;
1350 stgdict->length = length;
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001351 stgdict->proto = type_attr;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 stgdict->paramfunc = &PyCArrayType_paramfunc;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 /* Arrays are passed as pointers to function calls. */
1356 stgdict->ffi_type_pointer = ffi_type_pointer;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 /* replace the class dict by our updated spam dict */
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001359 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict))
1360 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 Py_DECREF(result->tp_dict);
1362 result->tp_dict = (PyObject *)stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 /* Special case for character arrays.
1365 A permanent annoyance: char arrays are also strings!
1366 */
1367 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
1368 if (-1 == add_getset(result, CharArray_getsets))
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001369 goto error;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001370#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
1372 if (-1 == add_getset(result, WCharArray_getsets))
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001373 goto error;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001374#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 return (PyObject *)result;
Amaury Forgeot d'Arcfaecc382011-08-30 22:02:51 +02001378error:
1379 Py_XDECREF((PyObject*)stgdict);
1380 Py_XDECREF(type_attr);
1381 Py_DECREF(result);
1382 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001383}
1384
Thomas Heller34596a92009-04-24 20:50:00 +00001385PyTypeObject PyCArrayType_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 PyVarObject_HEAD_INIT(NULL, 0)
1387 "_ctypes.PyCArrayType", /* tp_name */
1388 0, /* tp_basicsize */
1389 0, /* tp_itemsize */
1390 0, /* tp_dealloc */
1391 0, /* tp_print */
1392 0, /* tp_getattr */
1393 0, /* tp_setattr */
1394 0, /* tp_reserved */
1395 0, /* tp_repr */
1396 0, /* tp_as_number */
1397 &CDataType_as_sequence, /* tp_as_sequence */
1398 0, /* tp_as_mapping */
1399 0, /* tp_hash */
1400 0, /* tp_call */
1401 0, /* tp_str */
1402 0, /* tp_getattro */
1403 0, /* tp_setattro */
1404 0, /* tp_as_buffer */
1405 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1406 "metatype for the Array Objects", /* tp_doc */
1407 0, /* tp_traverse */
1408 0, /* tp_clear */
1409 0, /* tp_richcompare */
1410 0, /* tp_weaklistoffset */
1411 0, /* tp_iter */
1412 0, /* tp_iternext */
1413 CDataType_methods, /* tp_methods */
1414 0, /* tp_members */
1415 0, /* tp_getset */
1416 0, /* tp_base */
1417 0, /* tp_dict */
1418 0, /* tp_descr_get */
1419 0, /* tp_descr_set */
1420 0, /* tp_dictoffset */
1421 0, /* tp_init */
1422 0, /* tp_alloc */
1423 PyCArrayType_new, /* tp_new */
1424 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00001425};
1426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427
Thomas Hellerd4c93202006-03-08 19:35:11 +00001428/******************************************************************/
1429/*
Thomas Heller34596a92009-04-24 20:50:00 +00001430 PyCSimpleType_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00001431*/
1432/*
1433
Thomas Heller34596a92009-04-24 20:50:00 +00001434PyCSimpleType_new ensures that the new Simple_Type subclass created has a valid
Thomas Hellerd4c93202006-03-08 19:35:11 +00001435_type_ attribute.
1436
1437*/
1438
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001439static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv?g";
Thomas Hellerd4c93202006-03-08 19:35:11 +00001440
1441static PyObject *
1442c_wchar_p_from_param(PyObject *type, PyObject *value)
1443{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 PyObject *as_parameter;
Benjamin Peterson39530f82011-03-26 18:04:09 -05001445 int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 if (value == Py_None) {
1447 Py_INCREF(Py_None);
1448 return Py_None;
1449 }
1450 if (PyUnicode_Check(value) || PyBytes_Check(value)) {
1451 PyCArgObject *parg;
1452 struct fielddesc *fd = _ctypes_get_fielddesc("Z");
Thomas Hellerd4c93202006-03-08 19:35:11 +00001453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 parg = PyCArgObject_new();
1455 if (parg == NULL)
1456 return NULL;
1457 parg->pffi_type = &ffi_type_pointer;
1458 parg->tag = 'Z';
1459 parg->obj = fd->setfunc(&parg->value, value, 0);
1460 if (parg->obj == NULL) {
1461 Py_DECREF(parg);
1462 return NULL;
1463 }
1464 return (PyObject *)parg;
1465 }
Benjamin Peterson39530f82011-03-26 18:04:09 -05001466 res = PyObject_IsInstance(value, type);
1467 if (res == -1)
1468 return NULL;
1469 if (res) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 Py_INCREF(value);
1471 return value;
1472 }
1473 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1474 /* c_wchar array instance or pointer(c_wchar(...)) */
1475 StgDictObject *dt = PyObject_stgdict(value);
1476 StgDictObject *dict;
1477 assert(dt); /* Cannot be NULL for pointer or array objects */
1478 dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1479 if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1480 Py_INCREF(value);
1481 return value;
1482 }
1483 }
1484 if (PyCArg_CheckExact(value)) {
1485 /* byref(c_char(...)) */
1486 PyCArgObject *a = (PyCArgObject *)value;
1487 StgDictObject *dict = PyObject_stgdict(a->obj);
1488 if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1489 Py_INCREF(value);
1490 return value;
1491 }
1492 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1495 if (as_parameter) {
1496 value = c_wchar_p_from_param(type, as_parameter);
1497 Py_DECREF(as_parameter);
1498 return value;
1499 }
1500 /* XXX better message */
1501 PyErr_SetString(PyExc_TypeError,
1502 "wrong type");
1503 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001504}
1505
1506static PyObject *
1507c_char_p_from_param(PyObject *type, PyObject *value)
1508{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 PyObject *as_parameter;
Benjamin Peterson39530f82011-03-26 18:04:09 -05001510 int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 if (value == Py_None) {
1512 Py_INCREF(Py_None);
1513 return Py_None;
1514 }
Victor Stinnercf448832010-07-28 00:15:03 +00001515 if (PyBytes_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 PyCArgObject *parg;
1517 struct fielddesc *fd = _ctypes_get_fielddesc("z");
Thomas Hellerd4c93202006-03-08 19:35:11 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 parg = PyCArgObject_new();
1520 if (parg == NULL)
1521 return NULL;
1522 parg->pffi_type = &ffi_type_pointer;
1523 parg->tag = 'z';
1524 parg->obj = fd->setfunc(&parg->value, value, 0);
1525 if (parg->obj == NULL) {
1526 Py_DECREF(parg);
1527 return NULL;
1528 }
1529 return (PyObject *)parg;
1530 }
Benjamin Peterson39530f82011-03-26 18:04:09 -05001531 res = PyObject_IsInstance(value, type);
1532 if (res == -1)
1533 return NULL;
1534 if (res) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 Py_INCREF(value);
1536 return value;
1537 }
1538 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1539 /* c_char array instance or pointer(c_char(...)) */
1540 StgDictObject *dt = PyObject_stgdict(value);
1541 StgDictObject *dict;
1542 assert(dt); /* Cannot be NULL for pointer or array objects */
1543 dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1544 if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1545 Py_INCREF(value);
1546 return value;
1547 }
1548 }
1549 if (PyCArg_CheckExact(value)) {
1550 /* byref(c_char(...)) */
1551 PyCArgObject *a = (PyCArgObject *)value;
1552 StgDictObject *dict = PyObject_stgdict(a->obj);
1553 if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1554 Py_INCREF(value);
1555 return value;
1556 }
1557 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001558
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001559 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1560 if (as_parameter) {
1561 value = c_char_p_from_param(type, as_parameter);
1562 Py_DECREF(as_parameter);
1563 return value;
1564 }
1565 /* XXX better message */
1566 PyErr_SetString(PyExc_TypeError,
1567 "wrong type");
1568 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001569}
1570
1571static PyObject *
1572c_void_p_from_param(PyObject *type, PyObject *value)
1573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 StgDictObject *stgd;
1575 PyObject *as_parameter;
Benjamin Peterson39530f82011-03-26 18:04:09 -05001576 int res;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001577
1578/* None */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 if (value == Py_None) {
1580 Py_INCREF(Py_None);
1581 return Py_None;
1582 }
1583 /* Should probably allow buffer interface as well */
Thomas Hellerd4c93202006-03-08 19:35:11 +00001584/* int, long */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 if (PyLong_Check(value)) {
1586 PyCArgObject *parg;
1587 struct fielddesc *fd = _ctypes_get_fielddesc("P");
Thomas Hellerd4c93202006-03-08 19:35:11 +00001588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 parg = PyCArgObject_new();
1590 if (parg == NULL)
1591 return NULL;
1592 parg->pffi_type = &ffi_type_pointer;
1593 parg->tag = 'P';
1594 parg->obj = fd->setfunc(&parg->value, value, 0);
1595 if (parg->obj == NULL) {
1596 Py_DECREF(parg);
1597 return NULL;
1598 }
1599 return (PyObject *)parg;
1600 }
1601 /* XXX struni: remove later */
Thomas Hellerd4c93202006-03-08 19:35:11 +00001602/* string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 if (PyBytes_Check(value)) {
1604 PyCArgObject *parg;
1605 struct fielddesc *fd = _ctypes_get_fielddesc("z");
Thomas Hellerd4c93202006-03-08 19:35:11 +00001606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 parg = PyCArgObject_new();
1608 if (parg == NULL)
1609 return NULL;
1610 parg->pffi_type = &ffi_type_pointer;
1611 parg->tag = 'z';
1612 parg->obj = fd->setfunc(&parg->value, value, 0);
1613 if (parg->obj == NULL) {
1614 Py_DECREF(parg);
1615 return NULL;
1616 }
1617 return (PyObject *)parg;
1618 }
Thomas Heller3821e312007-07-12 19:38:33 +00001619/* bytes */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 if (PyByteArray_Check(value)) {
1621 PyCArgObject *parg;
1622 struct fielddesc *fd = _ctypes_get_fielddesc("z");
Thomas Heller3821e312007-07-12 19:38:33 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 parg = PyCArgObject_new();
1625 if (parg == NULL)
1626 return NULL;
1627 parg->pffi_type = &ffi_type_pointer;
1628 parg->tag = 'z';
1629 parg->obj = fd->setfunc(&parg->value, value, 0);
1630 if (parg->obj == NULL) {
1631 Py_DECREF(parg);
1632 return NULL;
1633 }
1634 return (PyObject *)parg;
1635 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001636/* unicode */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 if (PyUnicode_Check(value)) {
1638 PyCArgObject *parg;
1639 struct fielddesc *fd = _ctypes_get_fielddesc("Z");
Thomas Hellerd4c93202006-03-08 19:35:11 +00001640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 parg = PyCArgObject_new();
1642 if (parg == NULL)
1643 return NULL;
1644 parg->pffi_type = &ffi_type_pointer;
1645 parg->tag = 'Z';
1646 parg->obj = fd->setfunc(&parg->value, value, 0);
1647 if (parg->obj == NULL) {
1648 Py_DECREF(parg);
1649 return NULL;
1650 }
1651 return (PyObject *)parg;
1652 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001653/* c_void_p instance (or subclass) */
Benjamin Peterson39530f82011-03-26 18:04:09 -05001654 res = PyObject_IsInstance(value, type);
1655 if (res == -1)
1656 return NULL;
1657 if (res) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 /* c_void_p instances */
1659 Py_INCREF(value);
1660 return value;
1661 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001662/* ctypes array or pointer instance */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1664 /* Any array or pointer is accepted */
1665 Py_INCREF(value);
1666 return value;
1667 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001668/* byref(...) */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 if (PyCArg_CheckExact(value)) {
1670 /* byref(c_xxx()) */
1671 PyCArgObject *a = (PyCArgObject *)value;
1672 if (a->tag == 'P') {
1673 Py_INCREF(value);
1674 return value;
1675 }
1676 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001677/* function pointer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 if (PyCFuncPtrObject_Check(value)) {
1679 PyCArgObject *parg;
1680 PyCFuncPtrObject *func;
1681 func = (PyCFuncPtrObject *)value;
1682 parg = PyCArgObject_new();
1683 if (parg == NULL)
1684 return NULL;
1685 parg->pffi_type = &ffi_type_pointer;
1686 parg->tag = 'P';
1687 Py_INCREF(value);
1688 parg->value.p = *(void **)func->b_ptr;
1689 parg->obj = value;
1690 return (PyObject *)parg;
1691 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001692/* c_char_p, c_wchar_p */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693 stgd = PyObject_stgdict(value);
1694 if (stgd && CDataObject_Check(value) && stgd->proto && PyUnicode_Check(stgd->proto)) {
1695 PyCArgObject *parg;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001696
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 switch (_PyUnicode_AsString(stgd->proto)[0]) {
1698 case 'z': /* c_char_p */
1699 case 'Z': /* c_wchar_p */
1700 parg = PyCArgObject_new();
1701 if (parg == NULL)
1702 return NULL;
1703 parg->pffi_type = &ffi_type_pointer;
1704 parg->tag = 'Z';
1705 Py_INCREF(value);
1706 parg->obj = value;
1707 /* Remember: b_ptr points to where the pointer is stored! */
1708 parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
1709 return (PyObject *)parg;
1710 }
1711 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001712
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001713 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1714 if (as_parameter) {
1715 value = c_void_p_from_param(type, as_parameter);
1716 Py_DECREF(as_parameter);
1717 return value;
1718 }
1719 /* XXX better message */
1720 PyErr_SetString(PyExc_TypeError,
1721 "wrong type");
1722 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001723}
Thomas Hellerd4c93202006-03-08 19:35:11 +00001724
1725static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1726static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
1727static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1728
Thomas Hellerd4c93202006-03-08 19:35:11 +00001729static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 PyObject *proto, struct fielddesc *fmt)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 PyTypeObject *result;
1733 StgDictObject *stgdict;
1734 PyObject *name = PyTuple_GET_ITEM(args, 0);
1735 PyObject *newname;
1736 PyObject *swapped_args;
1737 static PyObject *suffix;
1738 Py_ssize_t i;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
1741 if (!swapped_args)
1742 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001743
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 if (suffix == NULL)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001745#ifdef WORDS_BIGENDIAN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 suffix = PyUnicode_InternFromString("_le");
Thomas Hellerd4c93202006-03-08 19:35:11 +00001747#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 suffix = PyUnicode_InternFromString("_be");
Thomas Hellerd4c93202006-03-08 19:35:11 +00001749#endif
1750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 newname = PyUnicode_Concat(name, suffix);
1752 if (newname == NULL) {
1753 return NULL;
1754 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 PyTuple_SET_ITEM(swapped_args, 0, newname);
1757 for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
1758 PyObject *v = PyTuple_GET_ITEM(args, i);
1759 Py_INCREF(v);
1760 PyTuple_SET_ITEM(swapped_args, i, v);
1761 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 /* create the new instance (which is a class,
1764 since we are a metatype!) */
1765 result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
1766 Py_DECREF(swapped_args);
1767 if (result == NULL)
1768 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 stgdict = (StgDictObject *)PyObject_CallObject(
1771 (PyObject *)&PyCStgDict_Type, NULL);
1772 if (!stgdict) /* XXX leaks result! */
1773 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 stgdict->ffi_type_pointer = *fmt->pffi_type;
1776 stgdict->align = fmt->pffi_type->alignment;
1777 stgdict->length = 0;
1778 stgdict->size = fmt->pffi_type->size;
1779 stgdict->setfunc = fmt->setfunc_swapped;
1780 stgdict->getfunc = fmt->getfunc_swapped;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 Py_INCREF(proto);
1783 stgdict->proto = proto;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001784
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 /* replace the class dict by our updated spam dict */
1786 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1787 Py_DECREF(result);
1788 Py_DECREF((PyObject *)stgdict);
1789 return NULL;
1790 }
1791 Py_DECREF(result->tp_dict);
1792 result->tp_dict = (PyObject *)stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001793
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001794 return (PyObject *)result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001795}
1796
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001797static PyCArgObject *
Thomas Heller34596a92009-04-24 20:50:00 +00001798PyCSimpleType_paramfunc(CDataObject *self)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001799{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 StgDictObject *dict;
1801 char *fmt;
1802 PyCArgObject *parg;
1803 struct fielddesc *fd;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 dict = PyObject_stgdict((PyObject *)self);
1806 assert(dict); /* Cannot be NULL for CDataObject instances */
1807 fmt = _PyUnicode_AsString(dict->proto);
1808 assert(fmt);
1809
1810 fd = _ctypes_get_fielddesc(fmt);
1811 assert(fd);
1812
1813 parg = PyCArgObject_new();
1814 if (parg == NULL)
1815 return NULL;
1816
1817 parg->tag = fmt[0];
1818 parg->pffi_type = fd->pffi_type;
1819 Py_INCREF(self);
1820 parg->obj = (PyObject *)self;
1821 memcpy(&parg->value, self->b_ptr, self->b_size);
1822 return parg;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001823}
Thomas Hellerd4c93202006-03-08 19:35:11 +00001824
1825static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00001826PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001827{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 PyTypeObject *result;
1829 StgDictObject *stgdict;
1830 PyObject *proto;
1831 const char *proto_str;
1832 Py_ssize_t proto_len;
1833 PyMethodDef *ml;
1834 struct fielddesc *fmt;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 /* create the new instance (which is a class,
1837 since we are a metatype!) */
1838 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1839 if (result == NULL)
1840 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001842 proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
1843 if (!proto) {
1844 PyErr_SetString(PyExc_AttributeError,
1845 "class must define a '_type_' attribute");
Guido van Rossum5e23d572007-07-09 11:17:33 +00001846 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 Py_XDECREF(proto);
1848 Py_XDECREF(result);
1849 return NULL;
1850 }
1851 if (PyUnicode_Check(proto)) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001852 proto_str = PyUnicode_AsUTF8AndSize(proto, &proto_len);
1853 if (!proto_str)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 } else {
1856 PyErr_SetString(PyExc_TypeError,
1857 "class must define a '_type_' string attribute");
1858 goto error;
1859 }
1860 if (proto_len != 1) {
1861 PyErr_SetString(PyExc_ValueError,
1862 "class must define a '_type_' attribute "
1863 "which must be a string of length 1");
1864 goto error;
1865 }
1866 if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
1867 PyErr_Format(PyExc_AttributeError,
1868 "class must define a '_type_' attribute which must be\n"
1869 "a single character string containing one of '%s'.",
1870 SIMPLE_TYPE_CHARS);
1871 goto error;
1872 }
1873 fmt = _ctypes_get_fielddesc(proto_str);
1874 if (fmt == NULL) {
1875 PyErr_Format(PyExc_ValueError,
1876 "_type_ '%s' not supported", proto_str);
1877 goto error;
1878 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001879
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 stgdict = (StgDictObject *)PyObject_CallObject(
1881 (PyObject *)&PyCStgDict_Type, NULL);
1882 if (!stgdict)
1883 goto error;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001884
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 stgdict->ffi_type_pointer = *fmt->pffi_type;
1886 stgdict->align = fmt->pffi_type->alignment;
1887 stgdict->length = 0;
1888 stgdict->size = fmt->pffi_type->size;
1889 stgdict->setfunc = fmt->setfunc;
1890 stgdict->getfunc = fmt->getfunc;
Thomas Hellerb041fda2008-04-30 17:11:46 +00001891#ifdef WORDS_BIGENDIAN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 stgdict->format = _ctypes_alloc_format_string(">", proto_str);
Thomas Hellerb041fda2008-04-30 17:11:46 +00001893#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 stgdict->format = _ctypes_alloc_format_string("<", proto_str);
Thomas Hellerb041fda2008-04-30 17:11:46 +00001895#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 if (stgdict->format == NULL) {
1897 Py_DECREF(result);
1898 Py_DECREF(proto);
1899 Py_DECREF((PyObject *)stgdict);
1900 return NULL;
1901 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001902
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001903 stgdict->paramfunc = PyCSimpleType_paramfunc;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001904/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 if (result->tp_base != &Simple_Type) {
1906 stgdict->setfunc = NULL;
1907 stgdict->getfunc = NULL;
1908 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001909*/
1910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 /* This consumes the refcount on proto which we have */
1912 stgdict->proto = proto;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 /* replace the class dict by our updated spam dict */
1915 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1916 Py_DECREF(result);
1917 Py_DECREF((PyObject *)stgdict);
1918 return NULL;
1919 }
1920 Py_DECREF(result->tp_dict);
1921 result->tp_dict = (PyObject *)stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 /* Install from_param class methods in ctypes base classes.
1924 Overrides the PyCSimpleType_from_param generic method.
1925 */
1926 if (result->tp_base == &Simple_Type) {
1927 switch (*proto_str) {
1928 case 'z': /* c_char_p */
1929 ml = &c_char_p_method;
1930 stgdict->flags |= TYPEFLAG_ISPOINTER;
1931 break;
1932 case 'Z': /* c_wchar_p */
1933 ml = &c_wchar_p_method;
1934 stgdict->flags |= TYPEFLAG_ISPOINTER;
1935 break;
1936 case 'P': /* c_void_p */
1937 ml = &c_void_p_method;
1938 stgdict->flags |= TYPEFLAG_ISPOINTER;
1939 break;
1940 case 's':
1941 case 'X':
1942 case 'O':
1943 ml = NULL;
1944 stgdict->flags |= TYPEFLAG_ISPOINTER;
1945 break;
1946 default:
1947 ml = NULL;
1948 break;
1949 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 if (ml) {
1952 PyObject *meth;
1953 int x;
1954 meth = PyDescr_NewClassMethod(result, ml);
1955 if (!meth)
1956 return NULL;
1957 x = PyDict_SetItemString(result->tp_dict,
1958 ml->ml_name,
1959 meth);
1960 Py_DECREF(meth);
1961 if (x == -1) {
1962 Py_DECREF(result);
1963 return NULL;
1964 }
1965 }
1966 }
1967
1968 if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
1969 PyObject *swapped = CreateSwappedType(type, args, kwds,
1970 proto, fmt);
1971 StgDictObject *sw_dict;
1972 if (swapped == NULL) {
1973 Py_DECREF(result);
1974 return NULL;
1975 }
1976 sw_dict = PyType_stgdict(swapped);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001977#ifdef WORDS_BIGENDIAN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
1979 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
1980 PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
1981 PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
1982 /* We are creating the type for the OTHER endian */
1983 sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001984#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
1986 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
1987 PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
1988 PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
1989 /* We are creating the type for the OTHER endian */
1990 sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001991#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 Py_DECREF(swapped);
1993 if (PyErr_Occurred()) {
1994 Py_DECREF(result);
1995 return NULL;
1996 }
1997 };
Thomas Hellerd4c93202006-03-08 19:35:11 +00001998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 return (PyObject *)result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002000}
2001
2002/*
2003 * This is a *class method*.
2004 * Convert a parameter into something that ConvParam can handle.
Thomas Hellerd4c93202006-03-08 19:35:11 +00002005 */
2006static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002007PyCSimpleType_from_param(PyObject *type, PyObject *value)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002008{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 StgDictObject *dict;
2010 char *fmt;
2011 PyCArgObject *parg;
2012 struct fielddesc *fd;
2013 PyObject *as_parameter;
Benjamin Peterson8d6c62d2011-03-26 17:56:28 -05002014 int res;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002015
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 /* If the value is already an instance of the requested type,
2017 we can use it as is */
Benjamin Peterson8d6c62d2011-03-26 17:56:28 -05002018 res = PyObject_IsInstance(value, type);
2019 if (res == -1)
2020 return NULL;
2021 if (res) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 Py_INCREF(value);
2023 return value;
2024 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002026 dict = PyType_stgdict(type);
2027 assert(dict);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 /* I think we can rely on this being a one-character string */
2030 fmt = _PyUnicode_AsString(dict->proto);
2031 assert(fmt);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002032
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002033 fd = _ctypes_get_fielddesc(fmt);
2034 assert(fd);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 parg = PyCArgObject_new();
2037 if (parg == NULL)
2038 return NULL;
2039
2040 parg->tag = fmt[0];
2041 parg->pffi_type = fd->pffi_type;
2042 parg->obj = fd->setfunc(&parg->value, value, 0);
2043 if (parg->obj)
2044 return (PyObject *)parg;
2045 PyErr_Clear();
2046 Py_DECREF(parg);
2047
2048 as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
2049 if (as_parameter) {
Benjamin Peterson8d6c62d2011-03-26 17:56:28 -05002050 if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
2051 Py_DECREF(as_parameter);
2052 return NULL;
2053 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002054 value = PyCSimpleType_from_param(type, as_parameter);
Benjamin Peterson8d6c62d2011-03-26 17:56:28 -05002055 Py_LeaveRecursiveCall();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 Py_DECREF(as_parameter);
2057 return value;
2058 }
2059 PyErr_SetString(PyExc_TypeError,
2060 "wrong type");
2061 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002062}
2063
Thomas Heller34596a92009-04-24 20:50:00 +00002064static PyMethodDef PyCSimpleType_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc },
2066 { "from_address", CDataType_from_address, METH_O, from_address_doc },
2067 { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
2068 { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
2069 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
2070 { NULL, NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +00002071};
2072
Thomas Heller34596a92009-04-24 20:50:00 +00002073PyTypeObject PyCSimpleType_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 PyVarObject_HEAD_INIT(NULL, 0)
2075 "_ctypes.PyCSimpleType", /* tp_name */
2076 0, /* tp_basicsize */
2077 0, /* tp_itemsize */
2078 0, /* tp_dealloc */
2079 0, /* tp_print */
2080 0, /* tp_getattr */
2081 0, /* tp_setattr */
2082 0, /* tp_reserved */
2083 0, /* tp_repr */
2084 0, /* tp_as_number */
2085 &CDataType_as_sequence, /* tp_as_sequence */
2086 0, /* tp_as_mapping */
2087 0, /* tp_hash */
2088 0, /* tp_call */
2089 0, /* tp_str */
2090 0, /* tp_getattro */
2091 0, /* tp_setattro */
2092 0, /* tp_as_buffer */
2093 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2094 "metatype for the PyCSimpleType Objects", /* tp_doc */
2095 0, /* tp_traverse */
2096 0, /* tp_clear */
2097 0, /* tp_richcompare */
2098 0, /* tp_weaklistoffset */
2099 0, /* tp_iter */
2100 0, /* tp_iternext */
2101 PyCSimpleType_methods, /* tp_methods */
2102 0, /* tp_members */
2103 0, /* tp_getset */
2104 0, /* tp_base */
2105 0, /* tp_dict */
2106 0, /* tp_descr_get */
2107 0, /* tp_descr_set */
2108 0, /* tp_dictoffset */
2109 0, /* tp_init */
2110 0, /* tp_alloc */
2111 PyCSimpleType_new, /* tp_new */
2112 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00002113};
2114
2115/******************************************************************/
2116/*
Thomas Heller34596a92009-04-24 20:50:00 +00002117 PyCFuncPtrType_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00002118 */
2119
2120static PyObject *
2121converters_from_argtypes(PyObject *ob)
2122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 PyObject *converters;
2124 Py_ssize_t i;
2125 Py_ssize_t nArgs;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 ob = PySequence_Tuple(ob); /* new reference */
2128 if (!ob) {
2129 PyErr_SetString(PyExc_TypeError,
2130 "_argtypes_ must be a sequence of types");
2131 return NULL;
2132 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002134 nArgs = PyTuple_GET_SIZE(ob);
2135 converters = PyTuple_New(nArgs);
2136 if (!converters)
2137 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002138
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 /* I have to check if this is correct. Using c_char, which has a size
2140 of 1, will be assumed to be pushed as only one byte!
2141 Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
2142 */
2143
2144 for (i = 0; i < nArgs; ++i) {
2145 PyObject *tp = PyTuple_GET_ITEM(ob, i);
2146 PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
2147 if (!cnv)
2148 goto argtypes_error_1;
2149 PyTuple_SET_ITEM(converters, i, cnv);
2150 }
2151 Py_DECREF(ob);
2152 return converters;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002153
2154 argtypes_error_1:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 Py_XDECREF(converters);
2156 Py_DECREF(ob);
2157 PyErr_Format(PyExc_TypeError,
2158 "item %zd in _argtypes_ has no from_param method",
2159 i+1);
2160 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002161}
2162
2163static int
2164make_funcptrtype_dict(StgDictObject *stgdict)
2165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 PyObject *ob;
2167 PyObject *converters = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002168
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
2170 stgdict->length = 1;
2171 stgdict->size = sizeof(void *);
2172 stgdict->setfunc = NULL;
2173 stgdict->getfunc = NULL;
2174 stgdict->ffi_type_pointer = ffi_type_pointer;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002176 ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
2177 if (!ob || !PyLong_Check(ob)) {
2178 PyErr_SetString(PyExc_TypeError,
2179 "class must define _flags_ which must be an integer");
2180 return -1;
2181 }
2182 stgdict->flags = PyLong_AS_LONG(ob) | TYPEFLAG_ISPOINTER;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 /* _argtypes_ is optional... */
2185 ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
2186 if (ob) {
2187 converters = converters_from_argtypes(ob);
2188 if (!converters)
2189 goto error;
2190 Py_INCREF(ob);
2191 stgdict->argtypes = ob;
2192 stgdict->converters = converters;
2193 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002195 ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
2196 if (ob) {
2197 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2198 PyErr_SetString(PyExc_TypeError,
2199 "_restype_ must be a type, a callable, or None");
2200 return -1;
2201 }
2202 Py_INCREF(ob);
2203 stgdict->restype = ob;
2204 stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
2205 if (stgdict->checker == NULL)
2206 PyErr_Clear();
2207 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002208/* XXX later, maybe.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002209 ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
2210 if (ob) {
2211 if (!PyCallable_Check(ob)) {
2212 PyErr_SetString(PyExc_TypeError,
2213 "_errcheck_ must be callable");
2214 return -1;
2215 }
2216 Py_INCREF(ob);
2217 stgdict->errcheck = ob;
2218 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002219*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002220 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002221
2222 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002223 Py_XDECREF(converters);
2224 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002225
2226}
2227
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002228static PyCArgObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002229PyCFuncPtrType_paramfunc(CDataObject *self)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002230{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002231 PyCArgObject *parg;
2232
2233 parg = PyCArgObject_new();
2234 if (parg == NULL)
2235 return NULL;
2236
2237 parg->tag = 'P';
2238 parg->pffi_type = &ffi_type_pointer;
2239 Py_INCREF(self);
2240 parg->obj = (PyObject *)self;
2241 parg->value.p = *(void **)self->b_ptr;
2242 return parg;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002243}
2244
Thomas Hellerd4c93202006-03-08 19:35:11 +00002245static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002246PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 PyTypeObject *result;
2249 StgDictObject *stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002251 stgdict = (StgDictObject *)PyObject_CallObject(
2252 (PyObject *)&PyCStgDict_Type, NULL);
2253 if (!stgdict)
2254 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002256 stgdict->paramfunc = PyCFuncPtrType_paramfunc;
2257 /* We do NOT expose the function signature in the format string. It
2258 is impossible, generally, because the only requirement for the
2259 argtypes items is that they have a .from_param method - we do not
2260 know the types of the arguments (although, in practice, most
2261 argtypes would be a ctypes type).
2262 */
2263 stgdict->format = _ctypes_alloc_format_string(NULL, "X{}");
2264 stgdict->flags |= TYPEFLAG_ISPOINTER;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002266 /* create the new instance (which is a class,
2267 since we are a metatype!) */
2268 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2269 if (result == NULL) {
2270 Py_DECREF((PyObject *)stgdict);
2271 return NULL;
2272 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 /* replace the class dict by our updated storage dict */
2275 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2276 Py_DECREF(result);
2277 Py_DECREF((PyObject *)stgdict);
2278 return NULL;
2279 }
2280 Py_DECREF(result->tp_dict);
2281 result->tp_dict = (PyObject *)stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002283 if (-1 == make_funcptrtype_dict(stgdict)) {
2284 Py_DECREF(result);
2285 return NULL;
2286 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 return (PyObject *)result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002289}
2290
Thomas Heller34596a92009-04-24 20:50:00 +00002291PyTypeObject PyCFuncPtrType_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002292 PyVarObject_HEAD_INIT(NULL, 0)
2293 "_ctypes.PyCFuncPtrType", /* tp_name */
2294 0, /* tp_basicsize */
2295 0, /* tp_itemsize */
2296 0, /* tp_dealloc */
2297 0, /* tp_print */
2298 0, /* tp_getattr */
2299 0, /* tp_setattr */
2300 0, /* tp_reserved */
2301 0, /* tp_repr */
2302 0, /* tp_as_number */
2303 &CDataType_as_sequence, /* tp_as_sequence */
2304 0, /* tp_as_mapping */
2305 0, /* tp_hash */
2306 0, /* tp_call */
2307 0, /* tp_str */
2308 0, /* tp_getattro */
2309 0, /* tp_setattro */
2310 0, /* tp_as_buffer */
2311 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2312 "metatype for C function pointers", /* tp_doc */
2313 (traverseproc)CDataType_traverse, /* tp_traverse */
2314 (inquiry)CDataType_clear, /* tp_clear */
2315 0, /* tp_richcompare */
2316 0, /* tp_weaklistoffset */
2317 0, /* tp_iter */
2318 0, /* tp_iternext */
2319 CDataType_methods, /* tp_methods */
2320 0, /* tp_members */
2321 0, /* tp_getset */
2322 0, /* tp_base */
2323 0, /* tp_dict */
2324 0, /* tp_descr_get */
2325 0, /* tp_descr_set */
2326 0, /* tp_dictoffset */
2327 0, /* tp_init */
2328 0, /* tp_alloc */
2329 PyCFuncPtrType_new, /* tp_new */
2330 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00002331};
2332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002333
Thomas Hellerd4c93202006-03-08 19:35:11 +00002334/*****************************************************************
2335 * Code to keep needed objects alive
2336 */
2337
2338static CDataObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002339PyCData_GetContainer(CDataObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 while (self->b_base)
2342 self = self->b_base;
2343 if (self->b_objects == NULL) {
2344 if (self->b_length) {
2345 self->b_objects = PyDict_New();
2346 } else {
2347 Py_INCREF(Py_None);
2348 self->b_objects = Py_None;
2349 }
2350 }
2351 return self;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002352}
2353
2354static PyObject *
2355GetKeepedObjects(CDataObject *target)
2356{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002357 return PyCData_GetContainer(target)->b_objects;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002358}
2359
2360static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002361unique_key(CDataObject *target, Py_ssize_t index)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 char string[256];
2364 char *cp = string;
2365 size_t bytes_left;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002367 assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
2368 cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2369 while (target->b_base) {
2370 bytes_left = sizeof(string) - (cp - string) - 1;
2371 /* Hex format needs 2 characters per byte */
2372 if (bytes_left < sizeof(Py_ssize_t) * 2) {
2373 PyErr_SetString(PyExc_ValueError,
2374 "ctypes object structure too deep");
2375 return NULL;
2376 }
2377 cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
2378 target = target->b_base;
2379 }
2380 return PyUnicode_FromStringAndSize(string, cp-string);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002381}
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002382
Thomas Hellerd4c93202006-03-08 19:35:11 +00002383/*
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002384 * Keep a reference to 'keep' in the 'target', at index 'index'.
2385 *
2386 * If 'keep' is None, do nothing.
2387 *
2388 * Otherwise create a dictionary (if it does not yet exist) id the root
2389 * objects 'b_objects' item, which will store the 'keep' object under a unique
2390 * key.
2391 *
2392 * The unique_key helper travels the target's b_base pointer down to the root,
2393 * building a string containing hex-formatted indexes found during traversal,
2394 * separated by colons.
2395 *
2396 * The index tuple is used as a key into the root object's b_objects dict.
2397 *
2398 * Note: This function steals a refcount of the third argument, even if it
2399 * fails!
Thomas Hellerd4c93202006-03-08 19:35:11 +00002400 */
2401static int
Thomas Hellerfe8f8622006-03-14 19:53:09 +00002402KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 int result;
2405 CDataObject *ob;
2406 PyObject *key;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002407
2408/* Optimization: no need to store None */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002409 if (keep == Py_None) {
2410 Py_DECREF(Py_None);
2411 return 0;
2412 }
2413 ob = PyCData_GetContainer(target);
2414 if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
2415 Py_XDECREF(ob->b_objects);
2416 ob->b_objects = keep; /* refcount consumed */
2417 return 0;
2418 }
2419 key = unique_key(target, index);
2420 if (key == NULL) {
2421 Py_DECREF(keep);
2422 return -1;
2423 }
2424 result = PyDict_SetItem(ob->b_objects, key, keep);
2425 Py_DECREF(key);
2426 Py_DECREF(keep);
2427 return result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002428}
2429
2430/******************************************************************/
2431/*
Thomas Heller34596a92009-04-24 20:50:00 +00002432 PyCData_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00002433 */
2434static int
Thomas Heller34596a92009-04-24 20:50:00 +00002435PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 Py_VISIT(self->b_objects);
2438 Py_VISIT((PyObject *)self->b_base);
2439 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002440}
2441
2442static int
Thomas Heller34596a92009-04-24 20:50:00 +00002443PyCData_clear(CDataObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002445 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
2446 assert(dict); /* Cannot be NULL for CDataObject instances */
2447 Py_CLEAR(self->b_objects);
2448 if ((self->b_needsfree)
2449 && ((size_t)dict->size > sizeof(self->b_value)))
2450 PyMem_Free(self->b_ptr);
2451 self->b_ptr = NULL;
2452 Py_CLEAR(self->b_base);
2453 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002454}
2455
2456static void
Thomas Heller34596a92009-04-24 20:50:00 +00002457PyCData_dealloc(PyObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002459 PyCData_clear((CDataObject *)self);
2460 Py_TYPE(self)->tp_free(self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002461}
2462
Thomas Heller34596a92009-04-24 20:50:00 +00002463static PyMemberDef PyCData_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002464 { "_b_base_", T_OBJECT,
2465 offsetof(CDataObject, b_base), READONLY,
2466 "the base object" },
2467 { "_b_needsfree_", T_INT,
2468 offsetof(CDataObject, b_needsfree), READONLY,
2469 "whether the object owns the memory or not" },
2470 { "_objects", T_OBJECT,
2471 offsetof(CDataObject, b_objects), READONLY,
2472 "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2473 { NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +00002474};
2475
Thomas Heller34596a92009-04-24 20:50:00 +00002476static int PyCData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002478 CDataObject *self = (CDataObject *)_self;
2479 StgDictObject *dict = PyObject_stgdict(_self);
2480 Py_ssize_t i;
Thomas Hellerb041fda2008-04-30 17:11:46 +00002481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002482 if (view == NULL) return 0;
Thomas Hellerb041fda2008-04-30 17:11:46 +00002483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002484 view->buf = self->b_ptr;
2485 view->obj = _self;
2486 Py_INCREF(_self);
2487 view->len = self->b_size;
2488 view->readonly = 0;
2489 /* use default format character if not set */
2490 view->format = dict->format ? dict->format : "B";
2491 view->ndim = dict->ndim;
2492 view->shape = dict->shape;
2493 view->itemsize = self->b_size;
Amaury Forgeot d'Arc326e1892011-08-30 21:40:20 +02002494 if (view->itemsize) {
2495 for (i = 0; i < view->ndim; ++i) {
2496 view->itemsize /= dict->shape[i];
2497 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002498 }
2499 view->strides = NULL;
2500 view->suboffsets = NULL;
2501 view->internal = NULL;
2502 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002503}
2504
Thomas Heller34596a92009-04-24 20:50:00 +00002505static PyBufferProcs PyCData_as_buffer = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002506 PyCData_NewGetBuffer,
2507 NULL,
Thomas Hellerd4c93202006-03-08 19:35:11 +00002508};
2509
2510/*
2511 * CData objects are mutable, so they cannot be hashable!
2512 */
Georg Brandld49bf5e2010-10-18 07:30:06 +00002513static Py_hash_t
Thomas Heller34596a92009-04-24 20:50:00 +00002514PyCData_nohash(PyObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002515{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002516 PyErr_SetString(PyExc_TypeError, "unhashable type");
2517 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002518}
2519
Thomas Heller13394e92008-02-13 20:40:44 +00002520static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002521PyCData_reduce(PyObject *_self, PyObject *args)
Thomas Heller13394e92008-02-13 20:40:44 +00002522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 CDataObject *self = (CDataObject *)_self;
Thomas Heller13394e92008-02-13 20:40:44 +00002524
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002525 if (PyObject_stgdict(_self)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
2526 PyErr_SetString(PyExc_ValueError,
2527 "ctypes objects containing pointers cannot be pickled");
2528 return NULL;
2529 }
2530 return Py_BuildValue("O(O(NN))",
2531 _unpickle,
2532 Py_TYPE(_self),
2533 PyObject_GetAttrString(_self, "__dict__"),
2534 PyBytes_FromStringAndSize(self->b_ptr, self->b_size));
Thomas Heller13394e92008-02-13 20:40:44 +00002535}
2536
2537static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002538PyCData_setstate(PyObject *_self, PyObject *args)
Thomas Heller13394e92008-02-13 20:40:44 +00002539{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002540 void *data;
2541 Py_ssize_t len;
2542 int res;
2543 PyObject *dict, *mydict;
2544 CDataObject *self = (CDataObject *)_self;
2545 if (!PyArg_ParseTuple(args, "Os#", &dict, &data, &len))
2546 return NULL;
2547 if (len > self->b_size)
2548 len = self->b_size;
2549 memmove(self->b_ptr, data, len);
2550 mydict = PyObject_GetAttrString(_self, "__dict__");
2551 res = PyDict_Update(mydict, dict);
2552 Py_DECREF(mydict);
2553 if (res == -1)
2554 return NULL;
2555 Py_INCREF(Py_None);
2556 return Py_None;
Thomas Heller13394e92008-02-13 20:40:44 +00002557}
2558
Thomas Hellerd4c93202006-03-08 19:35:11 +00002559/*
2560 * default __ctypes_from_outparam__ method returns self.
2561 */
2562static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002563PyCData_from_outparam(PyObject *self, PyObject *args)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002564{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002565 Py_INCREF(self);
2566 return self;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002567}
2568
Thomas Heller34596a92009-04-24 20:50:00 +00002569static PyMethodDef PyCData_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002570 { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
2571 { "__reduce__", PyCData_reduce, METH_NOARGS, },
2572 { "__setstate__", PyCData_setstate, METH_VARARGS, },
2573 { NULL, NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +00002574};
2575
Thomas Heller34596a92009-04-24 20:50:00 +00002576PyTypeObject PyCData_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002577 PyVarObject_HEAD_INIT(NULL, 0)
2578 "_ctypes._CData",
2579 sizeof(CDataObject), /* tp_basicsize */
2580 0, /* tp_itemsize */
2581 PyCData_dealloc, /* tp_dealloc */
2582 0, /* tp_print */
2583 0, /* tp_getattr */
2584 0, /* tp_setattr */
2585 0, /* tp_reserved */
2586 0, /* tp_repr */
2587 0, /* tp_as_number */
2588 0, /* tp_as_sequence */
2589 0, /* tp_as_mapping */
2590 PyCData_nohash, /* tp_hash */
2591 0, /* tp_call */
2592 0, /* tp_str */
2593 0, /* tp_getattro */
2594 0, /* tp_setattro */
2595 &PyCData_as_buffer, /* tp_as_buffer */
2596 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2597 "XXX to be provided", /* tp_doc */
2598 (traverseproc)PyCData_traverse, /* tp_traverse */
2599 (inquiry)PyCData_clear, /* tp_clear */
2600 0, /* tp_richcompare */
2601 0, /* tp_weaklistoffset */
2602 0, /* tp_iter */
2603 0, /* tp_iternext */
2604 PyCData_methods, /* tp_methods */
2605 PyCData_members, /* tp_members */
2606 0, /* tp_getset */
2607 0, /* tp_base */
2608 0, /* tp_dict */
2609 0, /* tp_descr_get */
2610 0, /* tp_descr_set */
2611 0, /* tp_dictoffset */
2612 0, /* tp_init */
2613 0, /* tp_alloc */
2614 0, /* tp_new */
2615 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00002616};
2617
Thomas Heller34596a92009-04-24 20:50:00 +00002618static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002620 if ((size_t)dict->size <= sizeof(obj->b_value)) {
2621 /* No need to call malloc, can use the default buffer */
2622 obj->b_ptr = (char *)&obj->b_value;
2623 /* The b_needsfree flag does not mean that we actually did
2624 call PyMem_Malloc to allocate the memory block; instead it
2625 means we are the *owner* of the memory and are responsible
2626 for freeing resources associated with the memory. This is
2627 also the reason that b_needsfree is exposed to Python.
2628 */
2629 obj->b_needsfree = 1;
2630 } else {
2631 /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2632 33% of the creation time for c_int().
2633 */
2634 obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2635 if (obj->b_ptr == NULL) {
2636 PyErr_NoMemory();
2637 return -1;
2638 }
2639 obj->b_needsfree = 1;
2640 memset(obj->b_ptr, 0, dict->size);
2641 }
2642 obj->b_size = dict->size;
2643 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002644}
2645
2646PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002647PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002649 CDataObject *cmem;
2650 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002651
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002652 assert(PyType_Check(type));
2653 dict = PyType_stgdict(type);
2654 if (!dict) {
2655 PyErr_SetString(PyExc_TypeError,
2656 "abstract class");
2657 return NULL;
2658 }
2659 dict->flags |= DICTFLAG_FINAL;
2660 cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2661 if (cmem == NULL)
2662 return NULL;
2663 assert(CDataObject_Check(cmem));
Thomas Hellerd4c93202006-03-08 19:35:11 +00002664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002665 cmem->b_length = dict->length;
2666 cmem->b_size = dict->size;
2667 if (base) { /* use base's buffer */
2668 assert(CDataObject_Check(base));
2669 cmem->b_ptr = adr;
2670 cmem->b_needsfree = 0;
2671 Py_INCREF(base);
2672 cmem->b_base = (CDataObject *)base;
2673 cmem->b_index = index;
2674 } else { /* copy contents of adr */
2675 if (-1 == PyCData_MallocBuffer(cmem, dict)) {
2676 return NULL;
2677 Py_DECREF(cmem);
2678 }
2679 memcpy(cmem->b_ptr, adr, dict->size);
2680 cmem->b_index = index;
2681 }
2682 return (PyObject *)cmem;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002683}
2684
2685/*
2686 Box a memory block into a CData instance.
2687*/
2688PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002689PyCData_AtAddress(PyObject *type, void *buf)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002690{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002691 CDataObject *pd;
2692 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002694 assert(PyType_Check(type));
2695 dict = PyType_stgdict(type);
2696 if (!dict) {
2697 PyErr_SetString(PyExc_TypeError,
2698 "abstract class");
2699 return NULL;
2700 }
2701 dict->flags |= DICTFLAG_FINAL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002703 pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2704 if (!pd)
2705 return NULL;
2706 assert(CDataObject_Check(pd));
2707 pd->b_ptr = (char *)buf;
2708 pd->b_length = dict->length;
2709 pd->b_size = dict->size;
2710 return (PyObject *)pd;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002711}
2712
2713/*
2714 This function returns TRUE for c_int, c_void_p, and these kind of
2715 classes. FALSE otherwise FALSE also for subclasses of c_int and
2716 such.
2717*/
Thomas Heller34596a92009-04-24 20:50:00 +00002718int _ctypes_simple_instance(PyObject *obj)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 PyTypeObject *type = (PyTypeObject *)obj;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002721
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002722 if (PyCSimpleTypeObject_Check(type))
2723 return type->tp_base != &Simple_Type;
2724 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002725}
2726
2727PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002728PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002729 Py_ssize_t index, Py_ssize_t size, char *adr)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002730{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002731 StgDictObject *dict;
2732 if (getfunc)
2733 return getfunc(adr, size);
2734 assert(type);
2735 dict = PyType_stgdict(type);
2736 if (dict && dict->getfunc && !_ctypes_simple_instance(type))
2737 return dict->getfunc(adr, size);
2738 return PyCData_FromBaseObj(type, src, index, adr);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002739}
2740
2741/*
Thomas Heller34596a92009-04-24 20:50:00 +00002742 Helper function for PyCData_set below.
Thomas Hellerd4c93202006-03-08 19:35:11 +00002743*/
2744static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002745_PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002746 Py_ssize_t size, char *ptr)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002748 CDataObject *src;
Benjamin Peterson39530f82011-03-26 18:04:09 -05002749 int err;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002751 if (setfunc)
2752 return setfunc(ptr, value, size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002753
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002754 if (!CDataObject_Check(value)) {
2755 StgDictObject *dict = PyType_stgdict(type);
2756 if (dict && dict->setfunc)
2757 return dict->setfunc(ptr, value, size);
2758 /*
2759 If value is a tuple, we try to call the type with the tuple
2760 and use the result!
2761 */
2762 assert(PyType_Check(type));
2763 if (PyTuple_Check(value)) {
2764 PyObject *ob;
2765 PyObject *result;
2766 ob = PyObject_CallObject(type, value);
2767 if (ob == NULL) {
2768 _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
2769 ((PyTypeObject *)type)->tp_name);
2770 return NULL;
2771 }
2772 result = _PyCData_set(dst, type, setfunc, ob,
2773 size, ptr);
2774 Py_DECREF(ob);
2775 return result;
2776 } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
2777 *(void **)ptr = NULL;
2778 Py_INCREF(Py_None);
2779 return Py_None;
2780 } else {
2781 PyErr_Format(PyExc_TypeError,
2782 "expected %s instance, got %s",
2783 ((PyTypeObject *)type)->tp_name,
2784 Py_TYPE(value)->tp_name);
2785 return NULL;
2786 }
2787 }
2788 src = (CDataObject *)value;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002789
Benjamin Peterson39530f82011-03-26 18:04:09 -05002790 err = PyObject_IsInstance(value, type);
2791 if (err == -1)
2792 return NULL;
2793 if (err) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002794 memcpy(ptr,
2795 src->b_ptr,
2796 size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002798 if (PyCPointerTypeObject_Check(type))
2799 /* XXX */;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002801 value = GetKeepedObjects(src);
2802 Py_INCREF(value);
2803 return value;
2804 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002806 if (PyCPointerTypeObject_Check(type)
2807 && ArrayObject_Check(value)) {
2808 StgDictObject *p1, *p2;
2809 PyObject *keep;
2810 p1 = PyObject_stgdict(value);
2811 assert(p1); /* Cannot be NULL for array instances */
2812 p2 = PyType_stgdict(type);
2813 assert(p2); /* Cannot be NULL for pointer types */
Thomas Hellerd4c93202006-03-08 19:35:11 +00002814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002815 if (p1->proto != p2->proto) {
2816 PyErr_Format(PyExc_TypeError,
2817 "incompatible types, %s instance instead of %s instance",
2818 Py_TYPE(value)->tp_name,
2819 ((PyTypeObject *)type)->tp_name);
2820 return NULL;
2821 }
2822 *(void **)ptr = src->b_ptr;
2823
2824 keep = GetKeepedObjects(src);
2825 /*
2826 We are assigning an array object to a field which represents
2827 a pointer. This has the same effect as converting an array
2828 into a pointer. So, again, we have to keep the whole object
2829 pointed to (which is the array in this case) alive, and not
2830 only it's object list. So we create a tuple, containing
2831 b_objects list PLUS the array itself, and return that!
2832 */
2833 return PyTuple_Pack(2, keep, value);
2834 }
2835 PyErr_Format(PyExc_TypeError,
2836 "incompatible types, %s instance instead of %s instance",
2837 Py_TYPE(value)->tp_name,
2838 ((PyTypeObject *)type)->tp_name);
2839 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002840}
2841
2842/*
2843 * Set a slice in object 'dst', which has the type 'type',
2844 * to the value 'value'.
2845 */
2846int
Thomas Heller34596a92009-04-24 20:50:00 +00002847PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002848 Py_ssize_t index, Py_ssize_t size, char *ptr)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002849{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002850 CDataObject *mem = (CDataObject *)dst;
2851 PyObject *result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002853 if (!CDataObject_Check(dst)) {
2854 PyErr_SetString(PyExc_TypeError,
2855 "not a ctype instance");
2856 return -1;
2857 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002859 result = _PyCData_set(mem, type, setfunc, value,
2860 size, ptr);
2861 if (result == NULL)
2862 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002863
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002864 /* KeepRef steals a refcount from it's last argument */
2865 /* If KeepRef fails, we are stumped. The dst memory block has already
2866 been changed */
2867 return KeepRef(mem, index, result);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002868}
2869
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002870
Thomas Hellerd4c93202006-03-08 19:35:11 +00002871/******************************************************************/
2872static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002873GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002875 CDataObject *obj;
2876 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002878 dict = PyType_stgdict((PyObject *)type);
2879 if (!dict) {
2880 PyErr_SetString(PyExc_TypeError,
2881 "abstract class");
2882 return NULL;
2883 }
2884 dict->flags |= DICTFLAG_FINAL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002886 obj = (CDataObject *)type->tp_alloc(type, 0);
2887 if (!obj)
2888 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002890 obj->b_base = NULL;
2891 obj->b_index = 0;
2892 obj->b_objects = NULL;
2893 obj->b_length = dict->length;
2894
2895 if (-1 == PyCData_MallocBuffer(obj, dict)) {
2896 Py_DECREF(obj);
2897 return NULL;
2898 }
2899 return (PyObject *)obj;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002900}
2901/*****************************************************************/
2902/*
Thomas Heller34596a92009-04-24 20:50:00 +00002903 PyCFuncPtr_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00002904*/
2905
Thomas Hellerd4c93202006-03-08 19:35:11 +00002906static int
Thomas Heller34596a92009-04-24 20:50:00 +00002907PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002908{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002909 if (ob && !PyCallable_Check(ob)) {
2910 PyErr_SetString(PyExc_TypeError,
2911 "the errcheck attribute must be callable");
2912 return -1;
2913 }
2914 Py_XDECREF(self->errcheck);
2915 Py_XINCREF(ob);
2916 self->errcheck = ob;
2917 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002918}
2919
2920static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002921PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002922{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002923 if (self->errcheck) {
2924 Py_INCREF(self->errcheck);
2925 return self->errcheck;
2926 }
2927 Py_INCREF(Py_None);
2928 return Py_None;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002929}
2930
2931static int
Thomas Heller34596a92009-04-24 20:50:00 +00002932PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002933{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002934 if (ob == NULL) {
2935 Py_XDECREF(self->restype);
2936 self->restype = NULL;
2937 Py_XDECREF(self->checker);
2938 self->checker = NULL;
2939 return 0;
2940 }
2941 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2942 PyErr_SetString(PyExc_TypeError,
2943 "restype must be a type, a callable, or None");
2944 return -1;
2945 }
2946 Py_XDECREF(self->checker);
2947 Py_XDECREF(self->restype);
2948 Py_INCREF(ob);
2949 self->restype = ob;
2950 self->checker = PyObject_GetAttrString(ob, "_check_retval_");
2951 if (self->checker == NULL)
2952 PyErr_Clear();
2953 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002954}
2955
2956static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002957PyCFuncPtr_get_restype(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002959 StgDictObject *dict;
2960 if (self->restype) {
2961 Py_INCREF(self->restype);
2962 return self->restype;
2963 }
2964 dict = PyObject_stgdict((PyObject *)self);
2965 assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
2966 if (dict->restype) {
2967 Py_INCREF(dict->restype);
2968 return dict->restype;
2969 } else {
2970 Py_INCREF(Py_None);
2971 return Py_None;
2972 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002973}
2974
2975static int
Thomas Heller34596a92009-04-24 20:50:00 +00002976PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002978 PyObject *converters;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002980 if (ob == NULL || ob == Py_None) {
2981 Py_XDECREF(self->converters);
2982 self->converters = NULL;
2983 Py_XDECREF(self->argtypes);
2984 self->argtypes = NULL;
2985 } else {
2986 converters = converters_from_argtypes(ob);
2987 if (!converters)
2988 return -1;
2989 Py_XDECREF(self->converters);
2990 self->converters = converters;
2991 Py_XDECREF(self->argtypes);
2992 Py_INCREF(ob);
2993 self->argtypes = ob;
2994 }
2995 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002996}
2997
2998static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002999PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003000{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003001 StgDictObject *dict;
3002 if (self->argtypes) {
3003 Py_INCREF(self->argtypes);
3004 return self->argtypes;
3005 }
3006 dict = PyObject_stgdict((PyObject *)self);
3007 assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3008 if (dict->argtypes) {
3009 Py_INCREF(dict->argtypes);
3010 return dict->argtypes;
3011 } else {
3012 Py_INCREF(Py_None);
3013 return Py_None;
3014 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003015}
3016
Thomas Heller34596a92009-04-24 20:50:00 +00003017static PyGetSetDef PyCFuncPtr_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003018 { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
3019 "a function to check for errors", NULL },
3020 { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
3021 "specify the result type", NULL },
3022 { "argtypes", (getter)PyCFuncPtr_get_argtypes,
3023 (setter)PyCFuncPtr_set_argtypes,
3024 "specify the argument types", NULL },
3025 { NULL, NULL }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003026};
3027
3028#ifdef MS_WIN32
3029static PPROC FindAddress(void *handle, char *name, PyObject *type)
3030{
Guido van Rossumcd16bf62007-06-13 18:07:49 +00003031#ifdef MS_WIN64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003032 /* win64 has no stdcall calling conv, so it should
3033 also not have the name mangling of it.
3034 */
3035 return (PPROC)GetProcAddress(handle, name);
Guido van Rossumcd16bf62007-06-13 18:07:49 +00003036#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003037 PPROC address;
3038 char *mangled_name;
3039 int i;
3040 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003041
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003042 address = (PPROC)GetProcAddress(handle, name);
3043 if (address)
3044 return address;
3045 if (((size_t)name & ~0xFFFF) == 0) {
3046 return NULL;
3047 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003048
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003049 dict = PyType_stgdict((PyObject *)type);
3050 /* It should not happen that dict is NULL, but better be safe */
3051 if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
3052 return address;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003054 /* for stdcall, try mangled names:
3055 funcname -> _funcname@<n>
3056 where n is 0, 4, 8, 12, ..., 128
3057 */
3058 mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
3059 if (!mangled_name)
3060 return NULL;
3061 for (i = 0; i < 32; ++i) {
3062 sprintf(mangled_name, "_%s@%d", name, i*4);
3063 address = (PPROC)GetProcAddress(handle, mangled_name);
3064 if (address)
3065 return address;
3066 }
3067 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00003068#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +00003069}
3070#endif
3071
3072/* Return 1 if usable, 0 else and exception set. */
3073static int
Guido van Rossumcd16bf62007-06-13 18:07:49 +00003074_check_outarg_type(PyObject *arg, Py_ssize_t index)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003076 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003078 if (PyCPointerTypeObject_Check(arg))
3079 return 1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003081 if (PyCArrayTypeObject_Check(arg))
3082 return 1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003084 dict = PyType_stgdict(arg);
3085 if (dict
3086 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
3087 && PyUnicode_Check(dict->proto)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003088/* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003089 && (strchr("PzZ", _PyUnicode_AsString(dict->proto)[0]))) {
3090 return 1;
3091 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003092
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003093 PyErr_Format(PyExc_TypeError,
3094 "'out' parameter %d must be a pointer type, not %s",
3095 Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
3096 PyType_Check(arg) ?
3097 ((PyTypeObject *)arg)->tp_name :
3098 Py_TYPE(arg)->tp_name);
3099 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003100}
3101
3102/* Returns 1 on success, 0 on error */
3103static int
3104_validate_paramflags(PyTypeObject *type, PyObject *paramflags)
3105{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003106 Py_ssize_t i, len;
3107 StgDictObject *dict;
3108 PyObject *argtypes;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00003109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003110 dict = PyType_stgdict((PyObject *)type);
3111 assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */
3112 argtypes = dict->argtypes;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003113
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003114 if (paramflags == NULL || dict->argtypes == NULL)
3115 return 1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003117 if (!PyTuple_Check(paramflags)) {
3118 PyErr_SetString(PyExc_TypeError,
3119 "paramflags must be a tuple or None");
3120 return 0;
3121 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003123 len = PyTuple_GET_SIZE(paramflags);
3124 if (len != PyTuple_GET_SIZE(dict->argtypes)) {
3125 PyErr_SetString(PyExc_ValueError,
3126 "paramflags must have the same length as argtypes");
3127 return 0;
3128 }
3129
3130 for (i = 0; i < len; ++i) {
3131 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3132 int flag;
3133 char *name;
3134 PyObject *defval;
3135 PyObject *typ;
3136 if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) {
3137 PyErr_SetString(PyExc_TypeError,
3138 "paramflags must be a sequence of (int [,string [,value]]) tuples");
3139 return 0;
3140 }
3141 typ = PyTuple_GET_ITEM(argtypes, i);
3142 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3143 case 0:
3144 case PARAMFLAG_FIN:
3145 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3146 case PARAMFLAG_FIN | PARAMFLAG_FOUT:
3147 break;
3148 case PARAMFLAG_FOUT:
3149 if (!_check_outarg_type(typ, i+1))
3150 return 0;
3151 break;
3152 default:
3153 PyErr_Format(PyExc_TypeError,
3154 "paramflag value %d not supported",
3155 flag);
3156 return 0;
3157 }
3158 }
3159 return 1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003160}
3161
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003162static int
3163_get_name(PyObject *obj, char **pname)
3164{
3165#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003166 if (PyLong_Check(obj)) {
3167 /* We have to use MAKEINTRESOURCEA for Windows CE.
3168 Works on Windows as well, of course.
3169 */
3170 *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF);
3171 return 1;
3172 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003173#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003174 if (PyBytes_Check(obj)) {
3175 *pname = PyBytes_AS_STRING(obj);
3176 return *pname ? 1 : 0;
3177 }
3178 if (PyUnicode_Check(obj)) {
3179 *pname = _PyUnicode_AsString(obj);
3180 return *pname ? 1 : 0;
3181 }
3182 PyErr_SetString(PyExc_TypeError,
3183 "function name must be string or integer");
3184 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003185}
3186
3187
Thomas Hellerd4c93202006-03-08 19:35:11 +00003188static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003189PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003190{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003191 char *name;
3192 int (* address)(void);
3193 PyObject *dll;
3194 PyObject *obj;
3195 PyCFuncPtrObject *self;
3196 void *handle;
3197 PyObject *paramflags = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003199 if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
3200 return NULL;
3201 if (paramflags == Py_None)
3202 paramflags = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003204 obj = PyObject_GetAttrString(dll, "_handle");
3205 if (!obj)
3206 return NULL;
3207 if (!PyLong_Check(obj)) {
3208 PyErr_SetString(PyExc_TypeError,
3209 "the _handle attribute of the second argument must be an integer");
3210 Py_DECREF(obj);
3211 return NULL;
3212 }
3213 handle = (void *)PyLong_AsVoidPtr(obj);
3214 Py_DECREF(obj);
3215 if (PyErr_Occurred()) {
3216 PyErr_SetString(PyExc_ValueError,
3217 "could not convert the _handle attribute to a pointer");
3218 return NULL;
3219 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003220
3221#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003222 address = FindAddress(handle, name, (PyObject *)type);
3223 if (!address) {
3224 if (!IS_INTRESOURCE(name))
3225 PyErr_Format(PyExc_AttributeError,
3226 "function '%s' not found",
3227 name);
3228 else
3229 PyErr_Format(PyExc_AttributeError,
3230 "function ordinal %d not found",
3231 (WORD)(size_t)name);
3232 return NULL;
3233 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003234#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003235 address = (PPROC)ctypes_dlsym(handle, name);
3236 if (!address) {
Thomas Hellerd4c93202006-03-08 19:35:11 +00003237#ifdef __CYGWIN__
3238/* dlerror() isn't very helpful on cygwin */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003239 PyErr_Format(PyExc_AttributeError,
3240 "function '%s' not found (%s) ",
3241 name);
Benjamin Petersond75fcb42009-02-19 04:22:03 +00003242#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003243 PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
Thomas Hellerd4c93202006-03-08 19:35:11 +00003244#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003245 return NULL;
3246 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003247#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003248 if (!_validate_paramflags(type, paramflags))
3249 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003251 self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3252 if (!self)
3253 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003255 Py_XINCREF(paramflags);
3256 self->paramflags = paramflags;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003258 *(void **)self->b_ptr = address;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003260 Py_INCREF((PyObject *)dll); /* for KeepRef */
3261 if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
3262 Py_DECREF((PyObject *)self);
3263 return NULL;
3264 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003266 Py_INCREF(self);
3267 self->callable = (PyObject *)self;
3268 return (PyObject *)self;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003269}
3270
3271#ifdef MS_WIN32
3272static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003273PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003274{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003275 PyCFuncPtrObject *self;
3276 int index;
3277 char *name = NULL;
3278 PyObject *paramflags = NULL;
3279 GUID *iid = NULL;
3280 Py_ssize_t iid_len = 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003282 if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
3283 return NULL;
3284 if (paramflags == Py_None)
3285 paramflags = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003287 if (!_validate_paramflags(type, paramflags))
3288 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003290 self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3291 self->index = index + 0x1000;
3292 Py_XINCREF(paramflags);
3293 self->paramflags = paramflags;
3294 if (iid_len == sizeof(GUID))
3295 self->iid = iid;
3296 return (PyObject *)self;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003297}
3298#endif
3299
3300/*
Thomas Heller34596a92009-04-24 20:50:00 +00003301 PyCFuncPtr_new accepts different argument lists in addition to the standard
Thomas Hellerd4c93202006-03-08 19:35:11 +00003302 _basespec_ keyword arg:
3303
3304 one argument form
3305 "i" - function address
3306 "O" - must be a callable, creates a C callable function
3307
3308 two or more argument forms (the third argument is a paramflags tuple)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003309 "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
3310 "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
3311 "is|..." - vtable index, method name, creates callable calling COM vtbl
Thomas Hellerd4c93202006-03-08 19:35:11 +00003312*/
3313static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003314PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003315{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003316 PyCFuncPtrObject *self;
3317 PyObject *callable;
3318 StgDictObject *dict;
3319 CThunkObject *thunk;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003321 if (PyTuple_GET_SIZE(args) == 0)
3322 return GenericPyCData_new(type, args, kwds);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003324 if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
3325 return PyCFuncPtr_FromDll(type, args, kwds);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003326
3327#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003328 if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0)))
3329 return PyCFuncPtr_FromVtblIndex(type, args, kwds);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003330#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +00003331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003332 if (1 == PyTuple_GET_SIZE(args)
3333 && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
3334 CDataObject *ob;
3335 void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
3336 if (ptr == NULL && PyErr_Occurred())
3337 return NULL;
3338 ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
3339 if (ob == NULL)
3340 return NULL;
3341 *(void **)ob->b_ptr = ptr;
3342 return (PyObject *)ob;
3343 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003345 if (!PyArg_ParseTuple(args, "O", &callable))
3346 return NULL;
3347 if (!PyCallable_Check(callable)) {
3348 PyErr_SetString(PyExc_TypeError,
3349 "argument must be callable or integer function address");
3350 return NULL;
3351 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003353 /* XXX XXX This would allow to pass additional options. For COM
3354 method *implementations*, we would probably want different
3355 behaviour than in 'normal' callback functions: return a HRESULT if
Ezio Melotti13925002011-03-16 11:05:33 +02003356 an exception occurs in the callback, and print the traceback not
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003357 only on the console, but also to OutputDebugString() or something
3358 like that.
3359 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00003360/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003361 if (kwds && PyDict_GetItemString(kwds, "options")) {
3362 ...
3363 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003364*/
3365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003366 dict = PyType_stgdict((PyObject *)type);
3367 /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
3368 if (!dict || !dict->argtypes) {
3369 PyErr_SetString(PyExc_TypeError,
3370 "cannot construct instance of this class:"
3371 " no argtypes");
3372 return NULL;
3373 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003375 thunk = _ctypes_alloc_callback(callable,
3376 dict->argtypes,
3377 dict->restype,
3378 dict->flags);
3379 if (!thunk)
3380 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003382 self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3383 if (self == NULL) {
3384 Py_DECREF(thunk);
3385 return NULL;
3386 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003388 Py_INCREF(callable);
3389 self->callable = callable;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003391 self->thunk = thunk;
Thomas Heller864cc672010-08-08 17:58:53 +00003392 *(void **)self->b_ptr = (void *)thunk->pcl_exec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003393
3394 Py_INCREF((PyObject *)thunk); /* for KeepRef */
3395 if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3396 Py_DECREF((PyObject *)self);
3397 return NULL;
3398 }
3399 return (PyObject *)self;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003400}
3401
3402
3403/*
3404 _byref consumes a refcount to its argument
3405*/
3406static PyObject *
3407_byref(PyObject *obj)
3408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003409 PyCArgObject *parg;
3410 if (!CDataObject_Check(obj)) {
3411 PyErr_SetString(PyExc_TypeError,
3412 "expected CData instance");
3413 return NULL;
3414 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003416 parg = PyCArgObject_new();
3417 if (parg == NULL) {
3418 Py_DECREF(obj);
3419 return NULL;
3420 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003422 parg->tag = 'P';
3423 parg->pffi_type = &ffi_type_pointer;
3424 parg->obj = obj;
3425 parg->value.p = ((CDataObject *)obj)->b_ptr;
3426 return (PyObject *)parg;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003427}
3428
3429static PyObject *
Guido van Rossum97f9d4f2007-10-24 18:41:19 +00003430_get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003432 PyObject *v;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003434 if (*pindex < PyTuple_GET_SIZE(inargs)) {
3435 v = PyTuple_GET_ITEM(inargs, *pindex);
3436 ++*pindex;
3437 Py_INCREF(v);
3438 return v;
3439 }
3440 if (kwds && (v = PyDict_GetItem(kwds, name))) {
3441 ++*pindex;
3442 Py_INCREF(v);
3443 return v;
3444 }
3445 if (defval) {
3446 Py_INCREF(defval);
3447 return defval;
3448 }
3449 /* we can't currently emit a better error message */
3450 if (name)
3451 PyErr_Format(PyExc_TypeError,
3452 "required argument '%S' missing", name);
3453 else
3454 PyErr_Format(PyExc_TypeError,
3455 "not enough arguments");
3456 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003457}
3458
3459/*
3460 This function implements higher level functionality plus the ability to call
3461 functions with keyword arguments by looking at parameter flags. parameter
3462 flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer
3463 specifying the direction of the data transfer for this parameter - 'in',
3464 'out' or 'inout' (zero means the same as 'in'). The second entry is the
3465 parameter name, and the third is the default value if the parameter is
3466 missing in the function call.
3467
3468 This function builds and returns a new tuple 'callargs' which contains the
3469 parameters to use in the call. Items on this tuple are copied from the
3470 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
3471 'argtypes' tuple for 'out' parameters. It also calculates numretvals which
3472 is the number of return values for the function, outmask/inoutmask are
3473 bitmasks containing indexes into the callargs tuple specifying which
3474 parameters have to be returned. _build_result builds the return value of the
3475 function.
3476*/
3477static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003478_build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003479 PyObject *inargs, PyObject *kwds,
3480 int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003481{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003482 PyObject *paramflags = self->paramflags;
3483 PyObject *callargs;
3484 StgDictObject *dict;
3485 Py_ssize_t i, len;
3486 int inargs_index = 0;
3487 /* It's a little bit difficult to determine how many arguments the
3488 function call requires/accepts. For simplicity, we count the consumed
3489 args and compare this to the number of supplied args. */
3490 Py_ssize_t actual_args;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003492 *poutmask = 0;
3493 *pinoutmask = 0;
3494 *pnumretvals = 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003496 /* Trivial cases, where we either return inargs itself, or a slice of it. */
3497 if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
Thomas Hellerd4c93202006-03-08 19:35:11 +00003498#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003499 if (self->index)
3500 return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
Thomas Hellerd4c93202006-03-08 19:35:11 +00003501#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003502 Py_INCREF(inargs);
3503 return inargs;
3504 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003506 len = PyTuple_GET_SIZE(argtypes);
3507 callargs = PyTuple_New(len); /* the argument tuple we build */
3508 if (callargs == NULL)
3509 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003510
3511#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003512 /* For a COM method, skip the first arg */
3513 if (self->index) {
3514 inargs_index = 1;
3515 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003516#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003517 for (i = 0; i < len; ++i) {
3518 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3519 PyObject *ob;
3520 int flag;
3521 PyObject *name = NULL;
3522 PyObject *defval = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003524 /* This way seems to be ~2 us faster than the PyArg_ParseTuple
3525 calls below. */
3526 /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
3527 Py_ssize_t tsize = PyTuple_GET_SIZE(item);
3528 flag = PyLong_AS_LONG(PyTuple_GET_ITEM(item, 0));
3529 name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
3530 defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003532 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3533 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3534 /* ['in', 'lcid'] parameter. Always taken from defval,
3535 if given, else the integer 0. */
3536 if (defval == NULL) {
3537 defval = PyLong_FromLong(0);
3538 if (defval == NULL)
3539 goto error;
3540 } else
3541 Py_INCREF(defval);
3542 PyTuple_SET_ITEM(callargs, i, defval);
3543 break;
3544 case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
3545 *pinoutmask |= (1 << i); /* mark as inout arg */
3546 (*pnumretvals)++;
3547 /* fall through to PARAMFLAG_FIN... */
3548 case 0:
3549 case PARAMFLAG_FIN:
3550 /* 'in' parameter. Copy it from inargs. */
3551 ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
3552 if (ob == NULL)
3553 goto error;
3554 PyTuple_SET_ITEM(callargs, i, ob);
3555 break;
3556 case PARAMFLAG_FOUT:
3557 /* XXX Refactor this code into a separate function. */
3558 /* 'out' parameter.
3559 argtypes[i] must be a POINTER to a c type.
Thomas Hellerd4c93202006-03-08 19:35:11 +00003560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003561 Cannot by supplied in inargs, but a defval will be used
3562 if available. XXX Should we support getting it from kwds?
3563 */
3564 if (defval) {
3565 /* XXX Using mutable objects as defval will
3566 make the function non-threadsafe, unless we
3567 copy the object in each invocation */
3568 Py_INCREF(defval);
3569 PyTuple_SET_ITEM(callargs, i, defval);
3570 *poutmask |= (1 << i); /* mark as out arg */
3571 (*pnumretvals)++;
3572 break;
3573 }
3574 ob = PyTuple_GET_ITEM(argtypes, i);
3575 dict = PyType_stgdict(ob);
3576 if (dict == NULL) {
3577 /* Cannot happen: _validate_paramflags()
3578 would not accept such an object */
3579 PyErr_Format(PyExc_RuntimeError,
3580 "NULL stgdict unexpected");
3581 goto error;
3582 }
3583 if (PyUnicode_Check(dict->proto)) {
3584 PyErr_Format(
3585 PyExc_TypeError,
3586 "%s 'out' parameter must be passed as default value",
3587 ((PyTypeObject *)ob)->tp_name);
3588 goto error;
3589 }
3590 if (PyCArrayTypeObject_Check(ob))
3591 ob = PyObject_CallObject(ob, NULL);
3592 else
3593 /* Create an instance of the pointed-to type */
3594 ob = PyObject_CallObject(dict->proto, NULL);
3595 /*
3596 XXX Is the following correct any longer?
3597 We must not pass a byref() to the array then but
3598 the array instance itself. Then, we cannot retrive
3599 the result from the PyCArgObject.
3600 */
3601 if (ob == NULL)
3602 goto error;
3603 /* The .from_param call that will ocurr later will pass this
3604 as a byref parameter. */
3605 PyTuple_SET_ITEM(callargs, i, ob);
3606 *poutmask |= (1 << i); /* mark as out arg */
3607 (*pnumretvals)++;
3608 break;
3609 default:
3610 PyErr_Format(PyExc_ValueError,
3611 "paramflag %d not yet implemented", flag);
3612 goto error;
3613 break;
3614 }
3615 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003616
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003617 /* We have counted the arguments we have consumed in 'inargs_index'. This
3618 must be the same as len(inargs) + len(kwds), otherwise we have
3619 either too much or not enough arguments. */
Thomas Hellerd4c93202006-03-08 19:35:11 +00003620
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003621 actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
3622 if (actual_args != inargs_index) {
3623 /* When we have default values or named parameters, this error
3624 message is misleading. See unittests/test_paramflags.py
3625 */
3626 PyErr_Format(PyExc_TypeError,
3627 "call takes exactly %d arguments (%zd given)",
3628 inargs_index, actual_args);
3629 goto error;
3630 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003632 /* outmask is a bitmask containing indexes into callargs. Items at
3633 these indexes contain values to return.
3634 */
3635 return callargs;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003636 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003637 Py_DECREF(callargs);
3638 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003639}
3640
3641/* See also:
3642 http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
3643*/
3644/*
3645 Build return value of a function.
3646
3647 Consumes the refcount on result and callargs.
3648*/
3649static PyObject *
3650_build_result(PyObject *result, PyObject *callargs,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003651 int outmask, int inoutmask, unsigned int numretvals)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003652{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003653 unsigned int i, index;
3654 int bit;
3655 PyObject *tup = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003657 if (callargs == NULL)
3658 return result;
3659 if (result == NULL || numretvals == 0) {
3660 Py_DECREF(callargs);
3661 return result;
3662 }
3663 Py_DECREF(result);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003665 /* tup will not be allocated if numretvals == 1 */
3666 /* allocate tuple to hold the result */
3667 if (numretvals > 1) {
3668 tup = PyTuple_New(numretvals);
3669 if (tup == NULL) {
3670 Py_DECREF(callargs);
3671 return NULL;
3672 }
3673 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003674
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003675 index = 0;
3676 for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
3677 PyObject *v;
3678 if (bit & inoutmask) {
3679 v = PyTuple_GET_ITEM(callargs, i);
3680 Py_INCREF(v);
3681 if (numretvals == 1) {
3682 Py_DECREF(callargs);
3683 return v;
3684 }
3685 PyTuple_SET_ITEM(tup, index, v);
3686 index++;
3687 } else if (bit & outmask) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003688 _Py_IDENTIFIER(__ctypes_from_outparam__);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003689
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003690 v = PyTuple_GET_ITEM(callargs, i);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003691 v = _PyObject_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003692 if (v == NULL || numretvals == 1) {
3693 Py_DECREF(callargs);
3694 return v;
3695 }
3696 PyTuple_SET_ITEM(tup, index, v);
3697 index++;
3698 }
3699 if (index == numretvals)
3700 break;
3701 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003703 Py_DECREF(callargs);
3704 return tup;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003705}
3706
3707static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003708PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003709{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003710 PyObject *restype;
3711 PyObject *converters;
3712 PyObject *checker;
3713 PyObject *argtypes;
3714 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3715 PyObject *result;
3716 PyObject *callargs;
3717 PyObject *errcheck;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003718#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003719 IUnknown *piunk = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003720#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003721 void *pProc = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003723 int inoutmask;
3724 int outmask;
3725 unsigned int numretvals;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003727 assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3728 restype = self->restype ? self->restype : dict->restype;
3729 converters = self->converters ? self->converters : dict->converters;
3730 checker = self->checker ? self->checker : dict->checker;
3731 argtypes = self->argtypes ? self->argtypes : dict->argtypes;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003732/* later, we probably want to have an errcheck field in stgdict */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003733 errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003734
3735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003736 pProc = *(void **)self->b_ptr;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003737#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003738 if (self->index) {
3739 /* It's a COM method */
3740 CDataObject *this;
3741 this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
3742 if (!this) {
3743 PyErr_SetString(PyExc_ValueError,
3744 "native com method call without 'this' parameter");
3745 return NULL;
3746 }
3747 if (!CDataObject_Check(this)) {
3748 PyErr_SetString(PyExc_TypeError,
3749 "Expected a COM this pointer as first argument");
3750 return NULL;
3751 }
3752 /* there should be more checks? No, in Python */
3753 /* First arg is an pointer to an interface instance */
3754 if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
3755 PyErr_SetString(PyExc_ValueError,
3756 "NULL COM pointer access");
3757 return NULL;
3758 }
3759 piunk = *(IUnknown **)this->b_ptr;
3760 if (NULL == piunk->lpVtbl) {
3761 PyErr_SetString(PyExc_ValueError,
3762 "COM method call without VTable");
3763 return NULL;
3764 }
3765 pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
3766 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003767#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003768 callargs = _build_callargs(self, argtypes,
3769 inargs, kwds,
3770 &outmask, &inoutmask, &numretvals);
3771 if (callargs == NULL)
3772 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003773
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003774 if (converters) {
3775 int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
3776 Py_ssize_t, int);
3777 int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
3778 Py_ssize_t, int);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003779
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003780 if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
3781 /* For cdecl functions, we allow more actual arguments
3782 than the length of the argtypes tuple.
3783 */
3784 if (required > actual) {
3785 Py_DECREF(callargs);
3786 PyErr_Format(PyExc_TypeError,
3787 "this function takes at least %d argument%s (%d given)",
3788 required,
3789 required == 1 ? "" : "s",
3790 actual);
3791 return NULL;
3792 }
3793 } else if (required != actual) {
3794 Py_DECREF(callargs);
3795 PyErr_Format(PyExc_TypeError,
3796 "this function takes %d argument%s (%d given)",
3797 required,
3798 required == 1 ? "" : "s",
3799 actual);
3800 return NULL;
3801 }
3802 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003804 result = _ctypes_callproc(pProc,
3805 callargs,
Thomas Hellerd4c93202006-03-08 19:35:11 +00003806#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003807 piunk,
3808 self->iid,
Thomas Hellerd4c93202006-03-08 19:35:11 +00003809#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003810 dict->flags,
3811 converters,
3812 restype,
3813 checker);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003814/* The 'errcheck' protocol */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003815 if (result != NULL && errcheck) {
3816 PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
3817 result,
3818 self,
3819 callargs,
3820 NULL);
3821 /* If the errcheck funtion failed, return NULL.
3822 If the errcheck function returned callargs unchanged,
3823 continue normal processing.
3824 If the errcheck function returned something else,
3825 use that as result.
3826 */
3827 if (v == NULL || v != callargs) {
3828 Py_DECREF(result);
3829 Py_DECREF(callargs);
3830 return v;
3831 }
3832 Py_DECREF(v);
3833 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003835 return _build_result(result, callargs,
3836 outmask, inoutmask, numretvals);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003837}
3838
3839static int
Thomas Heller34596a92009-04-24 20:50:00 +00003840PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003842 Py_VISIT(self->callable);
3843 Py_VISIT(self->restype);
3844 Py_VISIT(self->checker);
3845 Py_VISIT(self->errcheck);
3846 Py_VISIT(self->argtypes);
3847 Py_VISIT(self->converters);
3848 Py_VISIT(self->paramflags);
3849 Py_VISIT(self->thunk);
3850 return PyCData_traverse((CDataObject *)self, visit, arg);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003851}
3852
3853static int
Thomas Heller34596a92009-04-24 20:50:00 +00003854PyCFuncPtr_clear(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003856 Py_CLEAR(self->callable);
3857 Py_CLEAR(self->restype);
3858 Py_CLEAR(self->checker);
3859 Py_CLEAR(self->errcheck);
3860 Py_CLEAR(self->argtypes);
3861 Py_CLEAR(self->converters);
3862 Py_CLEAR(self->paramflags);
3863 Py_CLEAR(self->thunk);
3864 return PyCData_clear((CDataObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003865}
3866
3867static void
Thomas Heller34596a92009-04-24 20:50:00 +00003868PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003869{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003870 PyCFuncPtr_clear(self);
3871 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003872}
3873
3874static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003875PyCFuncPtr_repr(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003876{
3877#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003878 if (self->index)
3879 return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
3880 self->index - 0x1000,
3881 Py_TYPE(self)->tp_name,
3882 self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003883#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003884 return PyUnicode_FromFormat("<%s object at %p>",
3885 Py_TYPE(self)->tp_name,
3886 self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003887}
3888
Thomas Heller7dca3eb2008-05-29 19:54:39 +00003889static int
Thomas Heller34596a92009-04-24 20:50:00 +00003890PyCFuncPtr_bool(PyCFuncPtrObject *self)
Thomas Heller7dca3eb2008-05-29 19:54:39 +00003891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003892 return ((*(void **)self->b_ptr != NULL)
Thomas Hellerf5049fc2008-08-19 19:49:49 +00003893#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003894 || (self->index != 0)
Thomas Hellerf5049fc2008-08-19 19:49:49 +00003895#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003896 );
Thomas Heller7dca3eb2008-05-29 19:54:39 +00003897}
3898
Thomas Heller34596a92009-04-24 20:50:00 +00003899static PyNumberMethods PyCFuncPtr_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003900 0, /* nb_add */
3901 0, /* nb_subtract */
3902 0, /* nb_multiply */
3903 0, /* nb_remainder */
3904 0, /* nb_divmod */
3905 0, /* nb_power */
3906 0, /* nb_negative */
3907 0, /* nb_positive */
3908 0, /* nb_absolute */
3909 (inquiry)PyCFuncPtr_bool, /* nb_bool */
Thomas Heller7dca3eb2008-05-29 19:54:39 +00003910};
3911
Thomas Heller34596a92009-04-24 20:50:00 +00003912PyTypeObject PyCFuncPtr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003913 PyVarObject_HEAD_INIT(NULL, 0)
3914 "_ctypes.PyCFuncPtr",
3915 sizeof(PyCFuncPtrObject), /* tp_basicsize */
3916 0, /* tp_itemsize */
3917 (destructor)PyCFuncPtr_dealloc, /* tp_dealloc */
3918 0, /* tp_print */
3919 0, /* tp_getattr */
3920 0, /* tp_setattr */
3921 0, /* tp_reserved */
3922 (reprfunc)PyCFuncPtr_repr, /* tp_repr */
3923 &PyCFuncPtr_as_number, /* tp_as_number */
3924 0, /* tp_as_sequence */
3925 0, /* tp_as_mapping */
3926 0, /* tp_hash */
3927 (ternaryfunc)PyCFuncPtr_call, /* tp_call */
3928 0, /* tp_str */
3929 0, /* tp_getattro */
3930 0, /* tp_setattro */
3931 &PyCData_as_buffer, /* tp_as_buffer */
3932 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3933 "Function Pointer", /* tp_doc */
3934 (traverseproc)PyCFuncPtr_traverse, /* tp_traverse */
3935 (inquiry)PyCFuncPtr_clear, /* tp_clear */
3936 0, /* tp_richcompare */
3937 0, /* tp_weaklistoffset */
3938 0, /* tp_iter */
3939 0, /* tp_iternext */
3940 0, /* tp_methods */
3941 0, /* tp_members */
3942 PyCFuncPtr_getsets, /* tp_getset */
3943 0, /* tp_base */
3944 0, /* tp_dict */
3945 0, /* tp_descr_get */
3946 0, /* tp_descr_set */
3947 0, /* tp_dictoffset */
3948 0, /* tp_init */
3949 0, /* tp_alloc */
3950 PyCFuncPtr_new, /* tp_new */
3951 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00003952};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003953
Thomas Hellerd4c93202006-03-08 19:35:11 +00003954/*****************************************************************/
3955/*
3956 Struct_Type
3957*/
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003958/*
3959 This function is called to initialize a Structure or Union with positional
3960 arguments. It calls itself recursively for all Structure or Union base
3961 classes, then retrieves the _fields_ member to associate the argument
3962 position with the correct field name.
3963
3964 Returns -1 on error, or the index of next argument on success.
3965 */
Victor Stinner0fcab4a2011-01-04 12:59:15 +00003966static Py_ssize_t
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003967_init_pos_args(PyObject *self, PyTypeObject *type,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003968 PyObject *args, PyObject *kwds,
Victor Stinner0fcab4a2011-01-04 12:59:15 +00003969 Py_ssize_t index)
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003970{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003971 StgDictObject *dict;
3972 PyObject *fields;
Victor Stinner0fcab4a2011-01-04 12:59:15 +00003973 Py_ssize_t i;
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003975 if (PyType_stgdict((PyObject *)type->tp_base)) {
3976 index = _init_pos_args(self, type->tp_base,
3977 args, kwds,
3978 index);
3979 if (index == -1)
3980 return -1;
3981 }
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003983 dict = PyType_stgdict((PyObject *)type);
3984 fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
3985 if (fields == NULL)
3986 return index;
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003988 for (i = 0;
3989 i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
3990 ++i) {
3991 PyObject *pair = PySequence_GetItem(fields, i);
3992 PyObject *name, *val;
3993 int res;
3994 if (!pair)
3995 return -1;
3996 name = PySequence_GetItem(pair, 0);
3997 if (!name) {
3998 Py_DECREF(pair);
3999 return -1;
4000 }
4001 val = PyTuple_GET_ITEM(args, i + index);
4002 if (kwds && PyDict_GetItem(kwds, name)) {
4003 char *field = PyBytes_AsString(name);
4004 if (field == NULL) {
4005 PyErr_Clear();
4006 field = "???";
4007 }
4008 PyErr_Format(PyExc_TypeError,
4009 "duplicate values for field '%s'",
4010 field);
4011 Py_DECREF(pair);
4012 Py_DECREF(name);
4013 return -1;
4014 }
4015
4016 res = PyObject_SetAttr(self, name, val);
4017 Py_DECREF(pair);
4018 Py_DECREF(name);
4019 if (res == -1)
4020 return -1;
4021 }
4022 return index + dict->length;
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00004023}
4024
Thomas Hellerd4c93202006-03-08 19:35:11 +00004025static int
4026Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
4027{
Thomas Hellerd4c93202006-03-08 19:35:11 +00004028/* Optimization possible: Store the attribute names _fields_[x][0]
4029 * in C accessible fields somewhere ?
4030 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004031 if (!PyTuple_Check(args)) {
4032 PyErr_SetString(PyExc_TypeError,
4033 "args not a tuple?");
4034 return -1;
4035 }
4036 if (PyTuple_GET_SIZE(args)) {
4037 int res = _init_pos_args(self, Py_TYPE(self),
4038 args, kwds, 0);
4039 if (res == -1)
4040 return -1;
4041 if (res < PyTuple_GET_SIZE(args)) {
4042 PyErr_SetString(PyExc_TypeError,
4043 "too many initializers");
4044 return -1;
4045 }
4046 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004048 if (kwds) {
4049 PyObject *key, *value;
4050 Py_ssize_t pos = 0;
4051 while(PyDict_Next(kwds, &pos, &key, &value)) {
4052 if (-1 == PyObject_SetAttr(self, key, value))
4053 return -1;
4054 }
4055 }
4056 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004057}
4058
Thomas Hellerd4c93202006-03-08 19:35:11 +00004059static PyTypeObject Struct_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004060 PyVarObject_HEAD_INIT(NULL, 0)
4061 "_ctypes.Structure",
4062 sizeof(CDataObject), /* tp_basicsize */
4063 0, /* tp_itemsize */
4064 0, /* tp_dealloc */
4065 0, /* tp_print */
4066 0, /* tp_getattr */
4067 0, /* tp_setattr */
4068 0, /* tp_reserved */
4069 0, /* tp_repr */
4070 0, /* tp_as_number */
4071 0, /* tp_as_sequence */
4072 0, /* tp_as_mapping */
4073 0, /* tp_hash */
4074 0, /* tp_call */
4075 0, /* tp_str */
4076 0, /* tp_getattro */
4077 0, /* tp_setattro */
4078 &PyCData_as_buffer, /* tp_as_buffer */
4079 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4080 "Structure base class", /* tp_doc */
4081 (traverseproc)PyCData_traverse, /* tp_traverse */
4082 (inquiry)PyCData_clear, /* tp_clear */
4083 0, /* tp_richcompare */
4084 0, /* tp_weaklistoffset */
4085 0, /* tp_iter */
4086 0, /* tp_iternext */
4087 0, /* tp_methods */
4088 0, /* tp_members */
4089 0, /* tp_getset */
4090 0, /* tp_base */
4091 0, /* tp_dict */
4092 0, /* tp_descr_get */
4093 0, /* tp_descr_set */
4094 0, /* tp_dictoffset */
4095 Struct_init, /* tp_init */
4096 0, /* tp_alloc */
4097 GenericPyCData_new, /* tp_new */
4098 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004099};
4100
4101static PyTypeObject Union_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004102 PyVarObject_HEAD_INIT(NULL, 0)
4103 "_ctypes.Union",
4104 sizeof(CDataObject), /* tp_basicsize */
4105 0, /* tp_itemsize */
4106 0, /* tp_dealloc */
4107 0, /* tp_print */
4108 0, /* tp_getattr */
4109 0, /* tp_setattr */
4110 0, /* tp_reserved */
4111 0, /* tp_repr */
4112 0, /* tp_as_number */
4113 0, /* tp_as_sequence */
4114 0, /* tp_as_mapping */
4115 0, /* tp_hash */
4116 0, /* tp_call */
4117 0, /* tp_str */
4118 0, /* tp_getattro */
4119 0, /* tp_setattro */
4120 &PyCData_as_buffer, /* tp_as_buffer */
4121 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4122 "Union base class", /* tp_doc */
4123 (traverseproc)PyCData_traverse, /* tp_traverse */
4124 (inquiry)PyCData_clear, /* tp_clear */
4125 0, /* tp_richcompare */
4126 0, /* tp_weaklistoffset */
4127 0, /* tp_iter */
4128 0, /* tp_iternext */
4129 0, /* tp_methods */
4130 0, /* tp_members */
4131 0, /* tp_getset */
4132 0, /* tp_base */
4133 0, /* tp_dict */
4134 0, /* tp_descr_get */
4135 0, /* tp_descr_set */
4136 0, /* tp_dictoffset */
4137 Struct_init, /* tp_init */
4138 0, /* tp_alloc */
4139 GenericPyCData_new, /* tp_new */
4140 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004141};
4142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004143
Thomas Hellerd4c93202006-03-08 19:35:11 +00004144/******************************************************************/
4145/*
Thomas Heller34596a92009-04-24 20:50:00 +00004146 PyCArray_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00004147*/
4148static int
4149Array_init(CDataObject *self, PyObject *args, PyObject *kw)
4150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004151 Py_ssize_t i;
4152 Py_ssize_t n;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004153
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004154 if (!PyTuple_Check(args)) {
4155 PyErr_SetString(PyExc_TypeError,
4156 "args not a tuple?");
4157 return -1;
4158 }
4159 n = PyTuple_GET_SIZE(args);
4160 for (i = 0; i < n; ++i) {
4161 PyObject *v;
4162 v = PyTuple_GET_ITEM(args, i);
4163 if (-1 == PySequence_SetItem((PyObject *)self, i, v))
4164 return -1;
4165 }
4166 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004167}
4168
4169static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004170Array_item(PyObject *_self, Py_ssize_t index)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004171{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004172 CDataObject *self = (CDataObject *)_self;
4173 Py_ssize_t offset, size;
4174 StgDictObject *stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004175
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004177 if (index < 0 || index >= self->b_length) {
4178 PyErr_SetString(PyExc_IndexError,
4179 "invalid index");
4180 return NULL;
4181 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004183 stgdict = PyObject_stgdict((PyObject *)self);
4184 assert(stgdict); /* Cannot be NULL for array instances */
4185 /* Would it be clearer if we got the item size from
4186 stgdict->proto's stgdict?
4187 */
4188 size = stgdict->size / stgdict->length;
4189 offset = index * size;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004191 return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
4192 index, size, self->b_ptr + offset);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004193}
4194
4195static PyObject *
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004196Array_subscript(PyObject *_self, PyObject *item)
4197{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004198 CDataObject *self = (CDataObject *)_self;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004200 if (PyIndex_Check(item)) {
4201 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004203 if (i == -1 && PyErr_Occurred())
4204 return NULL;
4205 if (i < 0)
4206 i += self->b_length;
4207 return Array_item(_self, i);
4208 }
4209 else if PySlice_Check(item) {
4210 StgDictObject *stgdict, *itemdict;
4211 PyObject *proto;
4212 PyObject *np;
4213 Py_ssize_t start, stop, step, slicelen, cur, i;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004214
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00004215 if (PySlice_GetIndicesEx(item,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004216 self->b_length, &start, &stop,
4217 &step, &slicelen) < 0) {
4218 return NULL;
4219 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004220
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004221 stgdict = PyObject_stgdict((PyObject *)self);
4222 assert(stgdict); /* Cannot be NULL for array object instances */
4223 proto = stgdict->proto;
4224 itemdict = PyType_stgdict(proto);
4225 assert(itemdict); /* proto is the item type of the array, a
4226 ctypes type, so this cannot be NULL */
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004228 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4229 char *ptr = (char *)self->b_ptr;
4230 char *dest;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 if (slicelen <= 0)
4233 return PyBytes_FromStringAndSize("", 0);
4234 if (step == 1) {
4235 return PyBytes_FromStringAndSize(ptr + start,
4236 slicelen);
4237 }
4238 dest = (char *)PyMem_Malloc(slicelen);
4239
4240 if (dest == NULL)
4241 return PyErr_NoMemory();
4242
4243 for (cur = start, i = 0; i < slicelen;
4244 cur += step, i++) {
4245 dest[i] = ptr[cur];
4246 }
4247
4248 np = PyBytes_FromStringAndSize(dest, slicelen);
4249 PyMem_Free(dest);
4250 return np;
4251 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004252#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004253 if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4254 wchar_t *ptr = (wchar_t *)self->b_ptr;
4255 wchar_t *dest;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004257 if (slicelen <= 0)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004258 return PyUnicode_New(0, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004259 if (step == 1) {
4260 return PyUnicode_FromWideChar(ptr + start,
4261 slicelen);
4262 }
4263
4264 dest = (wchar_t *)PyMem_Malloc(
4265 slicelen * sizeof(wchar_t));
4266
4267 for (cur = start, i = 0; i < slicelen;
4268 cur += step, i++) {
4269 dest[i] = ptr[cur];
4270 }
4271
4272 np = PyUnicode_FromWideChar(dest, slicelen);
4273 PyMem_Free(dest);
4274 return np;
4275 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004276#endif
4277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004278 np = PyList_New(slicelen);
4279 if (np == NULL)
4280 return NULL;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004282 for (cur = start, i = 0; i < slicelen;
4283 cur += step, i++) {
4284 PyObject *v = Array_item(_self, cur);
4285 PyList_SET_ITEM(np, i, v);
4286 }
4287 return np;
4288 }
4289 else {
4290 PyErr_SetString(PyExc_TypeError,
4291 "indices must be integers");
4292 return NULL;
4293 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004294
4295}
4296
Thomas Hellerd4c93202006-03-08 19:35:11 +00004297static int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004298Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004300 CDataObject *self = (CDataObject *)_self;
4301 Py_ssize_t size, offset;
4302 StgDictObject *stgdict;
4303 char *ptr;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004305 if (value == NULL) {
4306 PyErr_SetString(PyExc_TypeError,
4307 "Array does not support item deletion");
4308 return -1;
4309 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004311 stgdict = PyObject_stgdict((PyObject *)self);
4312 assert(stgdict); /* Cannot be NULL for array object instances */
4313 if (index < 0 || index >= stgdict->length) {
4314 PyErr_SetString(PyExc_IndexError,
4315 "invalid index");
4316 return -1;
4317 }
4318 size = stgdict->size / stgdict->length;
4319 offset = index * size;
4320 ptr = self->b_ptr + offset;
4321
4322 return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
4323 index, size, ptr);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004324}
4325
4326static int
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004327Array_ass_subscript(PyObject *_self, PyObject *item, PyObject *value)
4328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004329 CDataObject *self = (CDataObject *)_self;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004331 if (value == NULL) {
4332 PyErr_SetString(PyExc_TypeError,
4333 "Array does not support item deletion");
4334 return -1;
4335 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004337 if (PyIndex_Check(item)) {
4338 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4339
4340 if (i == -1 && PyErr_Occurred())
4341 return -1;
4342 if (i < 0)
4343 i += self->b_length;
4344 return Array_ass_item(_self, i, value);
4345 }
4346 else if (PySlice_Check(item)) {
4347 Py_ssize_t start, stop, step, slicelen, otherlen, i, cur;
4348
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00004349 if (PySlice_GetIndicesEx(item,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004350 self->b_length, &start, &stop,
4351 &step, &slicelen) < 0) {
4352 return -1;
4353 }
4354 if ((step < 0 && start < stop) ||
4355 (step > 0 && start > stop))
4356 stop = start;
4357
4358 otherlen = PySequence_Length(value);
4359 if (otherlen != slicelen) {
4360 PyErr_SetString(PyExc_ValueError,
4361 "Can only assign sequence of same size");
4362 return -1;
4363 }
4364 for (cur = start, i = 0; i < otherlen; cur += step, i++) {
4365 PyObject *item = PySequence_GetItem(value, i);
4366 int result;
4367 if (item == NULL)
4368 return -1;
4369 result = Array_ass_item(_self, cur, item);
4370 Py_DECREF(item);
4371 if (result == -1)
4372 return -1;
4373 }
4374 return 0;
4375 }
4376 else {
4377 PyErr_SetString(PyExc_TypeError,
4378 "indices must be integer");
4379 return -1;
4380 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004381}
4382
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004383static Py_ssize_t
4384Array_length(PyObject *_self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004386 CDataObject *self = (CDataObject *)_self;
4387 return self->b_length;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004388}
4389
4390static PySequenceMethods Array_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004391 Array_length, /* sq_length; */
4392 0, /* sq_concat; */
4393 0, /* sq_repeat; */
4394 Array_item, /* sq_item; */
4395 0, /* sq_slice; */
4396 Array_ass_item, /* sq_ass_item; */
4397 0, /* sq_ass_slice; */
4398 0, /* sq_contains; */
4399
4400 0, /* sq_inplace_concat; */
4401 0, /* sq_inplace_repeat; */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004402};
4403
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004404static PyMappingMethods Array_as_mapping = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004405 Array_length,
4406 Array_subscript,
4407 Array_ass_subscript,
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004408};
4409
Thomas Heller34596a92009-04-24 20:50:00 +00004410PyTypeObject PyCArray_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004411 PyVarObject_HEAD_INIT(NULL, 0)
4412 "_ctypes.Array",
4413 sizeof(CDataObject), /* tp_basicsize */
4414 0, /* tp_itemsize */
4415 0, /* tp_dealloc */
4416 0, /* tp_print */
4417 0, /* tp_getattr */
4418 0, /* tp_setattr */
4419 0, /* tp_reserved */
4420 0, /* tp_repr */
4421 0, /* tp_as_number */
4422 &Array_as_sequence, /* tp_as_sequence */
4423 &Array_as_mapping, /* tp_as_mapping */
4424 0, /* tp_hash */
4425 0, /* tp_call */
4426 0, /* tp_str */
4427 0, /* tp_getattro */
4428 0, /* tp_setattro */
4429 &PyCData_as_buffer, /* tp_as_buffer */
4430 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4431 "XXX to be provided", /* tp_doc */
4432 (traverseproc)PyCData_traverse, /* tp_traverse */
4433 (inquiry)PyCData_clear, /* tp_clear */
4434 0, /* tp_richcompare */
4435 0, /* tp_weaklistoffset */
4436 0, /* tp_iter */
4437 0, /* tp_iternext */
4438 0, /* tp_methods */
4439 0, /* tp_members */
4440 0, /* tp_getset */
4441 0, /* tp_base */
4442 0, /* tp_dict */
4443 0, /* tp_descr_get */
4444 0, /* tp_descr_set */
4445 0, /* tp_dictoffset */
4446 (initproc)Array_init, /* tp_init */
4447 0, /* tp_alloc */
4448 GenericPyCData_new, /* tp_new */
4449 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004450};
4451
4452PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00004453PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004454{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004455 static PyObject *cache;
4456 PyObject *key;
4457 PyObject *result;
4458 char name[256];
4459 PyObject *len;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004461 if (cache == NULL) {
4462 cache = PyDict_New();
4463 if (cache == NULL)
4464 return NULL;
4465 }
4466 len = PyLong_FromSsize_t(length);
4467 if (len == NULL)
4468 return NULL;
4469 key = PyTuple_Pack(2, itemtype, len);
4470 Py_DECREF(len);
4471 if (!key)
4472 return NULL;
4473 result = PyDict_GetItemProxy(cache, key);
4474 if (result) {
4475 Py_INCREF(result);
4476 Py_DECREF(key);
4477 return result;
4478 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004480 if (!PyType_Check(itemtype)) {
4481 PyErr_SetString(PyExc_TypeError,
4482 "Expected a type object");
Meador Ingeb86ecf42011-09-27 20:45:30 -05004483 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004484 return NULL;
4485 }
Thomas Hellerfe8f8622006-03-14 19:53:09 +00004486#ifdef MS_WIN64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004487 sprintf(name, "%.200s_Array_%Id",
4488 ((PyTypeObject *)itemtype)->tp_name, length);
Thomas Hellerfe8f8622006-03-14 19:53:09 +00004489#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004490 sprintf(name, "%.200s_Array_%ld",
4491 ((PyTypeObject *)itemtype)->tp_name, (long)length);
Thomas Hellerfe8f8622006-03-14 19:53:09 +00004492#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +00004493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004494 result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type,
Victor Stinner7eeb5b52010-06-07 19:57:46 +00004495 "s(O){s:n,s:O}",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004496 name,
4497 &PyCArray_Type,
4498 "_length_",
4499 length,
4500 "_type_",
4501 itemtype
4502 );
4503 if (result == NULL) {
4504 Py_DECREF(key);
4505 return NULL;
4506 }
4507 if (-1 == PyDict_SetItemProxy(cache, key, result)) {
4508 Py_DECREF(key);
4509 Py_DECREF(result);
4510 return NULL;
4511 }
4512 Py_DECREF(key);
4513 return result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004514}
4515
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004516
Thomas Hellerd4c93202006-03-08 19:35:11 +00004517/******************************************************************/
4518/*
4519 Simple_Type
4520*/
4521
4522static int
4523Simple_set_value(CDataObject *self, PyObject *value)
4524{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004525 PyObject *result;
4526 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004528 if (value == NULL) {
4529 PyErr_SetString(PyExc_TypeError,
4530 "can't delete attribute");
4531 return -1;
4532 }
4533 assert(dict); /* Cannot be NULL for CDataObject instances */
4534 assert(dict->setfunc);
4535 result = dict->setfunc(self->b_ptr, value, dict->size);
4536 if (!result)
4537 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004538
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004539 /* consumes the refcount the setfunc returns */
4540 return KeepRef(self, 0, result);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004541}
4542
4543static int
4544Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
4545{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004546 PyObject *value = NULL;
4547 if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
4548 return -1;
4549 if (value)
4550 return Simple_set_value(self, value);
4551 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004552}
4553
4554static PyObject *
4555Simple_get_value(CDataObject *self)
4556{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004557 StgDictObject *dict;
4558 dict = PyObject_stgdict((PyObject *)self);
4559 assert(dict); /* Cannot be NULL for CDataObject instances */
4560 assert(dict->getfunc);
4561 return dict->getfunc(self->b_ptr, self->b_size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004562}
4563
Thomas Hellerd4c93202006-03-08 19:35:11 +00004564static PyGetSetDef Simple_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004565 { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4566 "current value", NULL },
4567 { NULL, NULL }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004568};
4569
4570static PyObject *
4571Simple_from_outparm(PyObject *self, PyObject *args)
4572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) {
4574 Py_INCREF(self);
4575 return self;
4576 }
4577 /* call stgdict->getfunc */
4578 return Simple_get_value((CDataObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004579}
4580
4581static PyMethodDef Simple_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004582 { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
4583 { NULL, NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +00004584};
4585
Jack Diederich4dafcc42006-11-28 19:15:13 +00004586static int Simple_bool(CDataObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004588 return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004589}
4590
4591static PyNumberMethods Simple_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004592 0, /* nb_add */
4593 0, /* nb_subtract */
4594 0, /* nb_multiply */
4595 0, /* nb_remainder */
4596 0, /* nb_divmod */
4597 0, /* nb_power */
4598 0, /* nb_negative */
4599 0, /* nb_positive */
4600 0, /* nb_absolute */
4601 (inquiry)Simple_bool, /* nb_bool */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004602};
4603
Thomas Hellerd4c93202006-03-08 19:35:11 +00004604/* "%s(%s)" % (self.__class__.__name__, self.value) */
4605static PyObject *
4606Simple_repr(CDataObject *self)
4607{
Amaury Forgeot d'Arc864741b2011-11-06 15:10:48 +01004608 PyObject *val, *result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004609
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004610 if (Py_TYPE(self)->tp_base != &Simple_Type) {
4611 return PyUnicode_FromFormat("<%s object at %p>",
4612 Py_TYPE(self)->tp_name, self);
4613 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004615 val = Simple_get_value(self);
4616 if (val == NULL)
4617 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004618
Amaury Forgeot d'Arc864741b2011-11-06 15:10:48 +01004619 result = PyUnicode_FromFormat("%s(%R)",
4620 Py_TYPE(self)->tp_name, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004621 Py_DECREF(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004622 return result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004623}
4624
4625static PyTypeObject Simple_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004626 PyVarObject_HEAD_INIT(NULL, 0)
4627 "_ctypes._SimpleCData",
4628 sizeof(CDataObject), /* tp_basicsize */
4629 0, /* tp_itemsize */
4630 0, /* tp_dealloc */
4631 0, /* tp_print */
4632 0, /* tp_getattr */
4633 0, /* tp_setattr */
4634 0, /* tp_reserved */
4635 (reprfunc)&Simple_repr, /* tp_repr */
4636 &Simple_as_number, /* tp_as_number */
4637 0, /* tp_as_sequence */
4638 0, /* tp_as_mapping */
4639 0, /* tp_hash */
4640 0, /* tp_call */
4641 0, /* tp_str */
4642 0, /* tp_getattro */
4643 0, /* tp_setattro */
4644 &PyCData_as_buffer, /* tp_as_buffer */
4645 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4646 "XXX to be provided", /* tp_doc */
4647 (traverseproc)PyCData_traverse, /* tp_traverse */
4648 (inquiry)PyCData_clear, /* tp_clear */
4649 0, /* tp_richcompare */
4650 0, /* tp_weaklistoffset */
4651 0, /* tp_iter */
4652 0, /* tp_iternext */
4653 Simple_methods, /* tp_methods */
4654 0, /* tp_members */
4655 Simple_getsets, /* tp_getset */
4656 0, /* tp_base */
4657 0, /* tp_dict */
4658 0, /* tp_descr_get */
4659 0, /* tp_descr_set */
4660 0, /* tp_dictoffset */
4661 (initproc)Simple_init, /* tp_init */
4662 0, /* tp_alloc */
4663 GenericPyCData_new, /* tp_new */
4664 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004665};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004666
Thomas Hellerd4c93202006-03-08 19:35:11 +00004667/******************************************************************/
4668/*
Thomas Heller34596a92009-04-24 20:50:00 +00004669 PyCPointer_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00004670*/
4671static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004672Pointer_item(PyObject *_self, Py_ssize_t index)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004674 CDataObject *self = (CDataObject *)_self;
4675 Py_ssize_t size;
4676 Py_ssize_t offset;
4677 StgDictObject *stgdict, *itemdict;
4678 PyObject *proto;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004680 if (*(void **)self->b_ptr == NULL) {
4681 PyErr_SetString(PyExc_ValueError,
4682 "NULL pointer access");
4683 return NULL;
4684 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004685
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004686 stgdict = PyObject_stgdict((PyObject *)self);
4687 assert(stgdict); /* Cannot be NULL for pointer object instances */
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00004688
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004689 proto = stgdict->proto;
4690 assert(proto);
4691 itemdict = PyType_stgdict(proto);
4692 assert(itemdict); /* proto is the item type of the pointer, a ctypes
4693 type, so this cannot be NULL */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004694
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004695 size = itemdict->size;
4696 offset = index * itemdict->size;
4697
4698 return PyCData_get(proto, stgdict->getfunc, (PyObject *)self,
4699 index, size, (*(char **)self->b_ptr) + offset);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004700}
4701
4702static int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004703Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004704{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004705 CDataObject *self = (CDataObject *)_self;
4706 Py_ssize_t size;
4707 Py_ssize_t offset;
4708 StgDictObject *stgdict, *itemdict;
4709 PyObject *proto;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004711 if (value == NULL) {
4712 PyErr_SetString(PyExc_TypeError,
4713 "Pointer does not support item deletion");
4714 return -1;
4715 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004716
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004717 if (*(void **)self->b_ptr == NULL) {
4718 PyErr_SetString(PyExc_ValueError,
4719 "NULL pointer access");
4720 return -1;
4721 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004723 stgdict = PyObject_stgdict((PyObject *)self);
4724 assert(stgdict); /* Cannot be NULL fr pointer instances */
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00004725
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004726 proto = stgdict->proto;
4727 assert(proto);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00004728
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004729 itemdict = PyType_stgdict(proto);
4730 assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
4731 is always a ctypes type */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004733 size = itemdict->size;
4734 offset = index * itemdict->size;
4735
4736 return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value,
4737 index, size, (*(char **)self->b_ptr) + offset);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004738}
4739
4740static PyObject *
4741Pointer_get_contents(CDataObject *self, void *closure)
4742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004743 StgDictObject *stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004745 if (*(void **)self->b_ptr == NULL) {
4746 PyErr_SetString(PyExc_ValueError,
4747 "NULL pointer access");
4748 return NULL;
4749 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004750
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004751 stgdict = PyObject_stgdict((PyObject *)self);
4752 assert(stgdict); /* Cannot be NULL fr pointer instances */
4753 return PyCData_FromBaseObj(stgdict->proto,
4754 (PyObject *)self, 0,
4755 *(void **)self->b_ptr);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004756}
4757
4758static int
4759Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
4760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004761 StgDictObject *stgdict;
4762 CDataObject *dst;
4763 PyObject *keep;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004764
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004765 if (value == NULL) {
4766 PyErr_SetString(PyExc_TypeError,
4767 "Pointer does not support item deletion");
4768 return -1;
4769 }
4770 stgdict = PyObject_stgdict((PyObject *)self);
4771 assert(stgdict); /* Cannot be NULL fr pointer instances */
4772 assert(stgdict->proto);
Benjamin Peterson39530f82011-03-26 18:04:09 -05004773 if (!CDataObject_Check(value)) {
4774 int res = PyObject_IsInstance(value, stgdict->proto);
4775 if (res == -1)
4776 return -1;
4777 if (!res) {
4778 PyErr_Format(PyExc_TypeError,
4779 "expected %s instead of %s",
4780 ((PyTypeObject *)(stgdict->proto))->tp_name,
4781 Py_TYPE(value)->tp_name);
4782 return -1;
4783 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004784 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004785
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004786 dst = (CDataObject *)value;
4787 *(void **)self->b_ptr = dst->b_ptr;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004789 /*
4790 A Pointer instance must keep a the value it points to alive. So, a
4791 pointer instance has b_length set to 2 instead of 1, and we set
4792 'value' itself as the second item of the b_objects list, additionally.
4793 */
4794 Py_INCREF(value);
4795 if (-1 == KeepRef(self, 1, value))
4796 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004798 keep = GetKeepedObjects(dst);
4799 Py_INCREF(keep);
4800 return KeepRef(self, 0, keep);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004801}
4802
Thomas Hellerd4c93202006-03-08 19:35:11 +00004803static PyGetSetDef Pointer_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004804 { "contents", (getter)Pointer_get_contents,
4805 (setter)Pointer_set_contents,
4806 "the object this pointer points to (read-write)", NULL },
4807 { NULL, NULL }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004808};
4809
4810static int
4811Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
4812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004813 PyObject *value = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004815 if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
4816 return -1;
4817 if (value == NULL)
4818 return 0;
4819 return Pointer_set_contents(self, value, NULL);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004820}
4821
4822static PyObject *
4823Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004825 StgDictObject *dict = PyType_stgdict((PyObject *)type);
4826 if (!dict || !dict->proto) {
4827 PyErr_SetString(PyExc_TypeError,
4828 "Cannot create instance: has no _type_");
4829 return NULL;
4830 }
4831 return GenericPyCData_new(type, args, kw);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004832}
4833
4834static PyObject *
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004835Pointer_subscript(PyObject *_self, PyObject *item)
4836{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004837 CDataObject *self = (CDataObject *)_self;
4838 if (PyIndex_Check(item)) {
4839 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4840 if (i == -1 && PyErr_Occurred())
4841 return NULL;
4842 return Pointer_item(_self, i);
4843 }
4844 else if (PySlice_Check(item)) {
4845 PySliceObject *slice = (PySliceObject *)item;
4846 Py_ssize_t start, stop, step;
4847 PyObject *np;
4848 StgDictObject *stgdict, *itemdict;
4849 PyObject *proto;
4850 Py_ssize_t i, len, cur;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004852 /* Since pointers have no length, and we want to apply
4853 different semantics to negative indices than normal
4854 slicing, we have to dissect the slice object ourselves.*/
4855 if (slice->step == Py_None) {
4856 step = 1;
4857 }
4858 else {
4859 step = PyNumber_AsSsize_t(slice->step,
4860 PyExc_ValueError);
4861 if (step == -1 && PyErr_Occurred())
4862 return NULL;
4863 if (step == 0) {
4864 PyErr_SetString(PyExc_ValueError,
4865 "slice step cannot be zero");
4866 return NULL;
4867 }
4868 }
4869 if (slice->start == Py_None) {
4870 if (step < 0) {
4871 PyErr_SetString(PyExc_ValueError,
4872 "slice start is required "
4873 "for step < 0");
4874 return NULL;
4875 }
4876 start = 0;
4877 }
4878 else {
4879 start = PyNumber_AsSsize_t(slice->start,
4880 PyExc_ValueError);
4881 if (start == -1 && PyErr_Occurred())
4882 return NULL;
4883 }
4884 if (slice->stop == Py_None) {
4885 PyErr_SetString(PyExc_ValueError,
4886 "slice stop is required");
4887 return NULL;
4888 }
4889 stop = PyNumber_AsSsize_t(slice->stop,
4890 PyExc_ValueError);
4891 if (stop == -1 && PyErr_Occurred())
4892 return NULL;
4893 if ((step > 0 && start > stop) ||
4894 (step < 0 && start < stop))
4895 len = 0;
4896 else if (step > 0)
4897 len = (stop - start - 1) / step + 1;
4898 else
4899 len = (stop - start + 1) / step + 1;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004901 stgdict = PyObject_stgdict((PyObject *)self);
4902 assert(stgdict); /* Cannot be NULL for pointer instances */
4903 proto = stgdict->proto;
4904 assert(proto);
4905 itemdict = PyType_stgdict(proto);
4906 assert(itemdict);
4907 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4908 char *ptr = *(char **)self->b_ptr;
4909 char *dest;
4910
4911 if (len <= 0)
4912 return PyBytes_FromStringAndSize("", 0);
4913 if (step == 1) {
4914 return PyBytes_FromStringAndSize(ptr + start,
4915 len);
4916 }
4917 dest = (char *)PyMem_Malloc(len);
4918 if (dest == NULL)
4919 return PyErr_NoMemory();
4920 for (cur = start, i = 0; i < len; cur += step, i++) {
4921 dest[i] = ptr[cur];
4922 }
4923 np = PyBytes_FromStringAndSize(dest, len);
4924 PyMem_Free(dest);
4925 return np;
4926 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004927#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004928 if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4929 wchar_t *ptr = *(wchar_t **)self->b_ptr;
4930 wchar_t *dest;
4931
4932 if (len <= 0)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004933 return PyUnicode_New(0, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004934 if (step == 1) {
4935 return PyUnicode_FromWideChar(ptr + start,
4936 len);
4937 }
4938 dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t));
4939 if (dest == NULL)
4940 return PyErr_NoMemory();
4941 for (cur = start, i = 0; i < len; cur += step, i++) {
4942 dest[i] = ptr[cur];
4943 }
4944 np = PyUnicode_FromWideChar(dest, len);
4945 PyMem_Free(dest);
4946 return np;
4947 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004948#endif
4949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004950 np = PyList_New(len);
4951 if (np == NULL)
4952 return NULL;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004954 for (cur = start, i = 0; i < len; cur += step, i++) {
4955 PyObject *v = Pointer_item(_self, cur);
4956 PyList_SET_ITEM(np, i, v);
4957 }
4958 return np;
4959 }
4960 else {
4961 PyErr_SetString(PyExc_TypeError,
4962 "Pointer indices must be integer");
4963 return NULL;
4964 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004965}
4966
Thomas Hellerd4c93202006-03-08 19:35:11 +00004967static PySequenceMethods Pointer_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004968 0, /* inquiry sq_length; */
4969 0, /* binaryfunc sq_concat; */
4970 0, /* intargfunc sq_repeat; */
4971 Pointer_item, /* intargfunc sq_item; */
4972 0, /* intintargfunc sq_slice; */
4973 Pointer_ass_item, /* intobjargproc sq_ass_item; */
4974 0, /* intintobjargproc sq_ass_slice; */
4975 0, /* objobjproc sq_contains; */
4976 /* Added in release 2.0 */
4977 0, /* binaryfunc sq_inplace_concat; */
4978 0, /* intargfunc sq_inplace_repeat; */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004979};
4980
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004981static PyMappingMethods Pointer_as_mapping = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004982 0,
4983 Pointer_subscript,
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004984};
4985
Thomas Hellerf5049fc2008-08-19 19:49:49 +00004986static int
4987Pointer_bool(CDataObject *self)
4988{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004989 return (*(void **)self->b_ptr != NULL);
Thomas Hellerf5049fc2008-08-19 19:49:49 +00004990}
4991
4992static PyNumberMethods Pointer_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004993 0, /* nb_add */
4994 0, /* nb_subtract */
4995 0, /* nb_multiply */
4996 0, /* nb_remainder */
4997 0, /* nb_divmod */
4998 0, /* nb_power */
4999 0, /* nb_negative */
5000 0, /* nb_positive */
5001 0, /* nb_absolute */
5002 (inquiry)Pointer_bool, /* nb_bool */
Thomas Hellerf5049fc2008-08-19 19:49:49 +00005003};
5004
Thomas Heller34596a92009-04-24 20:50:00 +00005005PyTypeObject PyCPointer_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005006 PyVarObject_HEAD_INIT(NULL, 0)
5007 "_ctypes._Pointer",
5008 sizeof(CDataObject), /* tp_basicsize */
5009 0, /* tp_itemsize */
5010 0, /* tp_dealloc */
5011 0, /* tp_print */
5012 0, /* tp_getattr */
5013 0, /* tp_setattr */
5014 0, /* tp_reserved */
5015 0, /* tp_repr */
5016 &Pointer_as_number, /* tp_as_number */
5017 &Pointer_as_sequence, /* tp_as_sequence */
5018 &Pointer_as_mapping, /* tp_as_mapping */
5019 0, /* tp_hash */
5020 0, /* tp_call */
5021 0, /* tp_str */
5022 0, /* tp_getattro */
5023 0, /* tp_setattro */
5024 &PyCData_as_buffer, /* tp_as_buffer */
5025 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5026 "XXX to be provided", /* tp_doc */
5027 (traverseproc)PyCData_traverse, /* tp_traverse */
5028 (inquiry)PyCData_clear, /* tp_clear */
5029 0, /* tp_richcompare */
5030 0, /* tp_weaklistoffset */
5031 0, /* tp_iter */
5032 0, /* tp_iternext */
5033 0, /* tp_methods */
5034 0, /* tp_members */
5035 Pointer_getsets, /* tp_getset */
5036 0, /* tp_base */
5037 0, /* tp_dict */
5038 0, /* tp_descr_get */
5039 0, /* tp_descr_set */
5040 0, /* tp_dictoffset */
5041 (initproc)Pointer_init, /* tp_init */
5042 0, /* tp_alloc */
5043 Pointer_new, /* tp_new */
5044 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005045};
5046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005047
Thomas Hellerd4c93202006-03-08 19:35:11 +00005048/******************************************************************/
5049/*
5050 * Module initialization.
5051 */
5052
Martin v. Löwis1a214512008-06-11 05:26:20 +00005053static const char module_docs[] =
Thomas Hellerd4c93202006-03-08 19:35:11 +00005054"Create and manipulate C compatible data types in Python.";
5055
5056#ifdef MS_WIN32
5057
5058static char comerror_doc[] = "Raised when a COM method call failed.";
5059
Christian Heimesc0ac1062007-11-28 12:33:51 +00005060int
5061comerror_init(PyObject *self, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00005062{
5063 PyObject *hresult, *text, *details;
Christian Heimesc0ac1062007-11-28 12:33:51 +00005064 PyBaseExceptionObject *bself;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005065 PyObject *a;
5066 int status;
5067
Christian Heimes90aa7642007-12-19 02:45:37 +00005068 if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005069 return -1;
Christian Heimesc0ac1062007-11-28 12:33:51 +00005070
5071 if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005072 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005073
5074 a = PySequence_GetSlice(args, 1, PySequence_Size(args));
5075 if (!a)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005076 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005077 status = PyObject_SetAttrString(self, "args", a);
5078 Py_DECREF(a);
5079 if (status < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005080 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005081
5082 if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005083 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005084
5085 if (PyObject_SetAttrString(self, "text", text) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005086 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005087
5088 if (PyObject_SetAttrString(self, "details", details) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005089 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005090
Christian Heimesc0ac1062007-11-28 12:33:51 +00005091 bself = (PyBaseExceptionObject *)self;
5092 Py_DECREF(bself->args);
5093 bself->args = args;
5094 Py_INCREF(bself->args);
5095
5096 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005097}
5098
Christian Heimesc0ac1062007-11-28 12:33:51 +00005099static PyTypeObject PyComError_Type = {
5100 PyVarObject_HEAD_INIT(NULL, 0)
5101 "_ctypes.COMError", /* tp_name */
5102 sizeof(PyBaseExceptionObject), /* tp_basicsize */
5103 0, /* tp_itemsize */
5104 0, /* tp_dealloc */
5105 0, /* tp_print */
5106 0, /* tp_getattr */
5107 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00005108 0, /* tp_reserved */
Christian Heimesc0ac1062007-11-28 12:33:51 +00005109 0, /* tp_repr */
5110 0, /* tp_as_number */
5111 0, /* tp_as_sequence */
5112 0, /* tp_as_mapping */
5113 0, /* tp_hash */
5114 0, /* tp_call */
5115 0, /* tp_str */
5116 0, /* tp_getattro */
5117 0, /* tp_setattro */
5118 0, /* tp_as_buffer */
Thomas Heller60e5f5e2008-11-26 18:40:58 +00005119 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Christian Heimesc0ac1062007-11-28 12:33:51 +00005120 PyDoc_STR(comerror_doc), /* tp_doc */
5121 0, /* tp_traverse */
5122 0, /* tp_clear */
5123 0, /* tp_richcompare */
5124 0, /* tp_weaklistoffset */
5125 0, /* tp_iter */
5126 0, /* tp_iternext */
5127 0, /* tp_methods */
5128 0, /* tp_members */
5129 0, /* tp_getset */
5130 0, /* tp_base */
5131 0, /* tp_dict */
5132 0, /* tp_descr_get */
5133 0, /* tp_descr_set */
5134 0, /* tp_dictoffset */
5135 (initproc)comerror_init, /* tp_init */
5136 0, /* tp_alloc */
5137 0, /* tp_new */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005138};
5139
Christian Heimesc0ac1062007-11-28 12:33:51 +00005140
Thomas Hellerd4c93202006-03-08 19:35:11 +00005141static int
5142create_comerror(void)
5143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005144 PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception;
5145 if (PyType_Ready(&PyComError_Type) < 0)
5146 return -1;
Hirokazu Yamamoto34aa30c2010-09-12 16:06:18 +00005147 Py_INCREF(&PyComError_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005148 ComError = (PyObject*)&PyComError_Type;
5149 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005150}
5151
5152#endif
5153
5154static PyObject *
Guido van Rossumd8faa362007-04-27 19:54:29 +00005155string_at(const char *ptr, int size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00005156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005157 if (size == -1)
5158 return PyBytes_FromStringAndSize(ptr, strlen(ptr));
5159 return PyBytes_FromStringAndSize(ptr, size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005160}
5161
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005162static int
5163cast_check_pointertype(PyObject *arg)
5164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005165 StgDictObject *dict;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005167 if (PyCPointerTypeObject_Check(arg))
5168 return 1;
5169 if (PyCFuncPtrTypeObject_Check(arg))
5170 return 1;
5171 dict = PyType_stgdict(arg);
5172 if (dict) {
5173 if (PyUnicode_Check(dict->proto)
5174 && (strchr("sPzUZXO", _PyUnicode_AsString(dict->proto)[0]))) {
5175 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
5176 return 1;
5177 }
5178 }
5179 PyErr_Format(PyExc_TypeError,
5180 "cast() argument 2 must be a pointer type, not %s",
5181 PyType_Check(arg)
5182 ? ((PyTypeObject *)arg)->tp_name
5183 : Py_TYPE(arg)->tp_name);
5184 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005185}
5186
5187static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005188cast(void *ptr, PyObject *src, PyObject *ctype)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005190 CDataObject *result;
5191 if (0 == cast_check_pointertype(ctype))
5192 return NULL;
5193 result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
5194 if (result == NULL)
5195 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005196
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005197 /*
5198 The casted objects '_objects' member:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005200 It must certainly contain the source objects one.
5201 It must contain the source object itself.
5202 */
5203 if (CDataObject_Check(src)) {
5204 CDataObject *obj = (CDataObject *)src;
5205 /* PyCData_GetContainer will initialize src.b_objects, we need
5206 this so it can be shared */
5207 PyCData_GetContainer(obj);
5208 /* But we need a dictionary! */
5209 if (obj->b_objects == Py_None) {
5210 Py_DECREF(Py_None);
5211 obj->b_objects = PyDict_New();
5212 if (obj->b_objects == NULL)
5213 goto failed;
5214 }
5215 Py_XINCREF(obj->b_objects);
5216 result->b_objects = obj->b_objects;
5217 if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
5218 PyObject *index;
5219 int rc;
5220 index = PyLong_FromVoidPtr((void *)src);
5221 if (index == NULL)
5222 goto failed;
5223 rc = PyDict_SetItem(result->b_objects, index, src);
5224 Py_DECREF(index);
5225 if (rc == -1)
5226 goto failed;
5227 }
5228 }
5229 /* Should we assert that result is a pointer type? */
5230 memcpy(result->b_ptr, &ptr, sizeof(void *));
5231 return (PyObject *)result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005232
5233 failed:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005234 Py_DECREF(result);
5235 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005236}
Thomas Hellerd4c93202006-03-08 19:35:11 +00005237
5238#ifdef CTYPES_UNICODE
5239static PyObject *
5240wstring_at(const wchar_t *ptr, int size)
5241{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005242 Py_ssize_t ssize = size;
5243 if (ssize == -1)
5244 ssize = wcslen(ptr);
5245 return PyUnicode_FromWideChar(ptr, ssize);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005246}
5247#endif
5248
Martin v. Löwis1a214512008-06-11 05:26:20 +00005249
5250static struct PyModuleDef _ctypesmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005251 PyModuleDef_HEAD_INIT,
5252 "_ctypes",
5253 module_docs,
5254 -1,
5255 _ctypes_module_methods,
5256 NULL,
5257 NULL,
5258 NULL,
5259 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005260};
5261
Thomas Hellerfe8f8622006-03-14 19:53:09 +00005262PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00005263PyInit__ctypes(void)
Thomas Hellerd4c93202006-03-08 19:35:11 +00005264{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005265 PyObject *m;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005266
5267/* Note:
5268 ob_type is the metatype (the 'type'), defaults to PyType_Type,
5269 tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
5270*/
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005271#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005272 PyEval_InitThreads();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005273#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005274 m = PyModule_Create(&_ctypesmodule);
5275 if (!m)
5276 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005278 _ctypes_ptrtype_cache = PyDict_New();
5279 if (_ctypes_ptrtype_cache == NULL)
5280 return NULL;
Thomas Heller3071f812008-04-14 16:17:33 +00005281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005282 PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache);
Thomas Heller3071f812008-04-14 16:17:33 +00005283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005284 _unpickle = PyObject_GetAttrString(m, "_unpickle");
5285 if (_unpickle == NULL)
5286 return NULL;
Thomas Heller13394e92008-02-13 20:40:44 +00005287
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005288 if (PyType_Ready(&PyCArg_Type) < 0)
5289 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005291 if (PyType_Ready(&PyCThunk_Type) < 0)
5292 return NULL;
Thomas Hellere106dc32008-04-24 18:39:36 +00005293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005294 /* StgDict is derived from PyDict_Type */
5295 PyCStgDict_Type.tp_base = &PyDict_Type;
5296 if (PyType_Ready(&PyCStgDict_Type) < 0)
5297 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005299 /*************************************************
5300 *
5301 * Metaclasses
5302 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005304 PyCStructType_Type.tp_base = &PyType_Type;
5305 if (PyType_Ready(&PyCStructType_Type) < 0)
5306 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005308 UnionType_Type.tp_base = &PyType_Type;
5309 if (PyType_Ready(&UnionType_Type) < 0)
5310 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005312 PyCPointerType_Type.tp_base = &PyType_Type;
5313 if (PyType_Ready(&PyCPointerType_Type) < 0)
5314 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005316 PyCArrayType_Type.tp_base = &PyType_Type;
5317 if (PyType_Ready(&PyCArrayType_Type) < 0)
5318 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005320 PyCSimpleType_Type.tp_base = &PyType_Type;
5321 if (PyType_Ready(&PyCSimpleType_Type) < 0)
5322 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005324 PyCFuncPtrType_Type.tp_base = &PyType_Type;
5325 if (PyType_Ready(&PyCFuncPtrType_Type) < 0)
5326 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005328 /*************************************************
5329 *
5330 * Classes using a custom metaclass
5331 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005333 if (PyType_Ready(&PyCData_Type) < 0)
5334 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005336 Py_TYPE(&Struct_Type) = &PyCStructType_Type;
5337 Struct_Type.tp_base = &PyCData_Type;
5338 if (PyType_Ready(&Struct_Type) < 0)
5339 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005340 Py_INCREF(&Struct_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005341 PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005343 Py_TYPE(&Union_Type) = &UnionType_Type;
5344 Union_Type.tp_base = &PyCData_Type;
5345 if (PyType_Ready(&Union_Type) < 0)
5346 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005347 Py_INCREF(&Union_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005348 PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005350 Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type;
5351 PyCPointer_Type.tp_base = &PyCData_Type;
5352 if (PyType_Ready(&PyCPointer_Type) < 0)
5353 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005354 Py_INCREF(&PyCPointer_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005355 PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005357 Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type;
5358 PyCArray_Type.tp_base = &PyCData_Type;
5359 if (PyType_Ready(&PyCArray_Type) < 0)
5360 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005361 Py_INCREF(&PyCArray_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005362 PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005364 Py_TYPE(&Simple_Type) = &PyCSimpleType_Type;
5365 Simple_Type.tp_base = &PyCData_Type;
5366 if (PyType_Ready(&Simple_Type) < 0)
5367 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005368 Py_INCREF(&Simple_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005369 PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005371 Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type;
5372 PyCFuncPtr_Type.tp_base = &PyCData_Type;
5373 if (PyType_Ready(&PyCFuncPtr_Type) < 0)
5374 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005375 Py_INCREF(&PyCFuncPtr_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005376 PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005378 /*************************************************
5379 *
5380 * Simple classes
5381 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005383 /* PyCField_Type is derived from PyBaseObject_Type */
5384 if (PyType_Ready(&PyCField_Type) < 0)
5385 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005387 /*************************************************
5388 *
5389 * Other stuff
5390 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005392 DictRemover_Type.tp_new = PyType_GenericNew;
5393 if (PyType_Ready(&DictRemover_Type) < 0)
5394 return NULL;
Christian Heimes969fe572008-01-25 11:23:10 +00005395
Thomas Hellerd4c93202006-03-08 19:35:11 +00005396#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005397 if (create_comerror() < 0)
5398 return NULL;
5399 PyModule_AddObject(m, "COMError", ComError);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005401 PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
5402 PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
Thomas Hellerd4c93202006-03-08 19:35:11 +00005403#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005404 PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL));
5405 PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
5406 PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
5407 PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
5408 PyModule_AddStringConstant(m, "__version__", "1.1.0");
Thomas Hellerd4c93202006-03-08 19:35:11 +00005409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005410 PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
5411 PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
5412 PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
5413 PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
Thomas Hellerd4c93202006-03-08 19:35:11 +00005414#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005415 PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
Thomas Hellerd4c93202006-03-08 19:35:11 +00005416#endif
5417
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005418/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
5419#ifndef RTLD_LOCAL
5420#define RTLD_LOCAL 0
5421#endif
5422
5423/* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
5424 RTLD_LOCAL.
5425*/
5426#ifndef RTLD_GLOBAL
5427#define RTLD_GLOBAL RTLD_LOCAL
5428#endif
5429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005430 PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL));
5431 PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL));
5432
5433 PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5434 if (PyExc_ArgError) {
5435 Py_INCREF(PyExc_ArgError);
5436 PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
5437 }
5438 return m;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005439}
5440
Thomas Hellerd4c93202006-03-08 19:35:11 +00005441/*
5442 Local Variables:
5443 compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
5444 End:
5445*/