blob: a43585f1b83f1341548ee3f42bab2e05c8ed30ab [file] [log] [blame]
Thomas Hellerd4c93202006-03-08 19:35:11 +00001#include "Python.h"
Thomas Hellerd4c93202006-03-08 19:35:11 +00002
3#include <ffi.h>
4#ifdef MS_WIN32
5#include <windows.h>
6#endif
7#include "ctypes.h"
8
Benjamin Petersonb173f782009-05-05 22:31:58 +00009
10#define CTYPES_CFIELD_CAPSULE_NAME_PYMEM "_ctypes/cfield.c pymem"
11
12static void pymem_destructor(PyObject *ptr)
13{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000014 void *p = PyCapsule_GetPointer(ptr, CTYPES_CFIELD_CAPSULE_NAME_PYMEM);
15 if (p) {
16 PyMem_Free(p);
17 }
Benjamin Petersonb173f782009-05-05 22:31:58 +000018}
19
20
Thomas Hellerd4c93202006-03-08 19:35:11 +000021/******************************************************************/
22/*
Thomas Heller34596a92009-04-24 20:50:00 +000023 PyCField_Type
Thomas Hellerd4c93202006-03-08 19:35:11 +000024*/
25static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +000026PyCField_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Thomas Hellerd4c93202006-03-08 19:35:11 +000027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028 CFieldObject *obj;
29 obj = (CFieldObject *)type->tp_alloc(type, 0);
30 return (PyObject *)obj;
Thomas Hellerd4c93202006-03-08 19:35:11 +000031}
32
33/*
34 * Expects the size, index and offset for the current field in *psize and
35 * *poffset, stores the total size so far in *psize, the offset for the next
36 * field in *poffset, the alignment requirements for the current field in
37 * *palign, and returns a field desriptor for this field.
38 */
39/*
40 * bitfields extension:
41 * bitsize != 0: this is a bit field.
42 * pbitofs points to the current bit offset, this will be updated.
43 * prev_desc points to the type of the previous bitfield, if any.
44 */
45PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +000046PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 Py_ssize_t *pfield_size, int bitsize, int *pbitofs,
48 Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign,
49 int pack, int big_endian)
Thomas Hellerd4c93202006-03-08 19:35:11 +000050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 CFieldObject *self;
52 PyObject *proto;
Brett Cannonb94767f2011-02-22 20:15:44 +000053 Py_ssize_t size, align;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000054 SETFUNC setfunc = NULL;
55 GETFUNC getfunc = NULL;
56 StgDictObject *dict;
57 int fieldtype;
Thomas Hellerd4c93202006-03-08 19:35:11 +000058#define NO_BITFIELD 0
59#define NEW_BITFIELD 1
60#define CONT_BITFIELD 2
61#define EXPAND_BITFIELD 3
62
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 self = (CFieldObject *)PyObject_CallObject((PyObject *)&PyCField_Type,
64 NULL);
65 if (self == NULL)
66 return NULL;
67 dict = PyType_stgdict(desc);
68 if (!dict) {
69 PyErr_SetString(PyExc_TypeError,
70 "has no _stginfo_");
71 Py_DECREF(self);
72 return NULL;
73 }
74 if (bitsize /* this is a bitfield request */
75 && *pfield_size /* we have a bitfield open */
Thomas Heller28acc6c2008-09-29 20:03:53 +000076#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 /* MSVC, GCC with -mms-bitfields */
78 && dict->size * 8 == *pfield_size
Thomas Hellerd4c93202006-03-08 19:35:11 +000079#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 /* GCC */
81 && dict->size * 8 <= *pfield_size
Thomas Hellerd4c93202006-03-08 19:35:11 +000082#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 && (*pbitofs + bitsize) <= *pfield_size) {
84 /* continue bit field */
85 fieldtype = CONT_BITFIELD;
Thomas Hellerd4c93202006-03-08 19:35:11 +000086#ifndef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 } else if (bitsize /* this is a bitfield request */
88 && *pfield_size /* we have a bitfield open */
89 && dict->size * 8 >= *pfield_size
90 && (*pbitofs + bitsize) <= dict->size * 8) {
91 /* expand bit field */
92 fieldtype = EXPAND_BITFIELD;
Thomas Hellerd4c93202006-03-08 19:35:11 +000093#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 } else if (bitsize) {
95 /* start new bitfield */
96 fieldtype = NEW_BITFIELD;
97 *pbitofs = 0;
98 *pfield_size = dict->size * 8;
99 } else {
100 /* not a bit field */
101 fieldtype = NO_BITFIELD;
102 *pbitofs = 0;
103 *pfield_size = 0;
104 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000105
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 size = dict->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 proto = desc;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 /* Field descriptors for 'c_char * n' are be scpecial cased to
110 return a Python string instead of an Array object instance...
111 */
112 if (PyCArrayTypeObject_Check(proto)) {
113 StgDictObject *adict = PyType_stgdict(proto);
114 StgDictObject *idict;
115 if (adict && adict->proto) {
116 idict = PyType_stgdict(adict->proto);
117 if (!idict) {
118 PyErr_SetString(PyExc_TypeError,
119 "has no _stginfo_");
120 Py_DECREF(self);
121 return NULL;
122 }
123 if (idict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
124 struct fielddesc *fd = _ctypes_get_fielddesc("s");
125 getfunc = fd->getfunc;
126 setfunc = fd->setfunc;
127 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000128#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 if (idict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
130 struct fielddesc *fd = _ctypes_get_fielddesc("U");
131 getfunc = fd->getfunc;
132 setfunc = fd->setfunc;
133 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000134#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 }
136 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 self->setfunc = setfunc;
139 self->getfunc = getfunc;
140 self->index = index;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142 Py_INCREF(proto);
143 self->proto = proto;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 switch (fieldtype) {
146 case NEW_BITFIELD:
147 if (big_endian)
148 self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
149 else
150 self->size = (bitsize << 16) + *pbitofs;
151 *pbitofs = bitsize;
152 /* fall through */
153 case NO_BITFIELD:
154 if (pack)
155 align = min(pack, dict->align);
156 else
157 align = dict->align;
158 if (align && *poffset % align) {
159 Py_ssize_t delta = align - (*poffset % align);
160 *psize += delta;
161 *poffset += delta;
162 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 if (bitsize == 0)
165 self->size = size;
166 *psize += size;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 self->offset = *poffset;
169 *poffset += size;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 *palign = align;
172 break;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 case EXPAND_BITFIELD:
175 *poffset += dict->size - *pfield_size/8;
176 *psize += dict->size - *pfield_size/8;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000177
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 *pfield_size = dict->size * 8;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000179
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 if (big_endian)
181 self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
182 else
183 self->size = (bitsize << 16) + *pbitofs;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
186 *pbitofs += bitsize;
187 break;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 case CONT_BITFIELD:
190 if (big_endian)
191 self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
192 else
193 self->size = (bitsize << 16) + *pbitofs;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
196 *pbitofs += bitsize;
197 break;
198 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 return (PyObject *)self;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000201}
202
203static int
Thomas Heller34596a92009-04-24 20:50:00 +0000204PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 CDataObject *dst;
207 char *ptr;
208 assert(CDataObject_Check(inst));
209 dst = (CDataObject *)inst;
210 ptr = dst->b_ptr + self->offset;
211 if (value == NULL) {
212 PyErr_SetString(PyExc_TypeError,
213 "can't delete attribute");
214 return -1;
215 }
216 return PyCData_set(inst, self->proto, self->setfunc, value,
217 self->index, self->size, ptr);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000218}
219
220static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000221PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000223 CDataObject *src;
224 if (inst == NULL) {
225 Py_INCREF(self);
226 return (PyObject *)self;
227 }
228 assert(CDataObject_Check(inst));
229 src = (CDataObject *)inst;
230 return PyCData_get(self->proto, self->getfunc, inst,
231 self->index, self->size, src->b_ptr + self->offset);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000232}
233
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000234static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000235PyCField_get_offset(PyObject *self, void *data)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 return PyLong_FromSsize_t(((CFieldObject *)self)->offset);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000238}
239
240static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000241PyCField_get_size(PyObject *self, void *data)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000242{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 return PyLong_FromSsize_t(((CFieldObject *)self)->size);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000244}
245
Thomas Heller34596a92009-04-24 20:50:00 +0000246static PyGetSetDef PyCField_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 { "offset", PyCField_get_offset, NULL, "offset in bytes of this field" },
248 { "size", PyCField_get_size, NULL, "size in bytes of this field" },
249 { NULL, NULL, NULL, NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +0000250};
251
252static int
Thomas Heller34596a92009-04-24 20:50:00 +0000253PyCField_traverse(CFieldObject *self, visitproc visit, void *arg)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000254{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 Py_VISIT(self->proto);
256 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000257}
258
259static int
Thomas Heller34596a92009-04-24 20:50:00 +0000260PyCField_clear(CFieldObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 Py_CLEAR(self->proto);
263 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000264}
265
266static void
Thomas Heller34596a92009-04-24 20:50:00 +0000267PyCField_dealloc(PyObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 PyCField_clear((CFieldObject *)self);
270 self->ob_type->tp_free((PyObject *)self);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000271}
272
273static PyObject *
Thomas Heller34596a92009-04-24 20:50:00 +0000274PyCField_repr(CFieldObject *self)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000275{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 PyObject *result;
277 Py_ssize_t bits = self->size >> 16;
278 Py_ssize_t size = self->size & 0xFFFF;
279 const char *name;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 name = ((PyTypeObject *)self->proto)->tp_name;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 if (bits)
284 result = PyUnicode_FromFormat(
285 "<Field type=%s, ofs=%zd:%zd, bits=%zd>",
286 name, self->offset, size, bits);
287 else
288 result = PyUnicode_FromFormat(
289 "<Field type=%s, ofs=%zd, size=%zd>",
290 name, self->offset, size);
291 return result;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000292}
293
Thomas Heller34596a92009-04-24 20:50:00 +0000294PyTypeObject PyCField_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 PyVarObject_HEAD_INIT(NULL, 0)
296 "_ctypes.CField", /* tp_name */
297 sizeof(CFieldObject), /* tp_basicsize */
298 0, /* tp_itemsize */
299 PyCField_dealloc, /* tp_dealloc */
300 0, /* tp_print */
301 0, /* tp_getattr */
302 0, /* tp_setattr */
303 0, /* tp_reserved */
304 (reprfunc)PyCField_repr, /* tp_repr */
305 0, /* tp_as_number */
306 0, /* tp_as_sequence */
307 0, /* tp_as_mapping */
308 0, /* tp_hash */
309 0, /* tp_call */
310 0, /* tp_str */
311 0, /* tp_getattro */
312 0, /* tp_setattro */
313 0, /* tp_as_buffer */
314 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
315 "Structure/Union member", /* tp_doc */
316 (traverseproc)PyCField_traverse, /* tp_traverse */
317 (inquiry)PyCField_clear, /* tp_clear */
318 0, /* tp_richcompare */
319 0, /* tp_weaklistoffset */
320 0, /* tp_iter */
321 0, /* tp_iternext */
322 0, /* tp_methods */
323 0, /* tp_members */
324 PyCField_getset, /* tp_getset */
325 0, /* tp_base */
326 0, /* tp_dict */
327 (descrgetfunc)PyCField_get, /* tp_descr_get */
328 (descrsetfunc)PyCField_set, /* tp_descr_set */
329 0, /* tp_dictoffset */
330 0, /* tp_init */
331 0, /* tp_alloc */
332 PyCField_new, /* tp_new */
333 0, /* tp_free */
Thomas Hellerd4c93202006-03-08 19:35:11 +0000334};
335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336
Thomas Hellerd4c93202006-03-08 19:35:11 +0000337/******************************************************************/
338/*
339 Accessor functions
340*/
341
342/* Derived from Modules/structmodule.c:
343 Helper routine to get a Python integer and raise the appropriate error
344 if it isn't one */
345
346static int
347get_long(PyObject *v, long *p)
348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 long x;
Christian Heimes969fe572008-01-25 11:23:10 +0000350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 if (PyFloat_Check(v)) {
352 PyErr_SetString(PyExc_TypeError,
353 "int expected instead of float");
354 return -1;
355 }
356 x = PyLong_AsUnsignedLongMask(v);
357 if (x == -1 && PyErr_Occurred())
358 return -1;
359 *p = x;
360 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000361}
362
363/* Same, but handling unsigned long */
364
365static int
366get_ulong(PyObject *v, unsigned long *p)
367{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 unsigned long x;
Christian Heimes969fe572008-01-25 11:23:10 +0000369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 if (PyFloat_Check(v)) {
371 PyErr_SetString(PyExc_TypeError,
372 "int expected instead of float");
373 return -1;
374 }
375 x = PyLong_AsUnsignedLongMask(v);
376 if (x == (unsigned long)-1 && PyErr_Occurred())
377 return -1;
378 *p = x;
379 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000380}
381
Thomas Hellerd4c93202006-03-08 19:35:11 +0000382/* Same, but handling native long long. */
383
384static int
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700385get_longlong(PyObject *v, long long *p)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000386{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700387 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 if (PyFloat_Check(v)) {
389 PyErr_SetString(PyExc_TypeError,
390 "int expected instead of float");
391 return -1;
392 }
393 x = PyLong_AsUnsignedLongLongMask(v);
394 if (x == -1 && PyErr_Occurred())
395 return -1;
396 *p = x;
397 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000398}
399
400/* Same, but handling native unsigned long long. */
401
402static int
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700403get_ulonglong(PyObject *v, unsigned long long *p)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000404{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700405 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 if (PyFloat_Check(v)) {
407 PyErr_SetString(PyExc_TypeError,
408 "int expected instead of float");
409 return -1;
410 }
411 x = PyLong_AsUnsignedLongLongMask(v);
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700412 if (x == (unsigned long long)-1 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 return -1;
414 *p = x;
415 return 0;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000416}
417
Thomas Hellerd4c93202006-03-08 19:35:11 +0000418/*****************************************************************
419 * Integer fields, with bitfield support
420 */
421
422/* how to decode the size field, for integer get/set functions */
423#define LOW_BIT(x) ((x) & 0xFFFF)
424#define NUM_BITS(x) ((x) >> 16)
425
Meador Inge60c22662012-07-19 00:01:22 -0500426/* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */
427#define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000428
429/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
430 we must first shift left, then right.
431*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432#define GET_BITFIELD(v, size) \
433 if (NUM_BITS(size)) { \
434 v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \
435 v >>= (sizeof(v)*8 - NUM_BITS(size)); \
436 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000437
438/* This macro RETURNS the first parameter with the bit field CHANGED. */
Meador Inge60c22662012-07-19 00:01:22 -0500439#define SET(type, x, v, size) \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 (NUM_BITS(size) ? \
Meador Inge60c22662012-07-19 00:01:22 -0500441 ( ( (type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type, size)) << LOW_BIT(size) ) ) \
442 : (type)v)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000443
444/* byte swapping macros */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445#define SWAP_2(v) \
446 ( ( (v >> 8) & 0x00FF) | \
447 ( (v << 8) & 0xFF00) )
Thomas Hellerd4c93202006-03-08 19:35:11 +0000448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449#define SWAP_4(v) \
450 ( ( (v & 0x000000FF) << 24 ) | \
451 ( (v & 0x0000FF00) << 8 ) | \
452 ( (v & 0x00FF0000) >> 8 ) | \
453 ( ((v >> 24) & 0xFF)) )
Thomas Hellerd4c93202006-03-08 19:35:11 +0000454
455#ifdef _MSC_VER
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456#define SWAP_8(v) \
457 ( ( (v & 0x00000000000000FFL) << 56 ) | \
458 ( (v & 0x000000000000FF00L) << 40 ) | \
459 ( (v & 0x0000000000FF0000L) << 24 ) | \
460 ( (v & 0x00000000FF000000L) << 8 ) | \
461 ( (v & 0x000000FF00000000L) >> 8 ) | \
462 ( (v & 0x0000FF0000000000L) >> 24 ) | \
463 ( (v & 0x00FF000000000000L) >> 40 ) | \
464 ( ((v >> 56) & 0xFF)) )
Thomas Hellerd4c93202006-03-08 19:35:11 +0000465#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466#define SWAP_8(v) \
467 ( ( (v & 0x00000000000000FFLL) << 56 ) | \
468 ( (v & 0x000000000000FF00LL) << 40 ) | \
469 ( (v & 0x0000000000FF0000LL) << 24 ) | \
470 ( (v & 0x00000000FF000000LL) << 8 ) | \
471 ( (v & 0x000000FF00000000LL) >> 8 ) | \
472 ( (v & 0x0000FF0000000000LL) >> 24 ) | \
473 ( (v & 0x00FF000000000000LL) >> 40 ) | \
474 ( ((v >> 56) & 0xFF)) )
Thomas Hellerd4c93202006-03-08 19:35:11 +0000475#endif
476
477#define SWAP_INT SWAP_4
478
479#if SIZEOF_LONG == 4
480# define SWAP_LONG SWAP_4
481#elif SIZEOF_LONG == 8
482# define SWAP_LONG SWAP_8
483#endif
484/*****************************************************************
485 * The setter methods return an object which must be kept alive, to keep the
486 * data valid which has been stored in the memory block. The ctypes object
487 * instance inserts this object into its 'b_objects' list.
488 *
489 * For simple Python types like integers or characters, there is nothing that
490 * has to been kept alive, so Py_None is returned in these cases. But this
491 * makes inspecting the 'b_objects' list, which is accessible from Python for
492 * debugging, less useful.
493 *
494 * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value
495 * instead of Py_None.
496 */
497
498#ifdef _CTYPES_DEBUG_KEEP
499#define _RET(x) Py_INCREF(x); return x
500#else
501#define _RET(X) Py_INCREF(Py_None); return Py_None
502#endif
503
504/*****************************************************************
505 * integer accessor methods, supporting bit fields
506 */
507
508static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000509b_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000510{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 long val;
512 if (get_long(value, &val) < 0)
513 return NULL;
Meador Inge60c22662012-07-19 00:01:22 -0500514 *(signed char *)ptr = SET(signed char, *(signed char *)ptr, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000516}
517
518
519static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000520b_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000521{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 signed char val = *(signed char *)ptr;
523 GET_BITFIELD(val, size);
524 return PyLong_FromLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000525}
526
527static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000528B_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 unsigned long val;
531 if (get_ulong(value, &val) < 0)
532 return NULL;
Meador Inge60c22662012-07-19 00:01:22 -0500533 *(unsigned char *)ptr = SET(unsigned char, *(unsigned char*)ptr, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000535}
536
537
538static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000539B_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 unsigned char val = *(unsigned char *)ptr;
542 GET_BITFIELD(val, size);
543 return PyLong_FromLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000544}
545
546static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000547h_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 long val;
550 short x;
551 if (get_long(value, &val) < 0)
552 return NULL;
553 memcpy(&x, ptr, sizeof(x));
Meador Inge60c22662012-07-19 00:01:22 -0500554 x = SET(short, x, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 memcpy(ptr, &x, sizeof(x));
556 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000557}
558
559
560static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000561h_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000562{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 long val;
564 short field;
565 if (get_long(value, &val) < 0)
566 return NULL;
567 memcpy(&field, ptr, sizeof(field));
568 field = SWAP_2(field);
Meador Inge60c22662012-07-19 00:01:22 -0500569 field = SET(short, field, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 field = SWAP_2(field);
571 memcpy(ptr, &field, sizeof(field));
572 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000573}
574
575static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000576h_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000577{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 short val;
579 memcpy(&val, ptr, sizeof(val));
580 GET_BITFIELD(val, size);
581 return PyLong_FromLong((long)val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000582}
583
584static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000585h_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000586{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 short val;
588 memcpy(&val, ptr, sizeof(val));
589 val = SWAP_2(val);
590 GET_BITFIELD(val, size);
591 return PyLong_FromLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000592}
593
594static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000595H_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000596{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 unsigned long val;
598 unsigned short x;
599 if (get_ulong(value, &val) < 0)
600 return NULL;
601 memcpy(&x, ptr, sizeof(x));
Meador Inge60c22662012-07-19 00:01:22 -0500602 x = SET(unsigned short, x, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 memcpy(ptr, &x, sizeof(x));
604 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000605}
606
607static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000608H_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000609{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 unsigned long val;
611 unsigned short field;
612 if (get_ulong(value, &val) < 0)
613 return NULL;
614 memcpy(&field, ptr, sizeof(field));
615 field = SWAP_2(field);
Meador Inge60c22662012-07-19 00:01:22 -0500616 field = SET(unsigned short, field, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 field = SWAP_2(field);
618 memcpy(ptr, &field, sizeof(field));
619 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000620}
621
622
623static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000624H_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 unsigned short val;
627 memcpy(&val, ptr, sizeof(val));
628 GET_BITFIELD(val, size);
629 return PyLong_FromLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000630}
631
632static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000633H_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000634{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 unsigned short val;
636 memcpy(&val, ptr, sizeof(val));
637 val = SWAP_2(val);
638 GET_BITFIELD(val, size);
639 return PyLong_FromLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000640}
641
642static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000643i_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000644{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 long val;
646 int x;
647 if (get_long(value, &val) < 0)
648 return NULL;
649 memcpy(&x, ptr, sizeof(x));
Meador Inge60c22662012-07-19 00:01:22 -0500650 x = SET(int, x, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 memcpy(ptr, &x, sizeof(x));
652 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000653}
654
655static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000656i_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000657{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 long val;
659 int field;
660 if (get_long(value, &val) < 0)
661 return NULL;
662 memcpy(&field, ptr, sizeof(field));
663 field = SWAP_INT(field);
Meador Inge60c22662012-07-19 00:01:22 -0500664 field = SET(int, field, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 field = SWAP_INT(field);
666 memcpy(ptr, &field, sizeof(field));
667 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000668}
669
670
671static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000672i_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000673{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 int val;
675 memcpy(&val, ptr, sizeof(val));
676 GET_BITFIELD(val, size);
677 return PyLong_FromLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000678}
679
680static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000681i_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000682{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 int val;
684 memcpy(&val, ptr, sizeof(val));
685 val = SWAP_INT(val);
686 GET_BITFIELD(val, size);
687 return PyLong_FromLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000688}
689
690#ifdef MS_WIN32
691/* short BOOL - VARIANT_BOOL */
692static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000693vBOOL_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000694{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 switch (PyObject_IsTrue(value)) {
696 case -1:
697 return NULL;
698 case 0:
699 *(short int *)ptr = VARIANT_FALSE;
700 _RET(value);
701 default:
702 *(short int *)ptr = VARIANT_TRUE;
703 _RET(value);
704 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000705}
706
707static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000708vBOOL_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000709{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000710 return PyBool_FromLong((long)*(short int *)ptr);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000711}
712#endif
713
Guido van Rossumd8faa362007-04-27 19:54:29 +0000714static PyObject *
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000715bool_set(void *ptr, PyObject *value, Py_ssize_t size)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 switch (PyObject_IsTrue(value)) {
718 case -1:
719 return NULL;
720 case 0:
Benjamin Petersona9296e72016-09-07 11:06:17 -0700721 *(_Bool *)ptr = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 _RET(value);
723 default:
Benjamin Petersona9296e72016-09-07 11:06:17 -0700724 *(_Bool *)ptr = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 _RET(value);
726 }
Guido van Rossumd8faa362007-04-27 19:54:29 +0000727}
728
729static PyObject *
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000730bool_get(void *ptr, Py_ssize_t size)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000731{
Benjamin Petersona9296e72016-09-07 11:06:17 -0700732 return PyBool_FromLong((long)*(_Bool *)ptr);
Guido van Rossumd8faa362007-04-27 19:54:29 +0000733}
734
Thomas Hellerd4c93202006-03-08 19:35:11 +0000735static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000736I_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 unsigned long val;
739 unsigned int x;
740 if (get_ulong(value, &val) < 0)
741 return NULL;
742 memcpy(&x, ptr, sizeof(x));
Meador Inge60c22662012-07-19 00:01:22 -0500743 x = SET(unsigned int, x, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 memcpy(ptr, &x, sizeof(x));
745 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000746}
747
748static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000749I_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 unsigned long val;
752 unsigned int field;
753 if (get_ulong(value, &val) < 0)
754 return NULL;
755 memcpy(&field, ptr, sizeof(field));
Victor Stinner9c631a02015-07-29 14:33:52 +0200756 field = SWAP_INT(field);
Meador Inge60c22662012-07-19 00:01:22 -0500757 field = SET(unsigned int, field, (unsigned int)val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 field = SWAP_INT(field);
759 memcpy(ptr, &field, sizeof(field));
760 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000761}
762
763
764static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000765I_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000766{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000767 unsigned int val;
768 memcpy(&val, ptr, sizeof(val));
769 GET_BITFIELD(val, size);
770 return PyLong_FromUnsignedLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000771}
772
773static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000774I_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000775{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 unsigned int val;
777 memcpy(&val, ptr, sizeof(val));
778 val = SWAP_INT(val);
779 GET_BITFIELD(val, size);
780 return PyLong_FromUnsignedLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000781}
782
783static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000784l_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000785{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 long val;
787 long x;
788 if (get_long(value, &val) < 0)
789 return NULL;
790 memcpy(&x, ptr, sizeof(x));
Meador Inge60c22662012-07-19 00:01:22 -0500791 x = SET(long, x, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 memcpy(ptr, &x, sizeof(x));
793 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000794}
795
796static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000797l_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000798{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 long val;
800 long field;
801 if (get_long(value, &val) < 0)
802 return NULL;
803 memcpy(&field, ptr, sizeof(field));
804 field = SWAP_LONG(field);
Meador Inge60c22662012-07-19 00:01:22 -0500805 field = SET(long, field, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 field = SWAP_LONG(field);
807 memcpy(ptr, &field, sizeof(field));
808 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000809}
810
811
812static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000813l_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000814{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 long val;
816 memcpy(&val, ptr, sizeof(val));
817 GET_BITFIELD(val, size);
818 return PyLong_FromLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000819}
820
821static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000822l_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 long val;
825 memcpy(&val, ptr, sizeof(val));
826 val = SWAP_LONG(val);
827 GET_BITFIELD(val, size);
828 return PyLong_FromLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000829}
830
831static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000832L_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 unsigned long val;
835 unsigned long x;
836 if (get_ulong(value, &val) < 0)
837 return NULL;
838 memcpy(&x, ptr, sizeof(x));
Meador Inge60c22662012-07-19 00:01:22 -0500839 x = SET(unsigned long, x, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 memcpy(ptr, &x, sizeof(x));
841 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000842}
843
844static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000845L_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 unsigned long val;
848 unsigned long field;
849 if (get_ulong(value, &val) < 0)
850 return NULL;
851 memcpy(&field, ptr, sizeof(field));
852 field = SWAP_LONG(field);
Meador Inge60c22662012-07-19 00:01:22 -0500853 field = SET(unsigned long, field, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 field = SWAP_LONG(field);
855 memcpy(ptr, &field, sizeof(field));
856 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000857}
858
859
860static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000861L_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000863 unsigned long val;
864 memcpy(&val, ptr, sizeof(val));
865 GET_BITFIELD(val, size);
866 return PyLong_FromUnsignedLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000867}
868
869static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000870L_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000871{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 unsigned long val;
873 memcpy(&val, ptr, sizeof(val));
874 val = SWAP_LONG(val);
875 GET_BITFIELD(val, size);
876 return PyLong_FromUnsignedLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000877}
878
Thomas Hellerd4c93202006-03-08 19:35:11 +0000879static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000880q_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000881{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700882 long long val;
883 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 if (get_longlong(value, &val) < 0)
885 return NULL;
886 memcpy(&x, ptr, sizeof(x));
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700887 x = SET(long long, x, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 memcpy(ptr, &x, sizeof(x));
889 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000890}
891
892static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000893q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000894{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700895 long long val;
896 long long field;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 if (get_longlong(value, &val) < 0)
898 return NULL;
899 memcpy(&field, ptr, sizeof(field));
900 field = SWAP_8(field);
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700901 field = SET(long long, field, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 field = SWAP_8(field);
903 memcpy(ptr, &field, sizeof(field));
904 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000905}
906
907static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000908q_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000909{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700910 long long val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 memcpy(&val, ptr, sizeof(val));
912 GET_BITFIELD(val, size);
913 return PyLong_FromLongLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000914}
915
916static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000917q_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000918{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700919 long long val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 memcpy(&val, ptr, sizeof(val));
921 val = SWAP_8(val);
922 GET_BITFIELD(val, size);
923 return PyLong_FromLongLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000924}
925
926static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000927Q_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000928{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700929 unsigned long long val;
930 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 if (get_ulonglong(value, &val) < 0)
932 return NULL;
933 memcpy(&x, ptr, sizeof(x));
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700934 x = SET(long long, x, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 memcpy(ptr, &x, sizeof(x));
936 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000937}
938
939static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000940Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000941{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700942 unsigned long long val;
943 unsigned long long field;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 if (get_ulonglong(value, &val) < 0)
945 return NULL;
946 memcpy(&field, ptr, sizeof(field));
947 field = SWAP_8(field);
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700948 field = SET(unsigned long long, field, val, size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 field = SWAP_8(field);
950 memcpy(ptr, &field, sizeof(field));
951 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000952}
953
954static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000955Q_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000956{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700957 unsigned long long val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 memcpy(&val, ptr, sizeof(val));
959 GET_BITFIELD(val, size);
960 return PyLong_FromUnsignedLongLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000961}
962
963static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000964Q_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000965{
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700966 unsigned long long val;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 memcpy(&val, ptr, sizeof(val));
968 val = SWAP_8(val);
969 GET_BITFIELD(val, size);
970 return PyLong_FromUnsignedLongLong(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000971}
Thomas Hellerd4c93202006-03-08 19:35:11 +0000972
973/*****************************************************************
974 * non-integer accessor methods, not supporting bit fields
975 */
976
977
Thomas Wouters89d996e2007-09-08 17:39:28 +0000978static PyObject *
Thomas Hellerff721222008-01-17 18:46:55 +0000979g_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Wouters89d996e2007-09-08 17:39:28 +0000980{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 long double x;
Thomas Wouters89d996e2007-09-08 17:39:28 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 x = PyFloat_AsDouble(value);
Meador Inge031e25b2012-05-28 14:21:16 -0500984 if (x == -1 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 memcpy(ptr, &x, sizeof(long double));
987 _RET(value);
Thomas Wouters89d996e2007-09-08 17:39:28 +0000988}
989
990static PyObject *
Thomas Hellerff721222008-01-17 18:46:55 +0000991g_get(void *ptr, Py_ssize_t size)
Thomas Wouters89d996e2007-09-08 17:39:28 +0000992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 long double val;
994 memcpy(&val, ptr, sizeof(long double));
995 return PyFloat_FromDouble(val);
Thomas Wouters89d996e2007-09-08 17:39:28 +0000996}
Thomas Hellerd4c93202006-03-08 19:35:11 +0000997
998static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000999d_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001000{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 double x;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001002
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 x = PyFloat_AsDouble(value);
Meador Inge031e25b2012-05-28 14:21:16 -05001004 if (x == -1 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 memcpy(ptr, &x, sizeof(double));
1007 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001008}
1009
1010static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001011d_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001012{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 double val;
1014 memcpy(&val, ptr, sizeof(val));
1015 return PyFloat_FromDouble(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001016}
1017
1018static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001019d_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 double x;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001022
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 x = PyFloat_AsDouble(value);
Meador Inge031e25b2012-05-28 14:21:16 -05001024 if (x == -1 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001026#ifdef WORDS_BIGENDIAN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1))
1028 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001029#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0))
1031 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001032#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001034}
1035
1036static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001037d_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001038{
1039#ifdef WORDS_BIGENDIAN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1));
Thomas Hellerd4c93202006-03-08 19:35:11 +00001041#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0));
Thomas Hellerd4c93202006-03-08 19:35:11 +00001043#endif
1044}
1045
1046static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001047f_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001048{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 float x;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 x = (float)PyFloat_AsDouble(value);
Meador Inge031e25b2012-05-28 14:21:16 -05001052 if (x == -1 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 memcpy(ptr, &x, sizeof(x));
1055 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001056}
1057
1058static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001059f_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001060{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 float val;
1062 memcpy(&val, ptr, sizeof(val));
1063 return PyFloat_FromDouble(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001064}
1065
1066static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001067f_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 float x;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 x = (float)PyFloat_AsDouble(value);
Meador Inge031e25b2012-05-28 14:21:16 -05001072 if (x == -1 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001074#ifdef WORDS_BIGENDIAN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1))
1076 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001077#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0))
1079 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001080#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001082}
1083
1084static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001085f_get_sw(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001086{
1087#ifdef WORDS_BIGENDIAN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1));
Thomas Hellerd4c93202006-03-08 19:35:11 +00001089#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0));
Thomas Hellerd4c93202006-03-08 19:35:11 +00001091#endif
1092}
1093
1094/*
1095 py_object refcounts:
1096
1097 1. If we have a py_object instance, O_get must Py_INCREF the returned
1098 object, of course. If O_get is called from a function result, no py_object
1099 instance is created - so callproc.c::GetResult has to call Py_DECREF.
1100
1101 2. The memory block in py_object owns a refcount. So, py_object must call
1102 Py_DECREF on destruction. Maybe only when b_needsfree is non-zero.
1103*/
1104static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001105O_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001106{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 PyObject *ob = *(PyObject **)ptr;
1108 if (ob == NULL) {
1109 if (!PyErr_Occurred())
1110 /* Set an error if not yet set */
1111 PyErr_SetString(PyExc_ValueError,
1112 "PyObject is NULL");
1113 return NULL;
1114 }
1115 Py_INCREF(ob);
1116 return ob;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001117}
1118
1119static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001120O_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001121{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 /* Hm, does the memory block need it's own refcount or not? */
1123 *(PyObject **)ptr = value;
1124 Py_INCREF(value);
1125 return value;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001126}
1127
1128
1129static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001130c_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001131{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 if (PyBytes_Check(value) && PyBytes_GET_SIZE(value) == 1) {
1133 *(char *)ptr = PyBytes_AS_STRING(value)[0];
1134 _RET(value);
1135 }
1136 if (PyByteArray_Check(value) && PyByteArray_GET_SIZE(value) == 1) {
1137 *(char *)ptr = PyByteArray_AS_STRING(value)[0];
1138 _RET(value);
1139 }
1140 if (PyLong_Check(value))
1141 {
1142 long longval = PyLong_AS_LONG(value);
1143 if (longval < 0 || longval >= 256)
1144 goto error;
1145 *(char *)ptr = (char)longval;
1146 _RET(value);
1147 }
Thomas Heller19b52542007-07-13 12:52:51 +00001148 error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 PyErr_Format(PyExc_TypeError,
Serhiy Storchaka4f06d602014-08-09 09:33:05 +03001150 "one character bytes, bytearray or integer expected");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001152}
1153
1154
1155static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001156c_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 return PyBytes_FromStringAndSize((char *)ptr, 1);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001159}
1160
1161#ifdef CTYPES_UNICODE
1162/* u - a single wchar_t character */
1163static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001164u_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001165{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 Py_ssize_t len;
Victor Stinner749261e2010-10-02 11:25:35 +00001167 wchar_t chars[2];
Victor Stinnercf448832010-07-28 00:15:03 +00001168 if (!PyUnicode_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 PyErr_Format(PyExc_TypeError,
1170 "unicode string expected instead of %s instance",
1171 value->ob_type->tp_name);
1172 return NULL;
1173 } else
1174 Py_INCREF(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001175
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001176 len = PyUnicode_AsWideChar(value, chars, 2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 if (len != 1) {
1178 Py_DECREF(value);
1179 PyErr_SetString(PyExc_TypeError,
1180 "one character unicode string expected");
1181 return NULL;
1182 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001183
Victor Stinner749261e2010-10-02 11:25:35 +00001184 *(wchar_t *)ptr = chars[0];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 Py_DECREF(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001188}
1189
1190
1191static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001192u_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001193{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 return PyUnicode_FromWideChar((wchar_t *)ptr, 1);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001195}
1196
1197/* U - a unicode string */
1198static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001199U_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 Py_ssize_t len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001202 wchar_t *p;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 size /= sizeof(wchar_t); /* we count character units here, not bytes */
Thomas Hellerd4c93202006-03-08 19:35:11 +00001205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 /* We need 'result' to be able to count the characters with wcslen,
1207 since ptr may not be NUL terminated. If the length is smaller (if
1208 it was actually NUL terminated, we construct a new one and throw
1209 away the result.
1210 */
1211 /* chop off at the first NUL character, if any. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001212 p = (wchar_t*)ptr;
1213 for (len = 0; len < size; ++len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 if (!p[len])
1215 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001217
1218 return PyUnicode_FromWideChar((wchar_t *)ptr, len);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001219}
1220
1221static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001222U_set(void *ptr, PyObject *value, Py_ssize_t length)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001223{
Victor Stinnerea90e0f2011-11-21 02:11:26 +01001224 Py_UNICODE *wstr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 Py_ssize_t size;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 /* It's easier to calculate in characters than in bytes */
1228 length /= sizeof(wchar_t);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001229
Victor Stinnercf448832010-07-28 00:15:03 +00001230 if (!PyUnicode_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 PyErr_Format(PyExc_TypeError,
1232 "unicode string expected instead of %s instance",
1233 value->ob_type->tp_name);
1234 return NULL;
Serhiy Storchakaadef6462016-06-16 22:08:46 +03001235 }
Victor Stinnerea90e0f2011-11-21 02:11:26 +01001236
1237 wstr = PyUnicode_AsUnicodeAndSize(value, &size);
1238 if (wstr == NULL)
1239 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 if (size > length) {
1241 PyErr_Format(PyExc_ValueError,
1242 "string too long (%zd, maximum length %zd)",
1243 size, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 return NULL;
1245 } else if (size < length-1)
1246 /* copy terminating NUL character if there is space */
1247 size += 1;
Brett Cannon845f7842013-07-25 17:34:00 -04001248
1249 if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, size) == -1) {
1250 return NULL;
1251 }
1252
Serhiy Storchakaadef6462016-06-16 22:08:46 +03001253 Py_INCREF(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 return value;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001255}
1256
1257#endif
1258
1259static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001260s_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 Py_ssize_t i;
1263 char *p;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 p = (char *)ptr;
1266 for (i = 0; i < size; ++i) {
1267 if (*p++ == '\0')
1268 break;
1269 }
Thomas Heller19b52542007-07-13 12:52:51 +00001270
Victor Stinnerda0eca42010-06-11 21:50:30 +00001271 return PyBytes_FromStringAndSize((char *)ptr, (Py_ssize_t)i);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001272}
1273
1274static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001275s_set(void *ptr, PyObject *value, Py_ssize_t length)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 char *data;
1278 Py_ssize_t size;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001279
Serhiy Storchakaadef6462016-06-16 22:08:46 +03001280 if(!PyBytes_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 PyErr_Format(PyExc_TypeError,
Serhiy Storchaka4f06d602014-08-09 09:33:05 +03001282 "expected bytes, %s found",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 value->ob_type->tp_name);
1284 return NULL;
1285 }
Thomas Hellere5095e12007-07-13 11:19:35 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 data = PyBytes_AS_STRING(value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 size = strlen(data); /* XXX Why not Py_SIZE(value)? */
1289 if (size < length) {
Serhiy Storchakaadef6462016-06-16 22:08:46 +03001290 /* This will copy the terminating NUL character
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 * if there is space for it.
1292 */
1293 ++size;
1294 } else if (size > length) {
1295 PyErr_Format(PyExc_ValueError,
Serhiy Storchaka4f06d602014-08-09 09:33:05 +03001296 "bytes too long (%zd, maximum length %zd)",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 size, length);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 return NULL;
1299 }
1300 /* Also copy the terminating NUL character if there is space */
1301 memcpy((char *)ptr, data, size);
Thomas Hellere5095e12007-07-13 11:19:35 +00001302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001304}
1305
1306static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001307z_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001308{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 if (value == Py_None) {
1310 *(char **)ptr = NULL;
1311 Py_INCREF(value);
1312 return value;
1313 }
1314 if (PyBytes_Check(value)) {
1315 *(char **)ptr = PyBytes_AsString(value);
1316 Py_INCREF(value);
1317 return value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 } else if (PyLong_Check(value)) {
Thomas Wouters89f507f2006-12-13 04:49:30 +00001319#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001321#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 *(char **)ptr = (char *)PyLong_AsUnsignedLongMask(value);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001323#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 _RET(value);
1325 }
1326 PyErr_Format(PyExc_TypeError,
Ezio Melottiacd5f7b2012-01-18 05:42:39 +02001327 "bytes or integer address expected instead of %s instance",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 value->ob_type->tp_name);
1329 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001330}
1331
1332static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001333z_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 /* XXX What about invalid pointers ??? */
1336 if (*(void **)ptr) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 return PyBytes_FromStringAndSize(*(char **)ptr,
1338 strlen(*(char **)ptr));
1339 } else {
1340 Py_INCREF(Py_None);
1341 return Py_None;
1342 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001343}
1344
1345#ifdef CTYPES_UNICODE
1346static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001347Z_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001348{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001349 PyObject *keep;
1350 wchar_t *buffer;
1351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001352 if (value == Py_None) {
1353 *(wchar_t **)ptr = NULL;
1354 Py_INCREF(value);
1355 return value;
1356 }
Martin Panterf0c03182015-12-12 06:57:13 +00001357 if (PyLong_Check(value)) {
Thomas Wouters89f507f2006-12-13 04:49:30 +00001358#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongLongMask(value);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001360#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongMask(value);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001362#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 Py_INCREF(Py_None);
1364 return Py_None;
1365 }
Victor Stinnercf448832010-07-28 00:15:03 +00001366 if (!PyUnicode_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 PyErr_Format(PyExc_TypeError,
1368 "unicode string or integer address expected instead of %s instance",
1369 value->ob_type->tp_name);
1370 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001372
1373 /* We must create a wchar_t* buffer from the unicode object,
1374 and keep it alive */
1375 buffer = PyUnicode_AsWideCharString(value, NULL);
1376 if (!buffer)
1377 return NULL;
1378 keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);
1379 if (!keep) {
1380 PyMem_Free(buffer);
1381 return NULL;
1382 }
1383 *(wchar_t **)ptr = buffer;
1384 return keep;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001385}
1386
1387static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001388Z_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001389{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 wchar_t *p;
1391 p = *(wchar_t **)ptr;
1392 if (p) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 return PyUnicode_FromWideChar(p, wcslen(p));
1394 } else {
1395 Py_INCREF(Py_None);
1396 return Py_None;
1397 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001398}
1399#endif
1400
1401#ifdef MS_WIN32
1402static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001403BSTR_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 BSTR bstr;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 /* convert value into a PyUnicodeObject or NULL */
1408 if (Py_None == value) {
1409 value = NULL;
Serhiy Storchakaadef6462016-06-16 22:08:46 +03001410 } else if (!PyUnicode_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001411 PyErr_Format(PyExc_TypeError,
1412 "unicode string expected instead of %s instance",
1413 value->ob_type->tp_name);
1414 return NULL;
1415 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 /* create a BSTR from value */
1418 if (value) {
Victor Stinner33354472011-11-21 02:01:41 +01001419 wchar_t* wvalue;
Steve Doweref42dae2015-03-24 23:28:54 -07001420 Py_ssize_t wsize;
1421 wvalue = PyUnicode_AsUnicodeAndSize(value, &wsize);
Victor Stinnerea90e0f2011-11-21 02:11:26 +01001422 if (wvalue == NULL)
1423 return NULL;
Steve Doweref42dae2015-03-24 23:28:54 -07001424 if ((unsigned) wsize != wsize) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 PyErr_SetString(PyExc_ValueError, "String too long for BSTR");
1426 return NULL;
1427 }
Steve Doweref42dae2015-03-24 23:28:54 -07001428 bstr = SysAllocStringLen(wvalue, (unsigned)wsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001429 } else
1430 bstr = NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 /* free the previous contents, if any */
1433 if (*(BSTR *)ptr)
1434 SysFreeString(*(BSTR *)ptr);
Guido van Rossumd8faa362007-04-27 19:54:29 +00001435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 /* and store it */
1437 *(BSTR *)ptr = bstr;
1438
1439 /* We don't need to keep any other object */
1440 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001441}
1442
1443
1444static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001445BSTR_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001446{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 BSTR p;
1448 p = *(BSTR *)ptr;
1449 if (p)
1450 return PyUnicode_FromWideChar(p, SysStringLen(p));
1451 else {
1452 /* Hm, it seems NULL pointer and zero length string are the
1453 same in BSTR, see Don Box, p 81
1454 */
1455 Py_INCREF(Py_None);
1456 return Py_None;
1457 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001458}
1459#endif
1460
1461static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001462P_set(void *ptr, PyObject *value, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001463{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 void *v;
1465 if (value == Py_None) {
1466 *(void **)ptr = NULL;
1467 _RET(value);
1468 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001469
Martin Panterf0c03182015-12-12 06:57:13 +00001470 if (!PyLong_Check(value)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 PyErr_SetString(PyExc_TypeError,
1472 "cannot be converted to pointer");
1473 return NULL;
1474 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001475
1476#if SIZEOF_VOID_P <= SIZEOF_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 v = (void *)PyLong_AsUnsignedLongMask(value);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001478#else
Benjamin Petersoned4aa832016-09-05 17:44:18 -07001479#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
Benjamin Peterson47ff0732016-09-08 09:15:54 -07001480# error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)"
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001481#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 v = (void *)PyLong_AsUnsignedLongLongMask(value);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001483#endif
1484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 if (PyErr_Occurred())
1486 return NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 *(void **)ptr = v;
1489 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001490}
1491
1492static PyObject *
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001493P_get(void *ptr, Py_ssize_t size)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 if (*(void **)ptr == NULL) {
1496 Py_INCREF(Py_None);
1497 return Py_None;
1498 }
1499 return PyLong_FromVoidPtr(*(void **)ptr);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001500}
1501
1502static struct fielddesc formattable[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 { 's', s_set, s_get, &ffi_type_pointer},
1504 { 'b', b_set, b_get, &ffi_type_schar},
1505 { 'B', B_set, B_get, &ffi_type_uchar},
1506 { 'c', c_set, c_get, &ffi_type_schar},
1507 { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw},
1508 { 'g', g_set, g_get, &ffi_type_longdouble},
1509 { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw},
1510 { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw},
1511 { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw},
1512 { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw},
1513 { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw},
Thomas Hellerd4c93202006-03-08 19:35:11 +00001514/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
1515/* As soon as we can get rid of the type codes, this is no longer a problem */
1516#if SIZEOF_LONG == 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 { 'l', l_set, l_get, &ffi_type_sint32, l_set_sw, l_get_sw},
1518 { 'L', L_set, L_get, &ffi_type_uint32, L_set_sw, L_get_sw},
Thomas Hellerd4c93202006-03-08 19:35:11 +00001519#elif SIZEOF_LONG == 8
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 { 'l', l_set, l_get, &ffi_type_sint64, l_set_sw, l_get_sw},
1521 { 'L', L_set, L_get, &ffi_type_uint64, L_set_sw, L_get_sw},
Thomas Hellerd4c93202006-03-08 19:35:11 +00001522#else
1523# error
1524#endif
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001525#if SIZEOF_LONG_LONG == 8
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001526 { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw},
1527 { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw},
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001528#else
1529# error
1530#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 { 'P', P_set, P_get, &ffi_type_pointer},
1532 { 'z', z_set, z_get, &ffi_type_pointer},
Thomas Hellerd4c93202006-03-08 19:35:11 +00001533#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 { 'u', u_set, u_get, NULL}, /* ffi_type set later */
1535 { 'U', U_set, U_get, &ffi_type_pointer},
1536 { 'Z', Z_set, Z_get, &ffi_type_pointer},
Thomas Hellerd4c93202006-03-08 19:35:11 +00001537#endif
1538#ifdef MS_WIN32
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 { 'X', BSTR_set, BSTR_get, &ffi_type_pointer},
1540 { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort},
Thomas Hellerd4c93202006-03-08 19:35:11 +00001541#endif
Guido van Rossumd8faa362007-04-27 19:54:29 +00001542#if SIZEOF__BOOL == 1
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 { '?', bool_set, bool_get, &ffi_type_uchar}, /* Also fallback for no native _Bool support */
Guido van Rossumd8faa362007-04-27 19:54:29 +00001544#elif SIZEOF__BOOL == SIZEOF_SHORT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 { '?', bool_set, bool_get, &ffi_type_ushort},
Guido van Rossumd8faa362007-04-27 19:54:29 +00001546#elif SIZEOF__BOOL == SIZEOF_INT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 { '?', bool_set, bool_get, &ffi_type_uint, I_set_sw, I_get_sw},
Guido van Rossumd8faa362007-04-27 19:54:29 +00001548#elif SIZEOF__BOOL == SIZEOF_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 { '?', bool_set, bool_get, &ffi_type_ulong, L_set_sw, L_get_sw},
Guido van Rossumd8faa362007-04-27 19:54:29 +00001550#elif SIZEOF__BOOL == SIZEOF_LONG_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 { '?', bool_set, bool_get, &ffi_type_ulong, Q_set_sw, Q_get_sw},
Guido van Rossumd8faa362007-04-27 19:54:29 +00001552#endif /* SIZEOF__BOOL */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 { 'O', O_set, O_get, &ffi_type_pointer},
1554 { 0, NULL, NULL, NULL},
Thomas Hellerd4c93202006-03-08 19:35:11 +00001555};
1556
1557/*
1558 Ideas: Implement VARIANT in this table, using 'V' code.
1559 Use '?' as code for BOOL.
1560*/
1561
1562struct fielddesc *
Thomas Heller34596a92009-04-24 20:50:00 +00001563_ctypes_get_fielddesc(const char *fmt)
Thomas Hellerd4c93202006-03-08 19:35:11 +00001564{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 static int initialized = 0;
1566 struct fielddesc *table = formattable;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 if (!initialized) {
1569 initialized = 1;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001570#ifdef CTYPES_UNICODE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 if (sizeof(wchar_t) == sizeof(short))
1572 _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort;
1573 else if (sizeof(wchar_t) == sizeof(int))
1574 _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint;
1575 else if (sizeof(wchar_t) == sizeof(long))
1576 _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001577#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 }
Thomas Hellerd4c93202006-03-08 19:35:11 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 for (; table->code; ++table) {
1581 if (table->code == fmt[0])
1582 return table;
1583 }
1584 return NULL;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001585}
1586
1587typedef struct { char c; char x; } s_char;
1588typedef struct { char c; short x; } s_short;
1589typedef struct { char c; int x; } s_int;
1590typedef struct { char c; long x; } s_long;
1591typedef struct { char c; float x; } s_float;
1592typedef struct { char c; double x; } s_double;
Thomas Wouters89d996e2007-09-08 17:39:28 +00001593typedef struct { char c; long double x; } s_long_double;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001594typedef struct { char c; char *x; } s_char_p;
1595typedef struct { char c; void *x; } s_void_p;
1596
1597/*
1598#define CHAR_ALIGN (sizeof(s_char) - sizeof(char))
1599#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
Thomas Hellerd4c93202006-03-08 19:35:11 +00001600#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
1601*/
Benjamin Petersonfda33552014-03-16 10:07:26 +01001602#define INT_ALIGN (sizeof(s_int) - sizeof(int))
Thomas Hellerd4c93202006-03-08 19:35:11 +00001603#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
1604#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
Thomas Wouters89d996e2007-09-08 17:39:28 +00001605#define LONGDOUBLE_ALIGN (sizeof(s_long_double) - sizeof(long double))
1606
Thomas Hellerd4c93202006-03-08 19:35:11 +00001607/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */
1608#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*))
1609
1610/*
1611#ifdef HAVE_USABLE_WCHAR_T
1612typedef struct { char c; wchar_t x; } s_wchar;
1613typedef struct { char c; wchar_t *x; } s_wchar_p;
1614
1615#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t))
1616#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*))
1617#endif
1618*/
1619
Benjamin Peterson47ff0732016-09-08 09:15:54 -07001620typedef struct { char c; long long x; } s_long_long;
1621#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
Thomas Hellerd4c93202006-03-08 19:35:11 +00001622
1623/* from ffi.h:
1624typedef struct _ffi_type
1625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 size_t size;
1627 unsigned short alignment;
1628 unsigned short type;
1629 struct _ffi_type **elements;
Thomas Hellerd4c93202006-03-08 19:35:11 +00001630} ffi_type;
1631*/
1632
1633/* align and size are bogus for void, but they must not be zero */
1634ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
1635
1636ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
1637ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
1638
1639ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
1640ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
1641
Benjamin Petersonfda33552014-03-16 10:07:26 +01001642ffi_type ffi_type_uint32 = { 4, INT_ALIGN, FFI_TYPE_UINT32 };
1643ffi_type ffi_type_sint32 = { 4, INT_ALIGN, FFI_TYPE_SINT32 };
Thomas Hellerd4c93202006-03-08 19:35:11 +00001644
1645ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
1646ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
1647
1648ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
1649ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001650
1651#ifdef ffi_type_longdouble
1652#undef ffi_type_longdouble
1653#endif
Georg Brandlfcaf9102008-07-16 02:17:56 +00001654 /* This is already defined on OSX */
Thomas Wouters89d996e2007-09-08 17:39:28 +00001655ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 FFI_TYPE_LONGDOUBLE };
Thomas Hellerd4c93202006-03-08 19:35:11 +00001657
Thomas Hellerd4c93202006-03-08 19:35:11 +00001658ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
1659
1660/*---------------- EOF ----------------*/