blob: 9a37aacf0cbc0c2286eefcd218527e5f7b3267fb [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 Py_CLEAR(self->b_objects);
2446 if ((self->b_needsfree)
Antoine Pitrou305e1a72012-12-08 11:05:50 +01002447 && _CDataObject_HasExternalBuffer(self))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002448 PyMem_Free(self->b_ptr);
2449 self->b_ptr = NULL;
2450 Py_CLEAR(self->b_base);
2451 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002452}
2453
2454static void
Thomas Heller34596a92009-04-24 20:50:00 +00002455PyCData_dealloc(PyObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002457 PyCData_clear((CDataObject *)self);
2458 Py_TYPE(self)->tp_free(self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002459}
2460
Thomas Heller34596a92009-04-24 20:50:00 +00002461static PyMemberDef PyCData_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002462 { "_b_base_", T_OBJECT,
2463 offsetof(CDataObject, b_base), READONLY,
2464 "the base object" },
2465 { "_b_needsfree_", T_INT,
2466 offsetof(CDataObject, b_needsfree), READONLY,
2467 "whether the object owns the memory or not" },
2468 { "_objects", T_OBJECT,
2469 offsetof(CDataObject, b_objects), READONLY,
2470 "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2471 { NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +00002472};
2473
Thomas Heller34596a92009-04-24 20:50:00 +00002474static int PyCData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002475{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 CDataObject *self = (CDataObject *)_self;
2477 StgDictObject *dict = PyObject_stgdict(_self);
2478 Py_ssize_t i;
Thomas Hellerb041fda2008-04-30 17:11:46 +00002479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 if (view == NULL) return 0;
Thomas Hellerb041fda2008-04-30 17:11:46 +00002481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002482 view->buf = self->b_ptr;
2483 view->obj = _self;
2484 Py_INCREF(_self);
2485 view->len = self->b_size;
2486 view->readonly = 0;
2487 /* use default format character if not set */
2488 view->format = dict->format ? dict->format : "B";
2489 view->ndim = dict->ndim;
2490 view->shape = dict->shape;
2491 view->itemsize = self->b_size;
Amaury Forgeot d'Arc326e1892011-08-30 21:40:20 +02002492 if (view->itemsize) {
2493 for (i = 0; i < view->ndim; ++i) {
2494 view->itemsize /= dict->shape[i];
2495 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 }
2497 view->strides = NULL;
2498 view->suboffsets = NULL;
2499 view->internal = NULL;
2500 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002501}
2502
Thomas Heller34596a92009-04-24 20:50:00 +00002503static PyBufferProcs PyCData_as_buffer = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002504 PyCData_NewGetBuffer,
2505 NULL,
Thomas Hellerd4c93202006-03-08 19:35:11 +00002506};
2507
2508/*
2509 * CData objects are mutable, so they cannot be hashable!
2510 */
Georg Brandld49bf5e2010-10-18 07:30:06 +00002511static Py_hash_t
Thomas Heller34596a92009-04-24 20:50:00 +00002512PyCData_nohash(PyObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002513{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002514 PyErr_SetString(PyExc_TypeError, "unhashable type");
2515 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002516}
2517
Thomas Heller13394e92008-02-13 20:40:44 +00002518static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002519PyCData_reduce(PyObject *_self, PyObject *args)
Thomas Heller13394e92008-02-13 20:40:44 +00002520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002521 CDataObject *self = (CDataObject *)_self;
Thomas Heller13394e92008-02-13 20:40:44 +00002522
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002523 if (PyObject_stgdict(_self)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
2524 PyErr_SetString(PyExc_ValueError,
2525 "ctypes objects containing pointers cannot be pickled");
2526 return NULL;
2527 }
2528 return Py_BuildValue("O(O(NN))",
2529 _unpickle,
2530 Py_TYPE(_self),
2531 PyObject_GetAttrString(_self, "__dict__"),
2532 PyBytes_FromStringAndSize(self->b_ptr, self->b_size));
Thomas Heller13394e92008-02-13 20:40:44 +00002533}
2534
2535static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002536PyCData_setstate(PyObject *_self, PyObject *args)
Thomas Heller13394e92008-02-13 20:40:44 +00002537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002538 void *data;
2539 Py_ssize_t len;
2540 int res;
2541 PyObject *dict, *mydict;
2542 CDataObject *self = (CDataObject *)_self;
2543 if (!PyArg_ParseTuple(args, "Os#", &dict, &data, &len))
2544 return NULL;
2545 if (len > self->b_size)
2546 len = self->b_size;
2547 memmove(self->b_ptr, data, len);
2548 mydict = PyObject_GetAttrString(_self, "__dict__");
2549 res = PyDict_Update(mydict, dict);
2550 Py_DECREF(mydict);
2551 if (res == -1)
2552 return NULL;
2553 Py_INCREF(Py_None);
2554 return Py_None;
Thomas Heller13394e92008-02-13 20:40:44 +00002555}
2556
Thomas Hellerd4c93202006-03-08 19:35:11 +00002557/*
2558 * default __ctypes_from_outparam__ method returns self.
2559 */
2560static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002561PyCData_from_outparam(PyObject *self, PyObject *args)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002562{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002563 Py_INCREF(self);
2564 return self;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002565}
2566
Thomas Heller34596a92009-04-24 20:50:00 +00002567static PyMethodDef PyCData_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002568 { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
2569 { "__reduce__", PyCData_reduce, METH_NOARGS, },
2570 { "__setstate__", PyCData_setstate, METH_VARARGS, },
2571 { NULL, NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +00002572};
2573
Thomas Heller34596a92009-04-24 20:50:00 +00002574PyTypeObject PyCData_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002575 PyVarObject_HEAD_INIT(NULL, 0)
2576 "_ctypes._CData",
2577 sizeof(CDataObject), /* tp_basicsize */
2578 0, /* tp_itemsize */
2579 PyCData_dealloc, /* tp_dealloc */
2580 0, /* tp_print */
2581 0, /* tp_getattr */
2582 0, /* tp_setattr */
2583 0, /* tp_reserved */
2584 0, /* tp_repr */
2585 0, /* tp_as_number */
2586 0, /* tp_as_sequence */
2587 0, /* tp_as_mapping */
2588 PyCData_nohash, /* tp_hash */
2589 0, /* tp_call */
2590 0, /* tp_str */
2591 0, /* tp_getattro */
2592 0, /* tp_setattro */
2593 &PyCData_as_buffer, /* tp_as_buffer */
2594 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2595 "XXX to be provided", /* tp_doc */
2596 (traverseproc)PyCData_traverse, /* tp_traverse */
2597 (inquiry)PyCData_clear, /* tp_clear */
2598 0, /* tp_richcompare */
2599 0, /* tp_weaklistoffset */
2600 0, /* tp_iter */
2601 0, /* tp_iternext */
2602 PyCData_methods, /* tp_methods */
2603 PyCData_members, /* tp_members */
2604 0, /* tp_getset */
2605 0, /* tp_base */
2606 0, /* tp_dict */
2607 0, /* tp_descr_get */
2608 0, /* tp_descr_set */
2609 0, /* tp_dictoffset */
2610 0, /* tp_init */
2611 0, /* tp_alloc */
2612 0, /* tp_new */
2613 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00002614};
2615
Thomas Heller34596a92009-04-24 20:50:00 +00002616static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002617{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002618 if ((size_t)dict->size <= sizeof(obj->b_value)) {
2619 /* No need to call malloc, can use the default buffer */
2620 obj->b_ptr = (char *)&obj->b_value;
2621 /* The b_needsfree flag does not mean that we actually did
2622 call PyMem_Malloc to allocate the memory block; instead it
2623 means we are the *owner* of the memory and are responsible
2624 for freeing resources associated with the memory. This is
2625 also the reason that b_needsfree is exposed to Python.
2626 */
2627 obj->b_needsfree = 1;
2628 } else {
2629 /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2630 33% of the creation time for c_int().
2631 */
2632 obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2633 if (obj->b_ptr == NULL) {
2634 PyErr_NoMemory();
2635 return -1;
2636 }
2637 obj->b_needsfree = 1;
2638 memset(obj->b_ptr, 0, dict->size);
2639 }
2640 obj->b_size = dict->size;
2641 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002642}
2643
2644PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002645PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002646{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002647 CDataObject *cmem;
2648 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002650 assert(PyType_Check(type));
2651 dict = PyType_stgdict(type);
2652 if (!dict) {
2653 PyErr_SetString(PyExc_TypeError,
2654 "abstract class");
2655 return NULL;
2656 }
2657 dict->flags |= DICTFLAG_FINAL;
2658 cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2659 if (cmem == NULL)
2660 return NULL;
2661 assert(CDataObject_Check(cmem));
Thomas Hellerd4c93202006-03-08 19:35:11 +00002662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002663 cmem->b_length = dict->length;
2664 cmem->b_size = dict->size;
2665 if (base) { /* use base's buffer */
2666 assert(CDataObject_Check(base));
2667 cmem->b_ptr = adr;
2668 cmem->b_needsfree = 0;
2669 Py_INCREF(base);
2670 cmem->b_base = (CDataObject *)base;
2671 cmem->b_index = index;
2672 } else { /* copy contents of adr */
2673 if (-1 == PyCData_MallocBuffer(cmem, dict)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002674 Py_DECREF(cmem);
Christian Heimes8c4c1f62013-07-21 16:24:51 +02002675 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002676 }
2677 memcpy(cmem->b_ptr, adr, dict->size);
2678 cmem->b_index = index;
2679 }
2680 return (PyObject *)cmem;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002681}
2682
2683/*
2684 Box a memory block into a CData instance.
2685*/
2686PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002687PyCData_AtAddress(PyObject *type, void *buf)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002688{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002689 CDataObject *pd;
2690 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002691
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002692 assert(PyType_Check(type));
2693 dict = PyType_stgdict(type);
2694 if (!dict) {
2695 PyErr_SetString(PyExc_TypeError,
2696 "abstract class");
2697 return NULL;
2698 }
2699 dict->flags |= DICTFLAG_FINAL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002701 pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2702 if (!pd)
2703 return NULL;
2704 assert(CDataObject_Check(pd));
2705 pd->b_ptr = (char *)buf;
2706 pd->b_length = dict->length;
2707 pd->b_size = dict->size;
2708 return (PyObject *)pd;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002709}
2710
2711/*
2712 This function returns TRUE for c_int, c_void_p, and these kind of
2713 classes. FALSE otherwise FALSE also for subclasses of c_int and
2714 such.
2715*/
Thomas Heller34596a92009-04-24 20:50:00 +00002716int _ctypes_simple_instance(PyObject *obj)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002717{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002718 PyTypeObject *type = (PyTypeObject *)obj;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002719
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002720 if (PyCSimpleTypeObject_Check(type))
2721 return type->tp_base != &Simple_Type;
2722 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002723}
2724
2725PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002726PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002727 Py_ssize_t index, Py_ssize_t size, char *adr)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002729 StgDictObject *dict;
2730 if (getfunc)
2731 return getfunc(adr, size);
2732 assert(type);
2733 dict = PyType_stgdict(type);
2734 if (dict && dict->getfunc && !_ctypes_simple_instance(type))
2735 return dict->getfunc(adr, size);
2736 return PyCData_FromBaseObj(type, src, index, adr);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002737}
2738
2739/*
Thomas Heller34596a92009-04-24 20:50:00 +00002740 Helper function for PyCData_set below.
Thomas Hellerd4c93202006-03-08 19:35:11 +00002741*/
2742static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002743_PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002744 Py_ssize_t size, char *ptr)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002746 CDataObject *src;
Benjamin Peterson39530f82011-03-26 18:04:09 -05002747 int err;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002749 if (setfunc)
2750 return setfunc(ptr, value, size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002752 if (!CDataObject_Check(value)) {
2753 StgDictObject *dict = PyType_stgdict(type);
2754 if (dict && dict->setfunc)
2755 return dict->setfunc(ptr, value, size);
2756 /*
2757 If value is a tuple, we try to call the type with the tuple
2758 and use the result!
2759 */
2760 assert(PyType_Check(type));
2761 if (PyTuple_Check(value)) {
2762 PyObject *ob;
2763 PyObject *result;
2764 ob = PyObject_CallObject(type, value);
2765 if (ob == NULL) {
2766 _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
2767 ((PyTypeObject *)type)->tp_name);
2768 return NULL;
2769 }
2770 result = _PyCData_set(dst, type, setfunc, ob,
2771 size, ptr);
2772 Py_DECREF(ob);
2773 return result;
2774 } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
2775 *(void **)ptr = NULL;
2776 Py_INCREF(Py_None);
2777 return Py_None;
2778 } else {
2779 PyErr_Format(PyExc_TypeError,
2780 "expected %s instance, got %s",
2781 ((PyTypeObject *)type)->tp_name,
2782 Py_TYPE(value)->tp_name);
2783 return NULL;
2784 }
2785 }
2786 src = (CDataObject *)value;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002787
Benjamin Peterson39530f82011-03-26 18:04:09 -05002788 err = PyObject_IsInstance(value, type);
2789 if (err == -1)
2790 return NULL;
2791 if (err) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002792 memcpy(ptr,
2793 src->b_ptr,
2794 size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002796 if (PyCPointerTypeObject_Check(type))
2797 /* XXX */;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002799 value = GetKeepedObjects(src);
2800 Py_INCREF(value);
2801 return value;
2802 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002803
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002804 if (PyCPointerTypeObject_Check(type)
2805 && ArrayObject_Check(value)) {
2806 StgDictObject *p1, *p2;
2807 PyObject *keep;
2808 p1 = PyObject_stgdict(value);
2809 assert(p1); /* Cannot be NULL for array instances */
2810 p2 = PyType_stgdict(type);
2811 assert(p2); /* Cannot be NULL for pointer types */
Thomas Hellerd4c93202006-03-08 19:35:11 +00002812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002813 if (p1->proto != p2->proto) {
2814 PyErr_Format(PyExc_TypeError,
2815 "incompatible types, %s instance instead of %s instance",
2816 Py_TYPE(value)->tp_name,
2817 ((PyTypeObject *)type)->tp_name);
2818 return NULL;
2819 }
2820 *(void **)ptr = src->b_ptr;
2821
2822 keep = GetKeepedObjects(src);
2823 /*
2824 We are assigning an array object to a field which represents
2825 a pointer. This has the same effect as converting an array
2826 into a pointer. So, again, we have to keep the whole object
2827 pointed to (which is the array in this case) alive, and not
2828 only it's object list. So we create a tuple, containing
2829 b_objects list PLUS the array itself, and return that!
2830 */
2831 return PyTuple_Pack(2, keep, value);
2832 }
2833 PyErr_Format(PyExc_TypeError,
2834 "incompatible types, %s instance instead of %s instance",
2835 Py_TYPE(value)->tp_name,
2836 ((PyTypeObject *)type)->tp_name);
2837 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002838}
2839
2840/*
2841 * Set a slice in object 'dst', which has the type 'type',
2842 * to the value 'value'.
2843 */
2844int
Thomas Heller34596a92009-04-24 20:50:00 +00002845PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002846 Py_ssize_t index, Py_ssize_t size, char *ptr)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002848 CDataObject *mem = (CDataObject *)dst;
2849 PyObject *result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002851 if (!CDataObject_Check(dst)) {
2852 PyErr_SetString(PyExc_TypeError,
2853 "not a ctype instance");
2854 return -1;
2855 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002856
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002857 result = _PyCData_set(mem, type, setfunc, value,
2858 size, ptr);
2859 if (result == NULL)
2860 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002862 /* KeepRef steals a refcount from it's last argument */
2863 /* If KeepRef fails, we are stumped. The dst memory block has already
2864 been changed */
2865 return KeepRef(mem, index, result);
Thomas Hellerd4c93202006-03-08 19:35:11 +00002866}
2867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002868
Thomas Hellerd4c93202006-03-08 19:35:11 +00002869/******************************************************************/
2870static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002871GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002872{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002873 CDataObject *obj;
2874 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002875
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002876 dict = PyType_stgdict((PyObject *)type);
2877 if (!dict) {
2878 PyErr_SetString(PyExc_TypeError,
2879 "abstract class");
2880 return NULL;
2881 }
2882 dict->flags |= DICTFLAG_FINAL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002883
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002884 obj = (CDataObject *)type->tp_alloc(type, 0);
2885 if (!obj)
2886 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002888 obj->b_base = NULL;
2889 obj->b_index = 0;
2890 obj->b_objects = NULL;
2891 obj->b_length = dict->length;
2892
2893 if (-1 == PyCData_MallocBuffer(obj, dict)) {
2894 Py_DECREF(obj);
2895 return NULL;
2896 }
2897 return (PyObject *)obj;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002898}
2899/*****************************************************************/
2900/*
Thomas Heller34596a92009-04-24 20:50:00 +00002901 PyCFuncPtr_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00002902*/
2903
Thomas Hellerd4c93202006-03-08 19:35:11 +00002904static int
Thomas Heller34596a92009-04-24 20:50:00 +00002905PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002906{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002907 if (ob && !PyCallable_Check(ob)) {
2908 PyErr_SetString(PyExc_TypeError,
2909 "the errcheck attribute must be callable");
2910 return -1;
2911 }
2912 Py_XDECREF(self->errcheck);
2913 Py_XINCREF(ob);
2914 self->errcheck = ob;
2915 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002916}
2917
2918static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002919PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002920{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002921 if (self->errcheck) {
2922 Py_INCREF(self->errcheck);
2923 return self->errcheck;
2924 }
2925 Py_INCREF(Py_None);
2926 return Py_None;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002927}
2928
2929static int
Thomas Heller34596a92009-04-24 20:50:00 +00002930PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002932 if (ob == NULL) {
2933 Py_XDECREF(self->restype);
2934 self->restype = NULL;
2935 Py_XDECREF(self->checker);
2936 self->checker = NULL;
2937 return 0;
2938 }
2939 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2940 PyErr_SetString(PyExc_TypeError,
2941 "restype must be a type, a callable, or None");
2942 return -1;
2943 }
2944 Py_XDECREF(self->checker);
2945 Py_XDECREF(self->restype);
2946 Py_INCREF(ob);
2947 self->restype = ob;
2948 self->checker = PyObject_GetAttrString(ob, "_check_retval_");
2949 if (self->checker == NULL)
2950 PyErr_Clear();
2951 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002952}
2953
2954static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002955PyCFuncPtr_get_restype(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002956{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002957 StgDictObject *dict;
2958 if (self->restype) {
2959 Py_INCREF(self->restype);
2960 return self->restype;
2961 }
2962 dict = PyObject_stgdict((PyObject *)self);
2963 assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
2964 if (dict->restype) {
2965 Py_INCREF(dict->restype);
2966 return dict->restype;
2967 } else {
2968 Py_INCREF(Py_None);
2969 return Py_None;
2970 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00002971}
2972
2973static int
Thomas Heller34596a92009-04-24 20:50:00 +00002974PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002975{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002976 PyObject *converters;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002978 if (ob == NULL || ob == Py_None) {
2979 Py_XDECREF(self->converters);
2980 self->converters = NULL;
2981 Py_XDECREF(self->argtypes);
2982 self->argtypes = NULL;
2983 } else {
2984 converters = converters_from_argtypes(ob);
2985 if (!converters)
2986 return -1;
2987 Py_XDECREF(self->converters);
2988 self->converters = converters;
2989 Py_XDECREF(self->argtypes);
2990 Py_INCREF(ob);
2991 self->argtypes = ob;
2992 }
2993 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00002994}
2995
2996static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00002997PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00002998{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002999 StgDictObject *dict;
3000 if (self->argtypes) {
3001 Py_INCREF(self->argtypes);
3002 return self->argtypes;
3003 }
3004 dict = PyObject_stgdict((PyObject *)self);
3005 assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3006 if (dict->argtypes) {
3007 Py_INCREF(dict->argtypes);
3008 return dict->argtypes;
3009 } else {
3010 Py_INCREF(Py_None);
3011 return Py_None;
3012 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003013}
3014
Thomas Heller34596a92009-04-24 20:50:00 +00003015static PyGetSetDef PyCFuncPtr_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003016 { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
3017 "a function to check for errors", NULL },
3018 { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
3019 "specify the result type", NULL },
3020 { "argtypes", (getter)PyCFuncPtr_get_argtypes,
3021 (setter)PyCFuncPtr_set_argtypes,
3022 "specify the argument types", NULL },
3023 { NULL, NULL }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003024};
3025
3026#ifdef MS_WIN32
3027static PPROC FindAddress(void *handle, char *name, PyObject *type)
3028{
Guido van Rossumcd16bf62007-06-13 18:07:49 +00003029#ifdef MS_WIN64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003030 /* win64 has no stdcall calling conv, so it should
3031 also not have the name mangling of it.
3032 */
3033 return (PPROC)GetProcAddress(handle, name);
Guido van Rossumcd16bf62007-06-13 18:07:49 +00003034#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003035 PPROC address;
3036 char *mangled_name;
3037 int i;
3038 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003039
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003040 address = (PPROC)GetProcAddress(handle, name);
3041 if (address)
3042 return address;
3043 if (((size_t)name & ~0xFFFF) == 0) {
3044 return NULL;
3045 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003047 dict = PyType_stgdict((PyObject *)type);
3048 /* It should not happen that dict is NULL, but better be safe */
3049 if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
3050 return address;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003052 /* for stdcall, try mangled names:
3053 funcname -> _funcname@<n>
3054 where n is 0, 4, 8, 12, ..., 128
3055 */
3056 mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
3057 if (!mangled_name)
3058 return NULL;
3059 for (i = 0; i < 32; ++i) {
3060 sprintf(mangled_name, "_%s@%d", name, i*4);
3061 address = (PPROC)GetProcAddress(handle, mangled_name);
3062 if (address)
3063 return address;
3064 }
3065 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00003066#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +00003067}
3068#endif
3069
3070/* Return 1 if usable, 0 else and exception set. */
3071static int
Guido van Rossumcd16bf62007-06-13 18:07:49 +00003072_check_outarg_type(PyObject *arg, Py_ssize_t index)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003074 StgDictObject *dict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003076 if (PyCPointerTypeObject_Check(arg))
3077 return 1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003078
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003079 if (PyCArrayTypeObject_Check(arg))
3080 return 1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003081
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003082 dict = PyType_stgdict(arg);
3083 if (dict
3084 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
3085 && PyUnicode_Check(dict->proto)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003086/* 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 +00003087 && (strchr("PzZ", _PyUnicode_AsString(dict->proto)[0]))) {
3088 return 1;
3089 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003091 PyErr_Format(PyExc_TypeError,
3092 "'out' parameter %d must be a pointer type, not %s",
3093 Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
3094 PyType_Check(arg) ?
3095 ((PyTypeObject *)arg)->tp_name :
3096 Py_TYPE(arg)->tp_name);
3097 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003098}
3099
3100/* Returns 1 on success, 0 on error */
3101static int
3102_validate_paramflags(PyTypeObject *type, PyObject *paramflags)
3103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003104 Py_ssize_t i, len;
3105 StgDictObject *dict;
3106 PyObject *argtypes;
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00003107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003108 dict = PyType_stgdict((PyObject *)type);
3109 assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */
3110 argtypes = dict->argtypes;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003112 if (paramflags == NULL || dict->argtypes == NULL)
3113 return 1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003115 if (!PyTuple_Check(paramflags)) {
3116 PyErr_SetString(PyExc_TypeError,
3117 "paramflags must be a tuple or None");
3118 return 0;
3119 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003120
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003121 len = PyTuple_GET_SIZE(paramflags);
3122 if (len != PyTuple_GET_SIZE(dict->argtypes)) {
3123 PyErr_SetString(PyExc_ValueError,
3124 "paramflags must have the same length as argtypes");
3125 return 0;
3126 }
3127
3128 for (i = 0; i < len; ++i) {
3129 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3130 int flag;
3131 char *name;
3132 PyObject *defval;
3133 PyObject *typ;
3134 if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) {
3135 PyErr_SetString(PyExc_TypeError,
3136 "paramflags must be a sequence of (int [,string [,value]]) tuples");
3137 return 0;
3138 }
3139 typ = PyTuple_GET_ITEM(argtypes, i);
3140 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3141 case 0:
3142 case PARAMFLAG_FIN:
3143 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3144 case PARAMFLAG_FIN | PARAMFLAG_FOUT:
3145 break;
3146 case PARAMFLAG_FOUT:
3147 if (!_check_outarg_type(typ, i+1))
3148 return 0;
3149 break;
3150 default:
3151 PyErr_Format(PyExc_TypeError,
3152 "paramflag value %d not supported",
3153 flag);
3154 return 0;
3155 }
3156 }
3157 return 1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003158}
3159
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003160static int
3161_get_name(PyObject *obj, char **pname)
3162{
3163#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003164 if (PyLong_Check(obj)) {
3165 /* We have to use MAKEINTRESOURCEA for Windows CE.
3166 Works on Windows as well, of course.
3167 */
3168 *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF);
3169 return 1;
3170 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003171#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003172 if (PyBytes_Check(obj)) {
3173 *pname = PyBytes_AS_STRING(obj);
3174 return *pname ? 1 : 0;
3175 }
3176 if (PyUnicode_Check(obj)) {
3177 *pname = _PyUnicode_AsString(obj);
3178 return *pname ? 1 : 0;
3179 }
3180 PyErr_SetString(PyExc_TypeError,
3181 "function name must be string or integer");
3182 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003183}
3184
3185
Thomas Hellerd4c93202006-03-08 19:35:11 +00003186static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003187PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003188{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003189 char *name;
3190 int (* address)(void);
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +02003191 PyObject *ftuple;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003192 PyObject *dll;
3193 PyObject *obj;
3194 PyCFuncPtrObject *self;
3195 void *handle;
3196 PyObject *paramflags = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003197
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +02003198 if (!PyArg_ParseTuple(args, "O|O", &ftuple, &paramflags))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003199 return NULL;
3200 if (paramflags == Py_None)
3201 paramflags = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003202
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +02003203 ftuple = PySequence_Tuple(ftuple);
3204 if (!ftuple)
3205 /* Here ftuple is a borrowed reference */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003206 return NULL;
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +02003207
3208 if (!PyArg_ParseTuple(ftuple, "O&O", _get_name, &name, &dll)) {
3209 Py_DECREF(ftuple);
3210 return NULL;
3211 }
3212
3213 obj = PyObject_GetAttrString(dll, "_handle");
3214 if (!obj) {
3215 Py_DECREF(ftuple);
3216 return NULL;
3217 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003218 if (!PyLong_Check(obj)) {
3219 PyErr_SetString(PyExc_TypeError,
3220 "the _handle attribute of the second argument must be an integer");
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +02003221 Py_DECREF(ftuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003222 Py_DECREF(obj);
3223 return NULL;
3224 }
3225 handle = (void *)PyLong_AsVoidPtr(obj);
3226 Py_DECREF(obj);
3227 if (PyErr_Occurred()) {
3228 PyErr_SetString(PyExc_ValueError,
3229 "could not convert the _handle attribute to a pointer");
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +02003230 Py_DECREF(ftuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003231 return NULL;
3232 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003233
3234#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003235 address = FindAddress(handle, name, (PyObject *)type);
3236 if (!address) {
3237 if (!IS_INTRESOURCE(name))
3238 PyErr_Format(PyExc_AttributeError,
3239 "function '%s' not found",
3240 name);
3241 else
3242 PyErr_Format(PyExc_AttributeError,
3243 "function ordinal %d not found",
3244 (WORD)(size_t)name);
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +02003245 Py_DECREF(ftuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003246 return NULL;
3247 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003248#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003249 address = (PPROC)ctypes_dlsym(handle, name);
3250 if (!address) {
Thomas Hellerd4c93202006-03-08 19:35:11 +00003251#ifdef __CYGWIN__
3252/* dlerror() isn't very helpful on cygwin */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003253 PyErr_Format(PyExc_AttributeError,
3254 "function '%s' not found (%s) ",
3255 name);
Benjamin Petersond75fcb42009-02-19 04:22:03 +00003256#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003257 PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
Thomas Hellerd4c93202006-03-08 19:35:11 +00003258#endif
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +02003259 Py_DECREF(ftuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003260 return NULL;
3261 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003262#endif
Serhiy Storchaka19c4e0d2013-02-04 12:47:24 +02003263 Py_INCREF(dll); /* for KeepRef */
3264 Py_DECREF(ftuple);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003265 if (!_validate_paramflags(type, paramflags))
3266 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003268 self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3269 if (!self)
3270 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003272 Py_XINCREF(paramflags);
3273 self->paramflags = paramflags;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003275 *(void **)self->b_ptr = address;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003276
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003277 if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
3278 Py_DECREF((PyObject *)self);
3279 return NULL;
3280 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003281
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003282 Py_INCREF(self);
3283 self->callable = (PyObject *)self;
3284 return (PyObject *)self;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003285}
3286
3287#ifdef MS_WIN32
3288static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003289PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003291 PyCFuncPtrObject *self;
3292 int index;
3293 char *name = NULL;
3294 PyObject *paramflags = NULL;
3295 GUID *iid = NULL;
3296 Py_ssize_t iid_len = 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003298 if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
3299 return NULL;
3300 if (paramflags == Py_None)
3301 paramflags = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003303 if (!_validate_paramflags(type, paramflags))
3304 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003306 self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3307 self->index = index + 0x1000;
3308 Py_XINCREF(paramflags);
3309 self->paramflags = paramflags;
3310 if (iid_len == sizeof(GUID))
3311 self->iid = iid;
3312 return (PyObject *)self;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003313}
3314#endif
3315
3316/*
Thomas Heller34596a92009-04-24 20:50:00 +00003317 PyCFuncPtr_new accepts different argument lists in addition to the standard
Thomas Hellerd4c93202006-03-08 19:35:11 +00003318 _basespec_ keyword arg:
3319
3320 one argument form
3321 "i" - function address
3322 "O" - must be a callable, creates a C callable function
3323
3324 two or more argument forms (the third argument is a paramflags tuple)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003325 "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
3326 "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
3327 "is|..." - vtable index, method name, creates callable calling COM vtbl
Thomas Hellerd4c93202006-03-08 19:35:11 +00003328*/
3329static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003330PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003332 PyCFuncPtrObject *self;
3333 PyObject *callable;
3334 StgDictObject *dict;
3335 CThunkObject *thunk;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003337 if (PyTuple_GET_SIZE(args) == 0)
3338 return GenericPyCData_new(type, args, kwds);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003340 if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
3341 return PyCFuncPtr_FromDll(type, args, kwds);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003342
3343#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003344 if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0)))
3345 return PyCFuncPtr_FromVtblIndex(type, args, kwds);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003346#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +00003347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003348 if (1 == PyTuple_GET_SIZE(args)
3349 && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
3350 CDataObject *ob;
3351 void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
3352 if (ptr == NULL && PyErr_Occurred())
3353 return NULL;
3354 ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
3355 if (ob == NULL)
3356 return NULL;
3357 *(void **)ob->b_ptr = ptr;
3358 return (PyObject *)ob;
3359 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003361 if (!PyArg_ParseTuple(args, "O", &callable))
3362 return NULL;
3363 if (!PyCallable_Check(callable)) {
3364 PyErr_SetString(PyExc_TypeError,
3365 "argument must be callable or integer function address");
3366 return NULL;
3367 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003369 /* XXX XXX This would allow to pass additional options. For COM
3370 method *implementations*, we would probably want different
3371 behaviour than in 'normal' callback functions: return a HRESULT if
Ezio Melotti13925002011-03-16 11:05:33 +02003372 an exception occurs in the callback, and print the traceback not
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003373 only on the console, but also to OutputDebugString() or something
3374 like that.
3375 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00003376/*
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003377 if (kwds && PyDict_GetItemString(kwds, "options")) {
3378 ...
3379 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003380*/
3381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003382 dict = PyType_stgdict((PyObject *)type);
3383 /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
3384 if (!dict || !dict->argtypes) {
3385 PyErr_SetString(PyExc_TypeError,
3386 "cannot construct instance of this class:"
3387 " no argtypes");
3388 return NULL;
3389 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003391 thunk = _ctypes_alloc_callback(callable,
3392 dict->argtypes,
3393 dict->restype,
3394 dict->flags);
3395 if (!thunk)
3396 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003398 self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3399 if (self == NULL) {
3400 Py_DECREF(thunk);
3401 return NULL;
3402 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003404 Py_INCREF(callable);
3405 self->callable = callable;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003407 self->thunk = thunk;
Thomas Heller864cc672010-08-08 17:58:53 +00003408 *(void **)self->b_ptr = (void *)thunk->pcl_exec;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003409
3410 Py_INCREF((PyObject *)thunk); /* for KeepRef */
3411 if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3412 Py_DECREF((PyObject *)self);
3413 return NULL;
3414 }
3415 return (PyObject *)self;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003416}
3417
3418
3419/*
3420 _byref consumes a refcount to its argument
3421*/
3422static PyObject *
3423_byref(PyObject *obj)
3424{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003425 PyCArgObject *parg;
3426 if (!CDataObject_Check(obj)) {
3427 PyErr_SetString(PyExc_TypeError,
3428 "expected CData instance");
3429 return NULL;
3430 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003432 parg = PyCArgObject_new();
3433 if (parg == NULL) {
3434 Py_DECREF(obj);
3435 return NULL;
3436 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003438 parg->tag = 'P';
3439 parg->pffi_type = &ffi_type_pointer;
3440 parg->obj = obj;
3441 parg->value.p = ((CDataObject *)obj)->b_ptr;
3442 return (PyObject *)parg;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003443}
3444
3445static PyObject *
Guido van Rossum97f9d4f2007-10-24 18:41:19 +00003446_get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003448 PyObject *v;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003450 if (*pindex < PyTuple_GET_SIZE(inargs)) {
3451 v = PyTuple_GET_ITEM(inargs, *pindex);
3452 ++*pindex;
3453 Py_INCREF(v);
3454 return v;
3455 }
Christian Heimes6ca8a052013-07-26 23:04:29 +02003456 if (kwds && name && (v = PyDict_GetItem(kwds, name))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003457 ++*pindex;
3458 Py_INCREF(v);
3459 return v;
3460 }
3461 if (defval) {
3462 Py_INCREF(defval);
3463 return defval;
3464 }
3465 /* we can't currently emit a better error message */
3466 if (name)
3467 PyErr_Format(PyExc_TypeError,
3468 "required argument '%S' missing", name);
3469 else
3470 PyErr_Format(PyExc_TypeError,
3471 "not enough arguments");
3472 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003473}
3474
3475/*
3476 This function implements higher level functionality plus the ability to call
3477 functions with keyword arguments by looking at parameter flags. parameter
3478 flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer
3479 specifying the direction of the data transfer for this parameter - 'in',
3480 'out' or 'inout' (zero means the same as 'in'). The second entry is the
3481 parameter name, and the third is the default value if the parameter is
3482 missing in the function call.
3483
3484 This function builds and returns a new tuple 'callargs' which contains the
3485 parameters to use in the call. Items on this tuple are copied from the
3486 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
3487 'argtypes' tuple for 'out' parameters. It also calculates numretvals which
3488 is the number of return values for the function, outmask/inoutmask are
3489 bitmasks containing indexes into the callargs tuple specifying which
3490 parameters have to be returned. _build_result builds the return value of the
3491 function.
3492*/
3493static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003494_build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003495 PyObject *inargs, PyObject *kwds,
3496 int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003498 PyObject *paramflags = self->paramflags;
3499 PyObject *callargs;
3500 StgDictObject *dict;
3501 Py_ssize_t i, len;
3502 int inargs_index = 0;
3503 /* It's a little bit difficult to determine how many arguments the
3504 function call requires/accepts. For simplicity, we count the consumed
3505 args and compare this to the number of supplied args. */
3506 Py_ssize_t actual_args;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003507
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003508 *poutmask = 0;
3509 *pinoutmask = 0;
3510 *pnumretvals = 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003511
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003512 /* Trivial cases, where we either return inargs itself, or a slice of it. */
3513 if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
Thomas Hellerd4c93202006-03-08 19:35:11 +00003514#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003515 if (self->index)
3516 return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
Thomas Hellerd4c93202006-03-08 19:35:11 +00003517#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003518 Py_INCREF(inargs);
3519 return inargs;
3520 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003522 len = PyTuple_GET_SIZE(argtypes);
3523 callargs = PyTuple_New(len); /* the argument tuple we build */
3524 if (callargs == NULL)
3525 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003526
3527#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003528 /* For a COM method, skip the first arg */
3529 if (self->index) {
3530 inargs_index = 1;
3531 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003532#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003533 for (i = 0; i < len; ++i) {
3534 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3535 PyObject *ob;
3536 int flag;
3537 PyObject *name = NULL;
3538 PyObject *defval = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003540 /* This way seems to be ~2 us faster than the PyArg_ParseTuple
3541 calls below. */
3542 /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
3543 Py_ssize_t tsize = PyTuple_GET_SIZE(item);
3544 flag = PyLong_AS_LONG(PyTuple_GET_ITEM(item, 0));
3545 name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
3546 defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003548 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3549 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3550 /* ['in', 'lcid'] parameter. Always taken from defval,
3551 if given, else the integer 0. */
3552 if (defval == NULL) {
3553 defval = PyLong_FromLong(0);
3554 if (defval == NULL)
3555 goto error;
3556 } else
3557 Py_INCREF(defval);
3558 PyTuple_SET_ITEM(callargs, i, defval);
3559 break;
3560 case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
3561 *pinoutmask |= (1 << i); /* mark as inout arg */
3562 (*pnumretvals)++;
3563 /* fall through to PARAMFLAG_FIN... */
3564 case 0:
3565 case PARAMFLAG_FIN:
3566 /* 'in' parameter. Copy it from inargs. */
3567 ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
3568 if (ob == NULL)
3569 goto error;
3570 PyTuple_SET_ITEM(callargs, i, ob);
3571 break;
3572 case PARAMFLAG_FOUT:
3573 /* XXX Refactor this code into a separate function. */
3574 /* 'out' parameter.
3575 argtypes[i] must be a POINTER to a c type.
Thomas Hellerd4c93202006-03-08 19:35:11 +00003576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003577 Cannot by supplied in inargs, but a defval will be used
3578 if available. XXX Should we support getting it from kwds?
3579 */
3580 if (defval) {
3581 /* XXX Using mutable objects as defval will
3582 make the function non-threadsafe, unless we
3583 copy the object in each invocation */
3584 Py_INCREF(defval);
3585 PyTuple_SET_ITEM(callargs, i, defval);
3586 *poutmask |= (1 << i); /* mark as out arg */
3587 (*pnumretvals)++;
3588 break;
3589 }
3590 ob = PyTuple_GET_ITEM(argtypes, i);
3591 dict = PyType_stgdict(ob);
3592 if (dict == NULL) {
3593 /* Cannot happen: _validate_paramflags()
3594 would not accept such an object */
3595 PyErr_Format(PyExc_RuntimeError,
3596 "NULL stgdict unexpected");
3597 goto error;
3598 }
3599 if (PyUnicode_Check(dict->proto)) {
3600 PyErr_Format(
3601 PyExc_TypeError,
3602 "%s 'out' parameter must be passed as default value",
3603 ((PyTypeObject *)ob)->tp_name);
3604 goto error;
3605 }
3606 if (PyCArrayTypeObject_Check(ob))
3607 ob = PyObject_CallObject(ob, NULL);
3608 else
3609 /* Create an instance of the pointed-to type */
3610 ob = PyObject_CallObject(dict->proto, NULL);
3611 /*
3612 XXX Is the following correct any longer?
3613 We must not pass a byref() to the array then but
3614 the array instance itself. Then, we cannot retrive
3615 the result from the PyCArgObject.
3616 */
3617 if (ob == NULL)
3618 goto error;
3619 /* The .from_param call that will ocurr later will pass this
3620 as a byref parameter. */
3621 PyTuple_SET_ITEM(callargs, i, ob);
3622 *poutmask |= (1 << i); /* mark as out arg */
3623 (*pnumretvals)++;
3624 break;
3625 default:
3626 PyErr_Format(PyExc_ValueError,
3627 "paramflag %d not yet implemented", flag);
3628 goto error;
3629 break;
3630 }
3631 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003633 /* We have counted the arguments we have consumed in 'inargs_index'. This
3634 must be the same as len(inargs) + len(kwds), otherwise we have
3635 either too much or not enough arguments. */
Thomas Hellerd4c93202006-03-08 19:35:11 +00003636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003637 actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
3638 if (actual_args != inargs_index) {
3639 /* When we have default values or named parameters, this error
3640 message is misleading. See unittests/test_paramflags.py
3641 */
3642 PyErr_Format(PyExc_TypeError,
3643 "call takes exactly %d arguments (%zd given)",
3644 inargs_index, actual_args);
3645 goto error;
3646 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003648 /* outmask is a bitmask containing indexes into callargs. Items at
3649 these indexes contain values to return.
3650 */
3651 return callargs;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003652 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003653 Py_DECREF(callargs);
3654 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003655}
3656
3657/* See also:
3658 http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
3659*/
3660/*
3661 Build return value of a function.
3662
3663 Consumes the refcount on result and callargs.
3664*/
3665static PyObject *
3666_build_result(PyObject *result, PyObject *callargs,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003667 int outmask, int inoutmask, unsigned int numretvals)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003668{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003669 unsigned int i, index;
3670 int bit;
3671 PyObject *tup = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003672
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003673 if (callargs == NULL)
3674 return result;
3675 if (result == NULL || numretvals == 0) {
3676 Py_DECREF(callargs);
3677 return result;
3678 }
3679 Py_DECREF(result);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003681 /* tup will not be allocated if numretvals == 1 */
3682 /* allocate tuple to hold the result */
3683 if (numretvals > 1) {
3684 tup = PyTuple_New(numretvals);
3685 if (tup == NULL) {
3686 Py_DECREF(callargs);
3687 return NULL;
3688 }
3689 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003690
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003691 index = 0;
3692 for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
3693 PyObject *v;
3694 if (bit & inoutmask) {
3695 v = PyTuple_GET_ITEM(callargs, i);
3696 Py_INCREF(v);
3697 if (numretvals == 1) {
3698 Py_DECREF(callargs);
3699 return v;
3700 }
3701 PyTuple_SET_ITEM(tup, index, v);
3702 index++;
3703 } else if (bit & outmask) {
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003704 _Py_IDENTIFIER(__ctypes_from_outparam__);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003705
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003706 v = PyTuple_GET_ITEM(callargs, i);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02003707 v = _PyObject_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003708 if (v == NULL || numretvals == 1) {
3709 Py_DECREF(callargs);
3710 return v;
3711 }
3712 PyTuple_SET_ITEM(tup, index, v);
3713 index++;
3714 }
3715 if (index == numretvals)
3716 break;
3717 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003718
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003719 Py_DECREF(callargs);
3720 return tup;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003721}
3722
3723static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003724PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003725{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003726 PyObject *restype;
3727 PyObject *converters;
3728 PyObject *checker;
3729 PyObject *argtypes;
3730 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3731 PyObject *result;
3732 PyObject *callargs;
3733 PyObject *errcheck;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003734#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003735 IUnknown *piunk = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003736#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003737 void *pProc = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003739 int inoutmask;
3740 int outmask;
3741 unsigned int numretvals;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003743 assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3744 restype = self->restype ? self->restype : dict->restype;
3745 converters = self->converters ? self->converters : dict->converters;
3746 checker = self->checker ? self->checker : dict->checker;
3747 argtypes = self->argtypes ? self->argtypes : dict->argtypes;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003748/* later, we probably want to have an errcheck field in stgdict */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003749 errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003750
3751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003752 pProc = *(void **)self->b_ptr;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003753#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003754 if (self->index) {
3755 /* It's a COM method */
3756 CDataObject *this;
3757 this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
3758 if (!this) {
3759 PyErr_SetString(PyExc_ValueError,
3760 "native com method call without 'this' parameter");
3761 return NULL;
3762 }
3763 if (!CDataObject_Check(this)) {
3764 PyErr_SetString(PyExc_TypeError,
3765 "Expected a COM this pointer as first argument");
3766 return NULL;
3767 }
3768 /* there should be more checks? No, in Python */
3769 /* First arg is an pointer to an interface instance */
3770 if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
3771 PyErr_SetString(PyExc_ValueError,
3772 "NULL COM pointer access");
3773 return NULL;
3774 }
3775 piunk = *(IUnknown **)this->b_ptr;
3776 if (NULL == piunk->lpVtbl) {
3777 PyErr_SetString(PyExc_ValueError,
3778 "COM method call without VTable");
3779 return NULL;
3780 }
3781 pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
3782 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003783#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003784 callargs = _build_callargs(self, argtypes,
3785 inargs, kwds,
3786 &outmask, &inoutmask, &numretvals);
3787 if (callargs == NULL)
3788 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00003789
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003790 if (converters) {
3791 int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
3792 Py_ssize_t, int);
3793 int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
3794 Py_ssize_t, int);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003796 if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
3797 /* For cdecl functions, we allow more actual arguments
3798 than the length of the argtypes tuple.
3799 */
3800 if (required > actual) {
3801 Py_DECREF(callargs);
3802 PyErr_Format(PyExc_TypeError,
3803 "this function takes at least %d argument%s (%d given)",
3804 required,
3805 required == 1 ? "" : "s",
3806 actual);
3807 return NULL;
3808 }
3809 } else if (required != actual) {
3810 Py_DECREF(callargs);
3811 PyErr_Format(PyExc_TypeError,
3812 "this function takes %d argument%s (%d given)",
3813 required,
3814 required == 1 ? "" : "s",
3815 actual);
3816 return NULL;
3817 }
3818 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003820 result = _ctypes_callproc(pProc,
3821 callargs,
Thomas Hellerd4c93202006-03-08 19:35:11 +00003822#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003823 piunk,
3824 self->iid,
Thomas Hellerd4c93202006-03-08 19:35:11 +00003825#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003826 dict->flags,
3827 converters,
3828 restype,
3829 checker);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003830/* The 'errcheck' protocol */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003831 if (result != NULL && errcheck) {
3832 PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
3833 result,
3834 self,
3835 callargs,
3836 NULL);
3837 /* If the errcheck funtion failed, return NULL.
3838 If the errcheck function returned callargs unchanged,
3839 continue normal processing.
3840 If the errcheck function returned something else,
3841 use that as result.
3842 */
3843 if (v == NULL || v != callargs) {
3844 Py_DECREF(result);
3845 Py_DECREF(callargs);
3846 return v;
3847 }
3848 Py_DECREF(v);
3849 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00003850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003851 return _build_result(result, callargs,
3852 outmask, inoutmask, numretvals);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003853}
3854
3855static int
Thomas Heller34596a92009-04-24 20:50:00 +00003856PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003858 Py_VISIT(self->callable);
3859 Py_VISIT(self->restype);
3860 Py_VISIT(self->checker);
3861 Py_VISIT(self->errcheck);
3862 Py_VISIT(self->argtypes);
3863 Py_VISIT(self->converters);
3864 Py_VISIT(self->paramflags);
3865 Py_VISIT(self->thunk);
3866 return PyCData_traverse((CDataObject *)self, visit, arg);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003867}
3868
3869static int
Thomas Heller34596a92009-04-24 20:50:00 +00003870PyCFuncPtr_clear(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003871{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003872 Py_CLEAR(self->callable);
3873 Py_CLEAR(self->restype);
3874 Py_CLEAR(self->checker);
3875 Py_CLEAR(self->errcheck);
3876 Py_CLEAR(self->argtypes);
3877 Py_CLEAR(self->converters);
3878 Py_CLEAR(self->paramflags);
3879 Py_CLEAR(self->thunk);
3880 return PyCData_clear((CDataObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003881}
3882
3883static void
Thomas Heller34596a92009-04-24 20:50:00 +00003884PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003885{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003886 PyCFuncPtr_clear(self);
3887 Py_TYPE(self)->tp_free((PyObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003888}
3889
3890static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00003891PyCFuncPtr_repr(PyCFuncPtrObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00003892{
3893#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003894 if (self->index)
3895 return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
3896 self->index - 0x1000,
3897 Py_TYPE(self)->tp_name,
3898 self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003899#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003900 return PyUnicode_FromFormat("<%s object at %p>",
3901 Py_TYPE(self)->tp_name,
3902 self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00003903}
3904
Thomas Heller7dca3eb2008-05-29 19:54:39 +00003905static int
Thomas Heller34596a92009-04-24 20:50:00 +00003906PyCFuncPtr_bool(PyCFuncPtrObject *self)
Thomas Heller7dca3eb2008-05-29 19:54:39 +00003907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003908 return ((*(void **)self->b_ptr != NULL)
Thomas Hellerf5049fc2008-08-19 19:49:49 +00003909#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003910 || (self->index != 0)
Thomas Hellerf5049fc2008-08-19 19:49:49 +00003911#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003912 );
Thomas Heller7dca3eb2008-05-29 19:54:39 +00003913}
3914
Thomas Heller34596a92009-04-24 20:50:00 +00003915static PyNumberMethods PyCFuncPtr_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003916 0, /* nb_add */
3917 0, /* nb_subtract */
3918 0, /* nb_multiply */
3919 0, /* nb_remainder */
3920 0, /* nb_divmod */
3921 0, /* nb_power */
3922 0, /* nb_negative */
3923 0, /* nb_positive */
3924 0, /* nb_absolute */
3925 (inquiry)PyCFuncPtr_bool, /* nb_bool */
Thomas Heller7dca3eb2008-05-29 19:54:39 +00003926};
3927
Thomas Heller34596a92009-04-24 20:50:00 +00003928PyTypeObject PyCFuncPtr_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003929 PyVarObject_HEAD_INIT(NULL, 0)
3930 "_ctypes.PyCFuncPtr",
3931 sizeof(PyCFuncPtrObject), /* tp_basicsize */
3932 0, /* tp_itemsize */
3933 (destructor)PyCFuncPtr_dealloc, /* tp_dealloc */
3934 0, /* tp_print */
3935 0, /* tp_getattr */
3936 0, /* tp_setattr */
3937 0, /* tp_reserved */
3938 (reprfunc)PyCFuncPtr_repr, /* tp_repr */
3939 &PyCFuncPtr_as_number, /* tp_as_number */
3940 0, /* tp_as_sequence */
3941 0, /* tp_as_mapping */
3942 0, /* tp_hash */
3943 (ternaryfunc)PyCFuncPtr_call, /* tp_call */
3944 0, /* tp_str */
3945 0, /* tp_getattro */
3946 0, /* tp_setattro */
3947 &PyCData_as_buffer, /* tp_as_buffer */
3948 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3949 "Function Pointer", /* tp_doc */
3950 (traverseproc)PyCFuncPtr_traverse, /* tp_traverse */
3951 (inquiry)PyCFuncPtr_clear, /* tp_clear */
3952 0, /* tp_richcompare */
3953 0, /* tp_weaklistoffset */
3954 0, /* tp_iter */
3955 0, /* tp_iternext */
3956 0, /* tp_methods */
3957 0, /* tp_members */
3958 PyCFuncPtr_getsets, /* tp_getset */
3959 0, /* tp_base */
3960 0, /* tp_dict */
3961 0, /* tp_descr_get */
3962 0, /* tp_descr_set */
3963 0, /* tp_dictoffset */
3964 0, /* tp_init */
3965 0, /* tp_alloc */
3966 PyCFuncPtr_new, /* tp_new */
3967 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00003968};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003969
Thomas Hellerd4c93202006-03-08 19:35:11 +00003970/*****************************************************************/
3971/*
3972 Struct_Type
3973*/
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003974/*
3975 This function is called to initialize a Structure or Union with positional
3976 arguments. It calls itself recursively for all Structure or Union base
3977 classes, then retrieves the _fields_ member to associate the argument
3978 position with the correct field name.
3979
3980 Returns -1 on error, or the index of next argument on success.
3981 */
Victor Stinner0fcab4a2011-01-04 12:59:15 +00003982static Py_ssize_t
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003983_init_pos_args(PyObject *self, PyTypeObject *type,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003984 PyObject *args, PyObject *kwds,
Victor Stinner0fcab4a2011-01-04 12:59:15 +00003985 Py_ssize_t index)
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003986{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003987 StgDictObject *dict;
3988 PyObject *fields;
Victor Stinner0fcab4a2011-01-04 12:59:15 +00003989 Py_ssize_t i;
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003991 if (PyType_stgdict((PyObject *)type->tp_base)) {
3992 index = _init_pos_args(self, type->tp_base,
3993 args, kwds,
3994 index);
3995 if (index == -1)
3996 return -1;
3997 }
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00003998
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003999 dict = PyType_stgdict((PyObject *)type);
4000 fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
4001 if (fields == NULL)
4002 return index;
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00004003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004004 for (i = 0;
4005 i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
4006 ++i) {
4007 PyObject *pair = PySequence_GetItem(fields, i);
4008 PyObject *name, *val;
4009 int res;
4010 if (!pair)
4011 return -1;
4012 name = PySequence_GetItem(pair, 0);
4013 if (!name) {
4014 Py_DECREF(pair);
4015 return -1;
4016 }
4017 val = PyTuple_GET_ITEM(args, i + index);
4018 if (kwds && PyDict_GetItem(kwds, name)) {
4019 char *field = PyBytes_AsString(name);
4020 if (field == NULL) {
4021 PyErr_Clear();
4022 field = "???";
4023 }
4024 PyErr_Format(PyExc_TypeError,
4025 "duplicate values for field '%s'",
4026 field);
4027 Py_DECREF(pair);
4028 Py_DECREF(name);
4029 return -1;
4030 }
4031
4032 res = PyObject_SetAttr(self, name, val);
4033 Py_DECREF(pair);
4034 Py_DECREF(name);
4035 if (res == -1)
4036 return -1;
4037 }
4038 return index + dict->length;
Thomas Hellerd7cb1b92009-09-18 19:05:13 +00004039}
4040
Thomas Hellerd4c93202006-03-08 19:35:11 +00004041static int
4042Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
4043{
Thomas Hellerd4c93202006-03-08 19:35:11 +00004044/* Optimization possible: Store the attribute names _fields_[x][0]
4045 * in C accessible fields somewhere ?
4046 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004047 if (!PyTuple_Check(args)) {
4048 PyErr_SetString(PyExc_TypeError,
4049 "args not a tuple?");
4050 return -1;
4051 }
4052 if (PyTuple_GET_SIZE(args)) {
4053 int res = _init_pos_args(self, Py_TYPE(self),
4054 args, kwds, 0);
4055 if (res == -1)
4056 return -1;
4057 if (res < PyTuple_GET_SIZE(args)) {
4058 PyErr_SetString(PyExc_TypeError,
4059 "too many initializers");
4060 return -1;
4061 }
4062 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004064 if (kwds) {
4065 PyObject *key, *value;
4066 Py_ssize_t pos = 0;
4067 while(PyDict_Next(kwds, &pos, &key, &value)) {
4068 if (-1 == PyObject_SetAttr(self, key, value))
4069 return -1;
4070 }
4071 }
4072 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004073}
4074
Thomas Hellerd4c93202006-03-08 19:35:11 +00004075static PyTypeObject Struct_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004076 PyVarObject_HEAD_INIT(NULL, 0)
4077 "_ctypes.Structure",
4078 sizeof(CDataObject), /* tp_basicsize */
4079 0, /* tp_itemsize */
4080 0, /* tp_dealloc */
4081 0, /* tp_print */
4082 0, /* tp_getattr */
4083 0, /* tp_setattr */
4084 0, /* tp_reserved */
4085 0, /* tp_repr */
4086 0, /* tp_as_number */
4087 0, /* tp_as_sequence */
4088 0, /* tp_as_mapping */
4089 0, /* tp_hash */
4090 0, /* tp_call */
4091 0, /* tp_str */
4092 0, /* tp_getattro */
4093 0, /* tp_setattro */
4094 &PyCData_as_buffer, /* tp_as_buffer */
4095 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4096 "Structure base class", /* tp_doc */
4097 (traverseproc)PyCData_traverse, /* tp_traverse */
4098 (inquiry)PyCData_clear, /* tp_clear */
4099 0, /* tp_richcompare */
4100 0, /* tp_weaklistoffset */
4101 0, /* tp_iter */
4102 0, /* tp_iternext */
4103 0, /* tp_methods */
4104 0, /* tp_members */
4105 0, /* tp_getset */
4106 0, /* tp_base */
4107 0, /* tp_dict */
4108 0, /* tp_descr_get */
4109 0, /* tp_descr_set */
4110 0, /* tp_dictoffset */
4111 Struct_init, /* tp_init */
4112 0, /* tp_alloc */
4113 GenericPyCData_new, /* tp_new */
4114 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004115};
4116
4117static PyTypeObject Union_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004118 PyVarObject_HEAD_INIT(NULL, 0)
4119 "_ctypes.Union",
4120 sizeof(CDataObject), /* tp_basicsize */
4121 0, /* tp_itemsize */
4122 0, /* tp_dealloc */
4123 0, /* tp_print */
4124 0, /* tp_getattr */
4125 0, /* tp_setattr */
4126 0, /* tp_reserved */
4127 0, /* tp_repr */
4128 0, /* tp_as_number */
4129 0, /* tp_as_sequence */
4130 0, /* tp_as_mapping */
4131 0, /* tp_hash */
4132 0, /* tp_call */
4133 0, /* tp_str */
4134 0, /* tp_getattro */
4135 0, /* tp_setattro */
4136 &PyCData_as_buffer, /* tp_as_buffer */
4137 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4138 "Union base class", /* tp_doc */
4139 (traverseproc)PyCData_traverse, /* tp_traverse */
4140 (inquiry)PyCData_clear, /* tp_clear */
4141 0, /* tp_richcompare */
4142 0, /* tp_weaklistoffset */
4143 0, /* tp_iter */
4144 0, /* tp_iternext */
4145 0, /* tp_methods */
4146 0, /* tp_members */
4147 0, /* tp_getset */
4148 0, /* tp_base */
4149 0, /* tp_dict */
4150 0, /* tp_descr_get */
4151 0, /* tp_descr_set */
4152 0, /* tp_dictoffset */
4153 Struct_init, /* tp_init */
4154 0, /* tp_alloc */
4155 GenericPyCData_new, /* tp_new */
4156 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004157};
4158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004159
Thomas Hellerd4c93202006-03-08 19:35:11 +00004160/******************************************************************/
4161/*
Thomas Heller34596a92009-04-24 20:50:00 +00004162 PyCArray_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00004163*/
4164static int
4165Array_init(CDataObject *self, PyObject *args, PyObject *kw)
4166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004167 Py_ssize_t i;
4168 Py_ssize_t n;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004170 if (!PyTuple_Check(args)) {
4171 PyErr_SetString(PyExc_TypeError,
4172 "args not a tuple?");
4173 return -1;
4174 }
4175 n = PyTuple_GET_SIZE(args);
4176 for (i = 0; i < n; ++i) {
4177 PyObject *v;
4178 v = PyTuple_GET_ITEM(args, i);
4179 if (-1 == PySequence_SetItem((PyObject *)self, i, v))
4180 return -1;
4181 }
4182 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004183}
4184
4185static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004186Array_item(PyObject *_self, Py_ssize_t index)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004187{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004188 CDataObject *self = (CDataObject *)_self;
4189 Py_ssize_t offset, size;
4190 StgDictObject *stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004191
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004193 if (index < 0 || index >= self->b_length) {
4194 PyErr_SetString(PyExc_IndexError,
4195 "invalid index");
4196 return NULL;
4197 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004199 stgdict = PyObject_stgdict((PyObject *)self);
4200 assert(stgdict); /* Cannot be NULL for array instances */
4201 /* Would it be clearer if we got the item size from
4202 stgdict->proto's stgdict?
4203 */
4204 size = stgdict->size / stgdict->length;
4205 offset = index * size;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004207 return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
4208 index, size, self->b_ptr + offset);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004209}
4210
4211static PyObject *
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004212Array_subscript(PyObject *_self, PyObject *item)
4213{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004214 CDataObject *self = (CDataObject *)_self;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004216 if (PyIndex_Check(item)) {
4217 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004219 if (i == -1 && PyErr_Occurred())
4220 return NULL;
4221 if (i < 0)
4222 i += self->b_length;
4223 return Array_item(_self, i);
4224 }
4225 else if PySlice_Check(item) {
4226 StgDictObject *stgdict, *itemdict;
4227 PyObject *proto;
4228 PyObject *np;
4229 Py_ssize_t start, stop, step, slicelen, cur, i;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004230
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00004231 if (PySlice_GetIndicesEx(item,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004232 self->b_length, &start, &stop,
4233 &step, &slicelen) < 0) {
4234 return NULL;
4235 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004237 stgdict = PyObject_stgdict((PyObject *)self);
4238 assert(stgdict); /* Cannot be NULL for array object instances */
4239 proto = stgdict->proto;
4240 itemdict = PyType_stgdict(proto);
4241 assert(itemdict); /* proto is the item type of the array, a
4242 ctypes type, so this cannot be NULL */
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004244 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4245 char *ptr = (char *)self->b_ptr;
4246 char *dest;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004248 if (slicelen <= 0)
4249 return PyBytes_FromStringAndSize("", 0);
4250 if (step == 1) {
4251 return PyBytes_FromStringAndSize(ptr + start,
4252 slicelen);
4253 }
4254 dest = (char *)PyMem_Malloc(slicelen);
4255
4256 if (dest == NULL)
4257 return PyErr_NoMemory();
4258
4259 for (cur = start, i = 0; i < slicelen;
4260 cur += step, i++) {
4261 dest[i] = ptr[cur];
4262 }
4263
4264 np = PyBytes_FromStringAndSize(dest, slicelen);
4265 PyMem_Free(dest);
4266 return np;
4267 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004268#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004269 if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4270 wchar_t *ptr = (wchar_t *)self->b_ptr;
4271 wchar_t *dest;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004273 if (slicelen <= 0)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004274 return PyUnicode_New(0, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004275 if (step == 1) {
4276 return PyUnicode_FromWideChar(ptr + start,
4277 slicelen);
4278 }
4279
4280 dest = (wchar_t *)PyMem_Malloc(
4281 slicelen * sizeof(wchar_t));
4282
4283 for (cur = start, i = 0; i < slicelen;
4284 cur += step, i++) {
4285 dest[i] = ptr[cur];
4286 }
4287
4288 np = PyUnicode_FromWideChar(dest, slicelen);
4289 PyMem_Free(dest);
4290 return np;
4291 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004292#endif
4293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004294 np = PyList_New(slicelen);
4295 if (np == NULL)
4296 return NULL;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004298 for (cur = start, i = 0; i < slicelen;
4299 cur += step, i++) {
4300 PyObject *v = Array_item(_self, cur);
4301 PyList_SET_ITEM(np, i, v);
4302 }
4303 return np;
4304 }
4305 else {
4306 PyErr_SetString(PyExc_TypeError,
4307 "indices must be integers");
4308 return NULL;
4309 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004310
4311}
4312
Thomas Hellerd4c93202006-03-08 19:35:11 +00004313static int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004314Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004315{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004316 CDataObject *self = (CDataObject *)_self;
4317 Py_ssize_t size, offset;
4318 StgDictObject *stgdict;
4319 char *ptr;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004321 if (value == NULL) {
4322 PyErr_SetString(PyExc_TypeError,
4323 "Array does not support item deletion");
4324 return -1;
4325 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004327 stgdict = PyObject_stgdict((PyObject *)self);
4328 assert(stgdict); /* Cannot be NULL for array object instances */
4329 if (index < 0 || index >= stgdict->length) {
4330 PyErr_SetString(PyExc_IndexError,
4331 "invalid index");
4332 return -1;
4333 }
4334 size = stgdict->size / stgdict->length;
4335 offset = index * size;
4336 ptr = self->b_ptr + offset;
4337
4338 return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
4339 index, size, ptr);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004340}
4341
4342static int
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004343Array_ass_subscript(PyObject *_self, PyObject *item, PyObject *value)
4344{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004345 CDataObject *self = (CDataObject *)_self;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004347 if (value == NULL) {
4348 PyErr_SetString(PyExc_TypeError,
4349 "Array does not support item deletion");
4350 return -1;
4351 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004353 if (PyIndex_Check(item)) {
4354 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4355
4356 if (i == -1 && PyErr_Occurred())
4357 return -1;
4358 if (i < 0)
4359 i += self->b_length;
4360 return Array_ass_item(_self, i, value);
4361 }
4362 else if (PySlice_Check(item)) {
4363 Py_ssize_t start, stop, step, slicelen, otherlen, i, cur;
4364
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00004365 if (PySlice_GetIndicesEx(item,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004366 self->b_length, &start, &stop,
4367 &step, &slicelen) < 0) {
4368 return -1;
4369 }
4370 if ((step < 0 && start < stop) ||
4371 (step > 0 && start > stop))
4372 stop = start;
4373
4374 otherlen = PySequence_Length(value);
4375 if (otherlen != slicelen) {
4376 PyErr_SetString(PyExc_ValueError,
4377 "Can only assign sequence of same size");
4378 return -1;
4379 }
4380 for (cur = start, i = 0; i < otherlen; cur += step, i++) {
4381 PyObject *item = PySequence_GetItem(value, i);
4382 int result;
4383 if (item == NULL)
4384 return -1;
4385 result = Array_ass_item(_self, cur, item);
4386 Py_DECREF(item);
4387 if (result == -1)
4388 return -1;
4389 }
4390 return 0;
4391 }
4392 else {
4393 PyErr_SetString(PyExc_TypeError,
4394 "indices must be integer");
4395 return -1;
4396 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004397}
4398
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004399static Py_ssize_t
4400Array_length(PyObject *_self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004402 CDataObject *self = (CDataObject *)_self;
4403 return self->b_length;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004404}
4405
4406static PySequenceMethods Array_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004407 Array_length, /* sq_length; */
4408 0, /* sq_concat; */
4409 0, /* sq_repeat; */
4410 Array_item, /* sq_item; */
4411 0, /* sq_slice; */
4412 Array_ass_item, /* sq_ass_item; */
4413 0, /* sq_ass_slice; */
4414 0, /* sq_contains; */
4415
4416 0, /* sq_inplace_concat; */
4417 0, /* sq_inplace_repeat; */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004418};
4419
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004420static PyMappingMethods Array_as_mapping = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004421 Array_length,
4422 Array_subscript,
4423 Array_ass_subscript,
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004424};
4425
Thomas Heller34596a92009-04-24 20:50:00 +00004426PyTypeObject PyCArray_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004427 PyVarObject_HEAD_INIT(NULL, 0)
4428 "_ctypes.Array",
4429 sizeof(CDataObject), /* tp_basicsize */
4430 0, /* tp_itemsize */
4431 0, /* tp_dealloc */
4432 0, /* tp_print */
4433 0, /* tp_getattr */
4434 0, /* tp_setattr */
4435 0, /* tp_reserved */
4436 0, /* tp_repr */
4437 0, /* tp_as_number */
4438 &Array_as_sequence, /* tp_as_sequence */
4439 &Array_as_mapping, /* tp_as_mapping */
4440 0, /* tp_hash */
4441 0, /* tp_call */
4442 0, /* tp_str */
4443 0, /* tp_getattro */
4444 0, /* tp_setattro */
4445 &PyCData_as_buffer, /* tp_as_buffer */
4446 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4447 "XXX to be provided", /* tp_doc */
4448 (traverseproc)PyCData_traverse, /* tp_traverse */
4449 (inquiry)PyCData_clear, /* tp_clear */
4450 0, /* tp_richcompare */
4451 0, /* tp_weaklistoffset */
4452 0, /* tp_iter */
4453 0, /* tp_iternext */
4454 0, /* tp_methods */
4455 0, /* tp_members */
4456 0, /* tp_getset */
4457 0, /* tp_base */
4458 0, /* tp_dict */
4459 0, /* tp_descr_get */
4460 0, /* tp_descr_set */
4461 0, /* tp_dictoffset */
4462 (initproc)Array_init, /* tp_init */
4463 0, /* tp_alloc */
4464 GenericPyCData_new, /* tp_new */
4465 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004466};
4467
4468PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +00004469PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004471 static PyObject *cache;
4472 PyObject *key;
4473 PyObject *result;
4474 char name[256];
4475 PyObject *len;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004477 if (cache == NULL) {
4478 cache = PyDict_New();
4479 if (cache == NULL)
4480 return NULL;
4481 }
4482 len = PyLong_FromSsize_t(length);
4483 if (len == NULL)
4484 return NULL;
4485 key = PyTuple_Pack(2, itemtype, len);
4486 Py_DECREF(len);
4487 if (!key)
4488 return NULL;
4489 result = PyDict_GetItemProxy(cache, key);
4490 if (result) {
4491 Py_INCREF(result);
4492 Py_DECREF(key);
4493 return result;
4494 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004496 if (!PyType_Check(itemtype)) {
4497 PyErr_SetString(PyExc_TypeError,
4498 "Expected a type object");
Meador Ingeb86ecf42011-09-27 20:45:30 -05004499 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004500 return NULL;
4501 }
Thomas Hellerfe8f8622006-03-14 19:53:09 +00004502#ifdef MS_WIN64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004503 sprintf(name, "%.200s_Array_%Id",
4504 ((PyTypeObject *)itemtype)->tp_name, length);
Thomas Hellerfe8f8622006-03-14 19:53:09 +00004505#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004506 sprintf(name, "%.200s_Array_%ld",
4507 ((PyTypeObject *)itemtype)->tp_name, (long)length);
Thomas Hellerfe8f8622006-03-14 19:53:09 +00004508#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +00004509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004510 result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type,
Victor Stinner7eeb5b52010-06-07 19:57:46 +00004511 "s(O){s:n,s:O}",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004512 name,
4513 &PyCArray_Type,
4514 "_length_",
4515 length,
4516 "_type_",
4517 itemtype
4518 );
4519 if (result == NULL) {
4520 Py_DECREF(key);
4521 return NULL;
4522 }
4523 if (-1 == PyDict_SetItemProxy(cache, key, result)) {
4524 Py_DECREF(key);
4525 Py_DECREF(result);
4526 return NULL;
4527 }
4528 Py_DECREF(key);
4529 return result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004530}
4531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004532
Thomas Hellerd4c93202006-03-08 19:35:11 +00004533/******************************************************************/
4534/*
4535 Simple_Type
4536*/
4537
4538static int
4539Simple_set_value(CDataObject *self, PyObject *value)
4540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004541 PyObject *result;
4542 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004544 if (value == NULL) {
4545 PyErr_SetString(PyExc_TypeError,
4546 "can't delete attribute");
4547 return -1;
4548 }
4549 assert(dict); /* Cannot be NULL for CDataObject instances */
4550 assert(dict->setfunc);
4551 result = dict->setfunc(self->b_ptr, value, dict->size);
4552 if (!result)
4553 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004555 /* consumes the refcount the setfunc returns */
4556 return KeepRef(self, 0, result);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004557}
4558
4559static int
4560Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
4561{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004562 PyObject *value = NULL;
4563 if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
4564 return -1;
4565 if (value)
4566 return Simple_set_value(self, value);
4567 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004568}
4569
4570static PyObject *
4571Simple_get_value(CDataObject *self)
4572{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004573 StgDictObject *dict;
4574 dict = PyObject_stgdict((PyObject *)self);
4575 assert(dict); /* Cannot be NULL for CDataObject instances */
4576 assert(dict->getfunc);
4577 return dict->getfunc(self->b_ptr, self->b_size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004578}
4579
Thomas Hellerd4c93202006-03-08 19:35:11 +00004580static PyGetSetDef Simple_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004581 { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4582 "current value", NULL },
4583 { NULL, NULL }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004584};
4585
4586static PyObject *
4587Simple_from_outparm(PyObject *self, PyObject *args)
4588{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004589 if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) {
4590 Py_INCREF(self);
4591 return self;
4592 }
4593 /* call stgdict->getfunc */
4594 return Simple_get_value((CDataObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004595}
4596
4597static PyMethodDef Simple_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004598 { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
4599 { NULL, NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +00004600};
4601
Jack Diederich4dafcc42006-11-28 19:15:13 +00004602static int Simple_bool(CDataObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004603{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004604 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 +00004605}
4606
4607static PyNumberMethods Simple_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004608 0, /* nb_add */
4609 0, /* nb_subtract */
4610 0, /* nb_multiply */
4611 0, /* nb_remainder */
4612 0, /* nb_divmod */
4613 0, /* nb_power */
4614 0, /* nb_negative */
4615 0, /* nb_positive */
4616 0, /* nb_absolute */
4617 (inquiry)Simple_bool, /* nb_bool */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004618};
4619
Thomas Hellerd4c93202006-03-08 19:35:11 +00004620/* "%s(%s)" % (self.__class__.__name__, self.value) */
4621static PyObject *
4622Simple_repr(CDataObject *self)
4623{
Amaury Forgeot d'Arc864741b2011-11-06 15:10:48 +01004624 PyObject *val, *result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004625
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004626 if (Py_TYPE(self)->tp_base != &Simple_Type) {
4627 return PyUnicode_FromFormat("<%s object at %p>",
4628 Py_TYPE(self)->tp_name, self);
4629 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004631 val = Simple_get_value(self);
4632 if (val == NULL)
4633 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004634
Amaury Forgeot d'Arc864741b2011-11-06 15:10:48 +01004635 result = PyUnicode_FromFormat("%s(%R)",
4636 Py_TYPE(self)->tp_name, val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004637 Py_DECREF(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004638 return result;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004639}
4640
4641static PyTypeObject Simple_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004642 PyVarObject_HEAD_INIT(NULL, 0)
4643 "_ctypes._SimpleCData",
4644 sizeof(CDataObject), /* tp_basicsize */
4645 0, /* tp_itemsize */
4646 0, /* tp_dealloc */
4647 0, /* tp_print */
4648 0, /* tp_getattr */
4649 0, /* tp_setattr */
4650 0, /* tp_reserved */
4651 (reprfunc)&Simple_repr, /* tp_repr */
4652 &Simple_as_number, /* tp_as_number */
4653 0, /* tp_as_sequence */
4654 0, /* tp_as_mapping */
4655 0, /* tp_hash */
4656 0, /* tp_call */
4657 0, /* tp_str */
4658 0, /* tp_getattro */
4659 0, /* tp_setattro */
4660 &PyCData_as_buffer, /* tp_as_buffer */
4661 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4662 "XXX to be provided", /* tp_doc */
4663 (traverseproc)PyCData_traverse, /* tp_traverse */
4664 (inquiry)PyCData_clear, /* tp_clear */
4665 0, /* tp_richcompare */
4666 0, /* tp_weaklistoffset */
4667 0, /* tp_iter */
4668 0, /* tp_iternext */
4669 Simple_methods, /* tp_methods */
4670 0, /* tp_members */
4671 Simple_getsets, /* tp_getset */
4672 0, /* tp_base */
4673 0, /* tp_dict */
4674 0, /* tp_descr_get */
4675 0, /* tp_descr_set */
4676 0, /* tp_dictoffset */
4677 (initproc)Simple_init, /* tp_init */
4678 0, /* tp_alloc */
4679 GenericPyCData_new, /* tp_new */
4680 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004681};
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004682
Thomas Hellerd4c93202006-03-08 19:35:11 +00004683/******************************************************************/
4684/*
Thomas Heller34596a92009-04-24 20:50:00 +00004685 PyCPointer_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +00004686*/
4687static PyObject *
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004688Pointer_item(PyObject *_self, Py_ssize_t index)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004689{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004690 CDataObject *self = (CDataObject *)_self;
4691 Py_ssize_t size;
4692 Py_ssize_t offset;
4693 StgDictObject *stgdict, *itemdict;
4694 PyObject *proto;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004695
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004696 if (*(void **)self->b_ptr == NULL) {
4697 PyErr_SetString(PyExc_ValueError,
4698 "NULL pointer access");
4699 return NULL;
4700 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004702 stgdict = PyObject_stgdict((PyObject *)self);
4703 assert(stgdict); /* Cannot be NULL for pointer object instances */
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00004704
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004705 proto = stgdict->proto;
4706 assert(proto);
4707 itemdict = PyType_stgdict(proto);
4708 assert(itemdict); /* proto is the item type of the pointer, a ctypes
4709 type, so this cannot be NULL */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004711 size = itemdict->size;
4712 offset = index * itemdict->size;
4713
4714 return PyCData_get(proto, stgdict->getfunc, (PyObject *)self,
4715 index, size, (*(char **)self->b_ptr) + offset);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004716}
4717
4718static int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004719Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
Thomas Hellerd4c93202006-03-08 19:35:11 +00004720{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004721 CDataObject *self = (CDataObject *)_self;
4722 Py_ssize_t size;
4723 Py_ssize_t offset;
4724 StgDictObject *stgdict, *itemdict;
4725 PyObject *proto;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004726
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004727 if (value == NULL) {
4728 PyErr_SetString(PyExc_TypeError,
4729 "Pointer does not support item deletion");
4730 return -1;
4731 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004732
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004733 if (*(void **)self->b_ptr == NULL) {
4734 PyErr_SetString(PyExc_ValueError,
4735 "NULL pointer access");
4736 return -1;
4737 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004739 stgdict = PyObject_stgdict((PyObject *)self);
4740 assert(stgdict); /* Cannot be NULL fr pointer instances */
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00004741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004742 proto = stgdict->proto;
4743 assert(proto);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00004744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004745 itemdict = PyType_stgdict(proto);
4746 assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
4747 is always a ctypes type */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004748
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004749 size = itemdict->size;
4750 offset = index * itemdict->size;
4751
4752 return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value,
4753 index, size, (*(char **)self->b_ptr) + offset);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004754}
4755
4756static PyObject *
4757Pointer_get_contents(CDataObject *self, void *closure)
4758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004759 StgDictObject *stgdict;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004761 if (*(void **)self->b_ptr == NULL) {
4762 PyErr_SetString(PyExc_ValueError,
4763 "NULL pointer access");
4764 return NULL;
4765 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004767 stgdict = PyObject_stgdict((PyObject *)self);
4768 assert(stgdict); /* Cannot be NULL fr pointer instances */
4769 return PyCData_FromBaseObj(stgdict->proto,
4770 (PyObject *)self, 0,
4771 *(void **)self->b_ptr);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004772}
4773
4774static int
4775Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
4776{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004777 StgDictObject *stgdict;
4778 CDataObject *dst;
4779 PyObject *keep;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004780
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004781 if (value == NULL) {
4782 PyErr_SetString(PyExc_TypeError,
4783 "Pointer does not support item deletion");
4784 return -1;
4785 }
4786 stgdict = PyObject_stgdict((PyObject *)self);
4787 assert(stgdict); /* Cannot be NULL fr pointer instances */
4788 assert(stgdict->proto);
Benjamin Peterson39530f82011-03-26 18:04:09 -05004789 if (!CDataObject_Check(value)) {
4790 int res = PyObject_IsInstance(value, stgdict->proto);
4791 if (res == -1)
4792 return -1;
4793 if (!res) {
4794 PyErr_Format(PyExc_TypeError,
4795 "expected %s instead of %s",
4796 ((PyTypeObject *)(stgdict->proto))->tp_name,
4797 Py_TYPE(value)->tp_name);
4798 return -1;
4799 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004800 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004802 dst = (CDataObject *)value;
4803 *(void **)self->b_ptr = dst->b_ptr;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004805 /*
4806 A Pointer instance must keep a the value it points to alive. So, a
4807 pointer instance has b_length set to 2 instead of 1, and we set
4808 'value' itself as the second item of the b_objects list, additionally.
4809 */
4810 Py_INCREF(value);
4811 if (-1 == KeepRef(self, 1, value))
4812 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004814 keep = GetKeepedObjects(dst);
4815 Py_INCREF(keep);
4816 return KeepRef(self, 0, keep);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004817}
4818
Thomas Hellerd4c93202006-03-08 19:35:11 +00004819static PyGetSetDef Pointer_getsets[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004820 { "contents", (getter)Pointer_get_contents,
4821 (setter)Pointer_set_contents,
4822 "the object this pointer points to (read-write)", NULL },
4823 { NULL, NULL }
Thomas Hellerd4c93202006-03-08 19:35:11 +00004824};
4825
4826static int
4827Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
4828{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004829 PyObject *value = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00004830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004831 if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
4832 return -1;
4833 if (value == NULL)
4834 return 0;
4835 return Pointer_set_contents(self, value, NULL);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004836}
4837
4838static PyObject *
4839Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4840{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004841 StgDictObject *dict = PyType_stgdict((PyObject *)type);
4842 if (!dict || !dict->proto) {
4843 PyErr_SetString(PyExc_TypeError,
4844 "Cannot create instance: has no _type_");
4845 return NULL;
4846 }
4847 return GenericPyCData_new(type, args, kw);
Thomas Hellerd4c93202006-03-08 19:35:11 +00004848}
4849
4850static PyObject *
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004851Pointer_subscript(PyObject *_self, PyObject *item)
4852{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004853 CDataObject *self = (CDataObject *)_self;
4854 if (PyIndex_Check(item)) {
4855 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4856 if (i == -1 && PyErr_Occurred())
4857 return NULL;
4858 return Pointer_item(_self, i);
4859 }
4860 else if (PySlice_Check(item)) {
4861 PySliceObject *slice = (PySliceObject *)item;
4862 Py_ssize_t start, stop, step;
4863 PyObject *np;
4864 StgDictObject *stgdict, *itemdict;
4865 PyObject *proto;
4866 Py_ssize_t i, len, cur;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004868 /* Since pointers have no length, and we want to apply
4869 different semantics to negative indices than normal
4870 slicing, we have to dissect the slice object ourselves.*/
4871 if (slice->step == Py_None) {
4872 step = 1;
4873 }
4874 else {
4875 step = PyNumber_AsSsize_t(slice->step,
4876 PyExc_ValueError);
4877 if (step == -1 && PyErr_Occurred())
4878 return NULL;
4879 if (step == 0) {
4880 PyErr_SetString(PyExc_ValueError,
4881 "slice step cannot be zero");
4882 return NULL;
4883 }
4884 }
4885 if (slice->start == Py_None) {
4886 if (step < 0) {
4887 PyErr_SetString(PyExc_ValueError,
4888 "slice start is required "
4889 "for step < 0");
4890 return NULL;
4891 }
4892 start = 0;
4893 }
4894 else {
4895 start = PyNumber_AsSsize_t(slice->start,
4896 PyExc_ValueError);
4897 if (start == -1 && PyErr_Occurred())
4898 return NULL;
4899 }
4900 if (slice->stop == Py_None) {
4901 PyErr_SetString(PyExc_ValueError,
4902 "slice stop is required");
4903 return NULL;
4904 }
4905 stop = PyNumber_AsSsize_t(slice->stop,
4906 PyExc_ValueError);
4907 if (stop == -1 && PyErr_Occurred())
4908 return NULL;
4909 if ((step > 0 && start > stop) ||
4910 (step < 0 && start < stop))
4911 len = 0;
4912 else if (step > 0)
4913 len = (stop - start - 1) / step + 1;
4914 else
4915 len = (stop - start + 1) / step + 1;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004917 stgdict = PyObject_stgdict((PyObject *)self);
4918 assert(stgdict); /* Cannot be NULL for pointer instances */
4919 proto = stgdict->proto;
4920 assert(proto);
4921 itemdict = PyType_stgdict(proto);
4922 assert(itemdict);
4923 if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4924 char *ptr = *(char **)self->b_ptr;
4925 char *dest;
4926
4927 if (len <= 0)
4928 return PyBytes_FromStringAndSize("", 0);
4929 if (step == 1) {
4930 return PyBytes_FromStringAndSize(ptr + start,
4931 len);
4932 }
4933 dest = (char *)PyMem_Malloc(len);
4934 if (dest == NULL)
4935 return PyErr_NoMemory();
4936 for (cur = start, i = 0; i < len; cur += step, i++) {
4937 dest[i] = ptr[cur];
4938 }
4939 np = PyBytes_FromStringAndSize(dest, len);
4940 PyMem_Free(dest);
4941 return np;
4942 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004943#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004944 if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4945 wchar_t *ptr = *(wchar_t **)self->b_ptr;
4946 wchar_t *dest;
4947
4948 if (len <= 0)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01004949 return PyUnicode_New(0, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004950 if (step == 1) {
4951 return PyUnicode_FromWideChar(ptr + start,
4952 len);
4953 }
4954 dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t));
4955 if (dest == NULL)
4956 return PyErr_NoMemory();
4957 for (cur = start, i = 0; i < len; cur += step, i++) {
4958 dest[i] = ptr[cur];
4959 }
4960 np = PyUnicode_FromWideChar(dest, len);
4961 PyMem_Free(dest);
4962 return np;
4963 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004964#endif
4965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004966 np = PyList_New(len);
4967 if (np == NULL)
4968 return NULL;
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004970 for (cur = start, i = 0; i < len; cur += step, i++) {
4971 PyObject *v = Pointer_item(_self, cur);
4972 PyList_SET_ITEM(np, i, v);
4973 }
4974 return np;
4975 }
4976 else {
4977 PyErr_SetString(PyExc_TypeError,
4978 "Pointer indices must be integer");
4979 return NULL;
4980 }
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004981}
4982
Thomas Hellerd4c93202006-03-08 19:35:11 +00004983static PySequenceMethods Pointer_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004984 0, /* inquiry sq_length; */
4985 0, /* binaryfunc sq_concat; */
4986 0, /* intargfunc sq_repeat; */
4987 Pointer_item, /* intargfunc sq_item; */
4988 0, /* intintargfunc sq_slice; */
4989 Pointer_ass_item, /* intobjargproc sq_ass_item; */
4990 0, /* intintobjargproc sq_ass_slice; */
4991 0, /* objobjproc sq_contains; */
4992 /* Added in release 2.0 */
4993 0, /* binaryfunc sq_inplace_concat; */
4994 0, /* intargfunc sq_inplace_repeat; */
Thomas Hellerd4c93202006-03-08 19:35:11 +00004995};
4996
Thomas Wouters47b49bf2007-08-30 22:15:33 +00004997static PyMappingMethods Pointer_as_mapping = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00004998 0,
4999 Pointer_subscript,
Thomas Wouters47b49bf2007-08-30 22:15:33 +00005000};
5001
Thomas Hellerf5049fc2008-08-19 19:49:49 +00005002static int
5003Pointer_bool(CDataObject *self)
5004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005005 return (*(void **)self->b_ptr != NULL);
Thomas Hellerf5049fc2008-08-19 19:49:49 +00005006}
5007
5008static PyNumberMethods Pointer_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005009 0, /* nb_add */
5010 0, /* nb_subtract */
5011 0, /* nb_multiply */
5012 0, /* nb_remainder */
5013 0, /* nb_divmod */
5014 0, /* nb_power */
5015 0, /* nb_negative */
5016 0, /* nb_positive */
5017 0, /* nb_absolute */
5018 (inquiry)Pointer_bool, /* nb_bool */
Thomas Hellerf5049fc2008-08-19 19:49:49 +00005019};
5020
Thomas Heller34596a92009-04-24 20:50:00 +00005021PyTypeObject PyCPointer_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005022 PyVarObject_HEAD_INIT(NULL, 0)
5023 "_ctypes._Pointer",
5024 sizeof(CDataObject), /* tp_basicsize */
5025 0, /* tp_itemsize */
5026 0, /* tp_dealloc */
5027 0, /* tp_print */
5028 0, /* tp_getattr */
5029 0, /* tp_setattr */
5030 0, /* tp_reserved */
5031 0, /* tp_repr */
5032 &Pointer_as_number, /* tp_as_number */
5033 &Pointer_as_sequence, /* tp_as_sequence */
5034 &Pointer_as_mapping, /* tp_as_mapping */
5035 0, /* tp_hash */
5036 0, /* tp_call */
5037 0, /* tp_str */
5038 0, /* tp_getattro */
5039 0, /* tp_setattro */
5040 &PyCData_as_buffer, /* tp_as_buffer */
5041 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
5042 "XXX to be provided", /* tp_doc */
5043 (traverseproc)PyCData_traverse, /* tp_traverse */
5044 (inquiry)PyCData_clear, /* tp_clear */
5045 0, /* tp_richcompare */
5046 0, /* tp_weaklistoffset */
5047 0, /* tp_iter */
5048 0, /* tp_iternext */
5049 0, /* tp_methods */
5050 0, /* tp_members */
5051 Pointer_getsets, /* tp_getset */
5052 0, /* tp_base */
5053 0, /* tp_dict */
5054 0, /* tp_descr_get */
5055 0, /* tp_descr_set */
5056 0, /* tp_dictoffset */
5057 (initproc)Pointer_init, /* tp_init */
5058 0, /* tp_alloc */
5059 Pointer_new, /* tp_new */
5060 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005061};
5062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005063
Thomas Hellerd4c93202006-03-08 19:35:11 +00005064/******************************************************************/
5065/*
5066 * Module initialization.
5067 */
5068
Martin v. Löwis1a214512008-06-11 05:26:20 +00005069static const char module_docs[] =
Thomas Hellerd4c93202006-03-08 19:35:11 +00005070"Create and manipulate C compatible data types in Python.";
5071
5072#ifdef MS_WIN32
5073
5074static char comerror_doc[] = "Raised when a COM method call failed.";
5075
Christian Heimesc0ac1062007-11-28 12:33:51 +00005076int
5077comerror_init(PyObject *self, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +00005078{
5079 PyObject *hresult, *text, *details;
Christian Heimesc0ac1062007-11-28 12:33:51 +00005080 PyBaseExceptionObject *bself;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005081 PyObject *a;
5082 int status;
5083
Christian Heimes90aa7642007-12-19 02:45:37 +00005084 if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005085 return -1;
Christian Heimesc0ac1062007-11-28 12:33:51 +00005086
5087 if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005088 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005089
5090 a = PySequence_GetSlice(args, 1, PySequence_Size(args));
5091 if (!a)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005092 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005093 status = PyObject_SetAttrString(self, "args", a);
5094 Py_DECREF(a);
5095 if (status < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005096 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005097
5098 if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005099 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005100
5101 if (PyObject_SetAttrString(self, "text", text) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005102 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005103
5104 if (PyObject_SetAttrString(self, "details", details) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005105 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005106
Christian Heimesc0ac1062007-11-28 12:33:51 +00005107 bself = (PyBaseExceptionObject *)self;
5108 Py_DECREF(bself->args);
5109 bself->args = args;
5110 Py_INCREF(bself->args);
5111
5112 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005113}
5114
Christian Heimesc0ac1062007-11-28 12:33:51 +00005115static PyTypeObject PyComError_Type = {
5116 PyVarObject_HEAD_INIT(NULL, 0)
5117 "_ctypes.COMError", /* tp_name */
5118 sizeof(PyBaseExceptionObject), /* tp_basicsize */
5119 0, /* tp_itemsize */
5120 0, /* tp_dealloc */
5121 0, /* tp_print */
5122 0, /* tp_getattr */
5123 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00005124 0, /* tp_reserved */
Christian Heimesc0ac1062007-11-28 12:33:51 +00005125 0, /* tp_repr */
5126 0, /* tp_as_number */
5127 0, /* tp_as_sequence */
5128 0, /* tp_as_mapping */
5129 0, /* tp_hash */
5130 0, /* tp_call */
5131 0, /* tp_str */
5132 0, /* tp_getattro */
5133 0, /* tp_setattro */
5134 0, /* tp_as_buffer */
Thomas Heller60e5f5e2008-11-26 18:40:58 +00005135 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Christian Heimesc0ac1062007-11-28 12:33:51 +00005136 PyDoc_STR(comerror_doc), /* tp_doc */
5137 0, /* tp_traverse */
5138 0, /* tp_clear */
5139 0, /* tp_richcompare */
5140 0, /* tp_weaklistoffset */
5141 0, /* tp_iter */
5142 0, /* tp_iternext */
5143 0, /* tp_methods */
5144 0, /* tp_members */
5145 0, /* tp_getset */
5146 0, /* tp_base */
5147 0, /* tp_dict */
5148 0, /* tp_descr_get */
5149 0, /* tp_descr_set */
5150 0, /* tp_dictoffset */
5151 (initproc)comerror_init, /* tp_init */
5152 0, /* tp_alloc */
5153 0, /* tp_new */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005154};
5155
Christian Heimesc0ac1062007-11-28 12:33:51 +00005156
Thomas Hellerd4c93202006-03-08 19:35:11 +00005157static int
5158create_comerror(void)
5159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005160 PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception;
5161 if (PyType_Ready(&PyComError_Type) < 0)
5162 return -1;
Hirokazu Yamamoto34aa30c2010-09-12 16:06:18 +00005163 Py_INCREF(&PyComError_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005164 ComError = (PyObject*)&PyComError_Type;
5165 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005166}
5167
5168#endif
5169
5170static PyObject *
Guido van Rossumd8faa362007-04-27 19:54:29 +00005171string_at(const char *ptr, int size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00005172{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005173 if (size == -1)
5174 return PyBytes_FromStringAndSize(ptr, strlen(ptr));
5175 return PyBytes_FromStringAndSize(ptr, size);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005176}
5177
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005178static int
5179cast_check_pointertype(PyObject *arg)
5180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005181 StgDictObject *dict;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005183 if (PyCPointerTypeObject_Check(arg))
5184 return 1;
5185 if (PyCFuncPtrTypeObject_Check(arg))
5186 return 1;
5187 dict = PyType_stgdict(arg);
5188 if (dict) {
5189 if (PyUnicode_Check(dict->proto)
5190 && (strchr("sPzUZXO", _PyUnicode_AsString(dict->proto)[0]))) {
5191 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
5192 return 1;
5193 }
5194 }
5195 PyErr_Format(PyExc_TypeError,
5196 "cast() argument 2 must be a pointer type, not %s",
5197 PyType_Check(arg)
5198 ? ((PyTypeObject *)arg)->tp_name
5199 : Py_TYPE(arg)->tp_name);
5200 return 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005201}
5202
5203static PyObject *
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005204cast(void *ptr, PyObject *src, PyObject *ctype)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005206 CDataObject *result;
5207 if (0 == cast_check_pointertype(ctype))
5208 return NULL;
5209 result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
5210 if (result == NULL)
5211 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005213 /*
5214 The casted objects '_objects' member:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005216 It must certainly contain the source objects one.
5217 It must contain the source object itself.
5218 */
5219 if (CDataObject_Check(src)) {
5220 CDataObject *obj = (CDataObject *)src;
5221 /* PyCData_GetContainer will initialize src.b_objects, we need
5222 this so it can be shared */
5223 PyCData_GetContainer(obj);
5224 /* But we need a dictionary! */
5225 if (obj->b_objects == Py_None) {
5226 Py_DECREF(Py_None);
5227 obj->b_objects = PyDict_New();
5228 if (obj->b_objects == NULL)
5229 goto failed;
5230 }
5231 Py_XINCREF(obj->b_objects);
5232 result->b_objects = obj->b_objects;
5233 if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
5234 PyObject *index;
5235 int rc;
5236 index = PyLong_FromVoidPtr((void *)src);
5237 if (index == NULL)
5238 goto failed;
5239 rc = PyDict_SetItem(result->b_objects, index, src);
5240 Py_DECREF(index);
5241 if (rc == -1)
5242 goto failed;
5243 }
5244 }
5245 /* Should we assert that result is a pointer type? */
5246 memcpy(result->b_ptr, &ptr, sizeof(void *));
5247 return (PyObject *)result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005248
5249 failed:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005250 Py_DECREF(result);
5251 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005252}
Thomas Hellerd4c93202006-03-08 19:35:11 +00005253
5254#ifdef CTYPES_UNICODE
5255static PyObject *
5256wstring_at(const wchar_t *ptr, int size)
5257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005258 Py_ssize_t ssize = size;
5259 if (ssize == -1)
5260 ssize = wcslen(ptr);
5261 return PyUnicode_FromWideChar(ptr, ssize);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005262}
5263#endif
5264
Martin v. Löwis1a214512008-06-11 05:26:20 +00005265
5266static struct PyModuleDef _ctypesmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005267 PyModuleDef_HEAD_INIT,
5268 "_ctypes",
5269 module_docs,
5270 -1,
5271 _ctypes_module_methods,
5272 NULL,
5273 NULL,
5274 NULL,
5275 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00005276};
5277
Thomas Hellerfe8f8622006-03-14 19:53:09 +00005278PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00005279PyInit__ctypes(void)
Thomas Hellerd4c93202006-03-08 19:35:11 +00005280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005281 PyObject *m;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005282
5283/* Note:
5284 ob_type is the metatype (the 'type'), defaults to PyType_Type,
5285 tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
5286*/
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005287#ifdef WITH_THREAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005288 PyEval_InitThreads();
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005289#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005290 m = PyModule_Create(&_ctypesmodule);
5291 if (!m)
5292 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005294 _ctypes_ptrtype_cache = PyDict_New();
5295 if (_ctypes_ptrtype_cache == NULL)
5296 return NULL;
Thomas Heller3071f812008-04-14 16:17:33 +00005297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005298 PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache);
Thomas Heller3071f812008-04-14 16:17:33 +00005299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005300 _unpickle = PyObject_GetAttrString(m, "_unpickle");
5301 if (_unpickle == NULL)
5302 return NULL;
Thomas Heller13394e92008-02-13 20:40:44 +00005303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005304 if (PyType_Ready(&PyCArg_Type) < 0)
5305 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005307 if (PyType_Ready(&PyCThunk_Type) < 0)
5308 return NULL;
Thomas Hellere106dc32008-04-24 18:39:36 +00005309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005310 /* StgDict is derived from PyDict_Type */
5311 PyCStgDict_Type.tp_base = &PyDict_Type;
5312 if (PyType_Ready(&PyCStgDict_Type) < 0)
5313 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005315 /*************************************************
5316 *
5317 * Metaclasses
5318 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005320 PyCStructType_Type.tp_base = &PyType_Type;
5321 if (PyType_Ready(&PyCStructType_Type) < 0)
5322 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005324 UnionType_Type.tp_base = &PyType_Type;
5325 if (PyType_Ready(&UnionType_Type) < 0)
5326 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005328 PyCPointerType_Type.tp_base = &PyType_Type;
5329 if (PyType_Ready(&PyCPointerType_Type) < 0)
5330 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005332 PyCArrayType_Type.tp_base = &PyType_Type;
5333 if (PyType_Ready(&PyCArrayType_Type) < 0)
5334 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005336 PyCSimpleType_Type.tp_base = &PyType_Type;
5337 if (PyType_Ready(&PyCSimpleType_Type) < 0)
5338 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005340 PyCFuncPtrType_Type.tp_base = &PyType_Type;
5341 if (PyType_Ready(&PyCFuncPtrType_Type) < 0)
5342 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005344 /*************************************************
5345 *
5346 * Classes using a custom metaclass
5347 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005349 if (PyType_Ready(&PyCData_Type) < 0)
5350 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005352 Py_TYPE(&Struct_Type) = &PyCStructType_Type;
5353 Struct_Type.tp_base = &PyCData_Type;
5354 if (PyType_Ready(&Struct_Type) < 0)
5355 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005356 Py_INCREF(&Struct_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005357 PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005359 Py_TYPE(&Union_Type) = &UnionType_Type;
5360 Union_Type.tp_base = &PyCData_Type;
5361 if (PyType_Ready(&Union_Type) < 0)
5362 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005363 Py_INCREF(&Union_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005364 PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005366 Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type;
5367 PyCPointer_Type.tp_base = &PyCData_Type;
5368 if (PyType_Ready(&PyCPointer_Type) < 0)
5369 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005370 Py_INCREF(&PyCPointer_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005371 PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005373 Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type;
5374 PyCArray_Type.tp_base = &PyCData_Type;
5375 if (PyType_Ready(&PyCArray_Type) < 0)
5376 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005377 Py_INCREF(&PyCArray_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005378 PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005380 Py_TYPE(&Simple_Type) = &PyCSimpleType_Type;
5381 Simple_Type.tp_base = &PyCData_Type;
5382 if (PyType_Ready(&Simple_Type) < 0)
5383 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005384 Py_INCREF(&Simple_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005385 PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005387 Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type;
5388 PyCFuncPtr_Type.tp_base = &PyCData_Type;
5389 if (PyType_Ready(&PyCFuncPtr_Type) < 0)
5390 return NULL;
Thomas Hellerbf4cc5d2010-08-08 18:16:20 +00005391 Py_INCREF(&PyCFuncPtr_Type);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005392 PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005394 /*************************************************
5395 *
5396 * Simple classes
5397 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005399 /* PyCField_Type is derived from PyBaseObject_Type */
5400 if (PyType_Ready(&PyCField_Type) < 0)
5401 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005403 /*************************************************
5404 *
5405 * Other stuff
5406 */
Thomas Hellerd4c93202006-03-08 19:35:11 +00005407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005408 DictRemover_Type.tp_new = PyType_GenericNew;
5409 if (PyType_Ready(&DictRemover_Type) < 0)
5410 return NULL;
Christian Heimes969fe572008-01-25 11:23:10 +00005411
Thomas Hellerd4c93202006-03-08 19:35:11 +00005412#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005413 if (create_comerror() < 0)
5414 return NULL;
5415 PyModule_AddObject(m, "COMError", ComError);
Thomas Hellerd4c93202006-03-08 19:35:11 +00005416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005417 PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
5418 PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
Thomas Hellerd4c93202006-03-08 19:35:11 +00005419#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005420 PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL));
5421 PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
5422 PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
5423 PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
5424 PyModule_AddStringConstant(m, "__version__", "1.1.0");
Thomas Hellerd4c93202006-03-08 19:35:11 +00005425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005426 PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
5427 PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
5428 PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
5429 PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
Thomas Hellerd4c93202006-03-08 19:35:11 +00005430#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005431 PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
Thomas Hellerd4c93202006-03-08 19:35:11 +00005432#endif
5433
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005434/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
5435#ifndef RTLD_LOCAL
5436#define RTLD_LOCAL 0
5437#endif
5438
5439/* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
5440 RTLD_LOCAL.
5441*/
5442#ifndef RTLD_GLOBAL
5443#define RTLD_GLOBAL RTLD_LOCAL
5444#endif
5445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00005446 PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL));
5447 PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL));
5448
5449 PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5450 if (PyExc_ArgError) {
5451 Py_INCREF(PyExc_ArgError);
5452 PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
5453 }
5454 return m;
Thomas Hellerd4c93202006-03-08 19:35:11 +00005455}
5456
Thomas Hellerd4c93202006-03-08 19:35:11 +00005457/*
5458 Local Variables:
5459 compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
5460 End:
5461*/