1#include "Python.h"
2#include "pycore_bitutils.h" // _Py_bswap32()
3
4#include <ffi.h>
5#ifdef MS_WIN32
6#include <windows.h>
7#endif
8#include "ctypes.h"
9
10
11#define CTYPES_CFIELD_CAPSULE_NAME_PYMEM "_ctypes/cfield.c pymem"
12
13static void pymem_destructor(PyObject *ptr)
14{
15 void *p = PyCapsule_GetPointer(ptr, CTYPES_CFIELD_CAPSULE_NAME_PYMEM);
16 if (p) {
17 PyMem_Free(p);
18 }
19}
20
21
22/******************************************************************/
23/*
24 PyCField_Type
25*/
26static PyObject *
27PyCField_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
28{
29 CFieldObject *obj;
30 obj = (CFieldObject *)type->tp_alloc(type, 0);
31 return (PyObject *)obj;
32}
33
34/*
35 * Expects the size, index and offset for the current field in *psize and
36 * *poffset, stores the total size so far in *psize, the offset for the next
37 * field in *poffset, the alignment requirements for the current field in
38 * *palign, and returns a field descriptor for this field.
39 */
40/*
41 * bitfields extension:
42 * bitsize != 0: this is a bit field.
43 * pbitofs points to the current bit offset, this will be updated.
44 * prev_desc points to the type of the previous bitfield, if any.
45 */
46PyObject *
47PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
48 Py_ssize_t *pfield_size, int bitsize, int *pbitofs,
49 Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign,
50 int pack, int big_endian)
51{
52 CFieldObject *self;
53 PyObject *proto;
54 Py_ssize_t size, align;
55 SETFUNC setfunc = NULL;
56 GETFUNC getfunc = NULL;
57 StgDictObject *dict;
58 int fieldtype;
59#define NO_BITFIELD 0
60#define NEW_BITFIELD 1
61#define CONT_BITFIELD 2
62#define EXPAND_BITFIELD 3
63
64 self = (CFieldObject *)_PyObject_CallNoArg((PyObject *)&PyCField_Type);
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 */
76#ifdef MS_WIN32
77 /* MSVC, GCC with -mms-bitfields */
78 && dict->size * 8 == *pfield_size
79#else
80 /* GCC */
81 && dict->size * 8 <= *pfield_size
82#endif
83 && (*pbitofs + bitsize) <= *pfield_size) {
84 /* continue bit field */
85 fieldtype = CONT_BITFIELD;
86#ifndef MS_WIN32
87 } 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;
93#endif
94 } 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 }
105
106 size = dict->size;
107 proto = desc;
108
109 /* 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 }
128 if (idict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
129 struct fielddesc *fd = _ctypes_get_fielddesc("U");
130 getfunc = fd->getfunc;
131 setfunc = fd->setfunc;
132 }
133 }
134 }
135
136 self->setfunc = setfunc;
137 self->getfunc = getfunc;
138 self->index = index;
139
140 Py_INCREF(proto);
141 self->proto = proto;
142
143 switch (fieldtype) {
144 case NEW_BITFIELD:
145 if (big_endian)
146 self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
147 else
148 self->size = (bitsize << 16) + *pbitofs;
149 *pbitofs = bitsize;
150 /* fall through */
151 case NO_BITFIELD:
152 if (pack)
153 align = min(pack, dict->align);
154 else
155 align = dict->align;
156 if (align && *poffset % align) {
157 Py_ssize_t delta = align - (*poffset % align);
158 *psize += delta;
159 *poffset += delta;
160 }
161
162 if (bitsize == 0)
163 self->size = size;
164 *psize += size;
165
166 self->offset = *poffset;
167 *poffset += size;
168
169 *palign = align;
170 break;
171
172 case EXPAND_BITFIELD:
173 *poffset += dict->size - *pfield_size/8;
174 *psize += dict->size - *pfield_size/8;
175
176 *pfield_size = dict->size * 8;
177
178 if (big_endian)
179 self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
180 else
181 self->size = (bitsize << 16) + *pbitofs;
182
183 self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
184 *pbitofs += bitsize;
185 break;
186
187 case CONT_BITFIELD:
188 if (big_endian)
189 self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
190 else
191 self->size = (bitsize << 16) + *pbitofs;
192
193 self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
194 *pbitofs += bitsize;
195 break;
196 }
197
198 return (PyObject *)self;
199}
200
201static int
202PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
203{
204 CDataObject *dst;
205 char *ptr;
206 if (!CDataObject_Check(inst)) {
207 PyErr_SetString(PyExc_TypeError,
208 "not a ctype instance");
209 return -1;
210 }
211 dst = (CDataObject *)inst;
212 ptr = dst->b_ptr + self->offset;
213 if (value == NULL) {
214 PyErr_SetString(PyExc_TypeError,
215 "can't delete attribute");
216 return -1;
217 }
218 return PyCData_set(inst, self->proto, self->setfunc, value,
219 self->index, self->size, ptr);
220}
221
222static PyObject *
223PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
224{
225 CDataObject *src;
226 if (inst == NULL) {
227 Py_INCREF(self);
228 return (PyObject *)self;
229 }
230 if (!CDataObject_Check(inst)) {
231 PyErr_SetString(PyExc_TypeError,
232 "not a ctype instance");
233 return NULL;
234 }
235 src = (CDataObject *)inst;
236 return PyCData_get(self->proto, self->getfunc, inst,
237 self->index, self->size, src->b_ptr + self->offset);
238}
239
240static PyObject *
241PyCField_get_offset(PyObject *self, void *data)
242{
243 return PyLong_FromSsize_t(((CFieldObject *)self)->offset);
244}
245
246static PyObject *
247PyCField_get_size(PyObject *self, void *data)
248{
249 return PyLong_FromSsize_t(((CFieldObject *)self)->size);
250}
251
252static PyGetSetDef PyCField_getset[] = {
253 { "offset", PyCField_get_offset, NULL, "offset in bytes of this field" },
254 { "size", PyCField_get_size, NULL, "size in bytes of this field" },
255 { NULL, NULL, NULL, NULL },
256};
257
258static int
259PyCField_traverse(CFieldObject *self, visitproc visit, void *arg)
260{
261 Py_VISIT(self->proto);
262 return 0;
263}
264
265static int
266PyCField_clear(CFieldObject *self)
267{
268 Py_CLEAR(self->proto);
269 return 0;
270}
271
272static void
273PyCField_dealloc(PyObject *self)
274{
275 PyCField_clear((CFieldObject *)self);
276 Py_TYPE(self)->tp_free((PyObject *)self);
277}
278
279static PyObject *
280PyCField_repr(CFieldObject *self)
281{
282 PyObject *result;
283 Py_ssize_t bits = self->size >> 16;
284 Py_ssize_t size = self->size & 0xFFFF;
285 const char *name;
286
287 name = ((PyTypeObject *)self->proto)->tp_name;
288
289 if (bits)
290 result = PyUnicode_FromFormat(
291 "<Field type=%s, ofs=%zd:%zd, bits=%zd>",
292 name, self->offset, size, bits);
293 else
294 result = PyUnicode_FromFormat(
295 "<Field type=%s, ofs=%zd, size=%zd>",
296 name, self->offset, size);
297 return result;
298}
299
300PyTypeObject PyCField_Type = {
301 PyVarObject_HEAD_INIT(NULL, 0)
302 "_ctypes.CField", /* tp_name */
303 sizeof(CFieldObject), /* tp_basicsize */
304 0, /* tp_itemsize */
305 PyCField_dealloc, /* tp_dealloc */
306 0, /* tp_vectorcall_offset */
307 0, /* tp_getattr */
308 0, /* tp_setattr */
309 0, /* tp_as_async */
310 (reprfunc)PyCField_repr, /* tp_repr */
311 0, /* tp_as_number */
312 0, /* tp_as_sequence */
313 0, /* tp_as_mapping */
314 0, /* tp_hash */
315 0, /* tp_call */
316 0, /* tp_str */
317 0, /* tp_getattro */
318 0, /* tp_setattro */
319 0, /* tp_as_buffer */
320 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
321 PyDoc_STR("Structure/Union member"), /* tp_doc */
322 (traverseproc)PyCField_traverse, /* tp_traverse */
323 (inquiry)PyCField_clear, /* tp_clear */
324 0, /* tp_richcompare */
325 0, /* tp_weaklistoffset */
326 0, /* tp_iter */
327 0, /* tp_iternext */
328 0, /* tp_methods */
329 0, /* tp_members */
330 PyCField_getset, /* tp_getset */
331 0, /* tp_base */
332 0, /* tp_dict */
333 (descrgetfunc)PyCField_get, /* tp_descr_get */
334 (descrsetfunc)PyCField_set, /* tp_descr_set */
335 0, /* tp_dictoffset */
336 0, /* tp_init */
337 0, /* tp_alloc */
338 PyCField_new, /* tp_new */
339 0, /* tp_free */
340};
341
342
343/******************************************************************/
344/*
345 Accessor functions
346*/
347
348/* Derived from Modules/structmodule.c:
349 Helper routine to get a Python integer and raise the appropriate error
350 if it isn't one */
351
352static int
353get_long(PyObject *v, long *p)
354{
355 long x = PyLong_AsUnsignedLongMask(v);
356 if (x == -1 && PyErr_Occurred())
357 return -1;
358 *p = x;
359 return 0;
360}
361
362/* Same, but handling unsigned long */
363
364static int
365get_ulong(PyObject *v, unsigned long *p)
366{
367 unsigned long x = PyLong_AsUnsignedLongMask(v);
368 if (x == (unsigned long)-1 && PyErr_Occurred())
369 return -1;
370 *p = x;
371 return 0;
372}
373
374/* Same, but handling native long long. */
375
376static int
377get_longlong(PyObject *v, long long *p)
378{
379 long long x = PyLong_AsUnsignedLongLongMask(v);
380 if (x == -1 && PyErr_Occurred())
381 return -1;
382 *p = x;
383 return 0;
384}
385
386/* Same, but handling native unsigned long long. */
387
388static int
389get_ulonglong(PyObject *v, unsigned long long *p)
390{
391 unsigned long long x = PyLong_AsUnsignedLongLongMask(v);
392 if (x == (unsigned long long)-1 && PyErr_Occurred())
393 return -1;
394 *p = x;
395 return 0;
396}
397
398/*****************************************************************
399 * Integer fields, with bitfield support
400 */
401
402/* how to decode the size field, for integer get/set functions */
403#define LOW_BIT(x) ((x) & 0xFFFF)
404#define NUM_BITS(x) ((x) >> 16)
405
406/* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */
407#define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1)
408
409/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
410 we must first shift left, then right.
411*/
412#define GET_BITFIELD(v, size) \
413 if (NUM_BITS(size)) { \
414 v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \
415 v >>= (sizeof(v)*8 - NUM_BITS(size)); \
416 }
417
418/* This macro RETURNS the first parameter with the bit field CHANGED. */
419#define SET(type, x, v, size) \
420 (NUM_BITS(size) ? \
421 ( ( (type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type, size)) << LOW_BIT(size) ) ) \
422 : (type)v)
423
424#if SIZEOF_SHORT == 2
425# define SWAP_SHORT _Py_bswap16
426#else
427# error "unsupported short size"
428#endif
429
430#if SIZEOF_INT == 4
431# define SWAP_INT _Py_bswap32
432#else
433# error "unsupported int size"
434#endif
435
436#if SIZEOF_LONG == 4
437# define SWAP_LONG _Py_bswap32
438#elif SIZEOF_LONG == 8
439# define SWAP_LONG _Py_bswap64
440#else
441# error "unsupported long size"
442#endif
443
444#if SIZEOF_LONG_LONG == 8
445# define SWAP_LONG_LONG _Py_bswap64
446#else
447# error "unsupported long long size"
448#endif
449
450/*****************************************************************
451 * The setter methods return an object which must be kept alive, to keep the
452 * data valid which has been stored in the memory block. The ctypes object
453 * instance inserts this object into its 'b_objects' list.
454 *
455 * For simple Python types like integers or characters, there is nothing that
456 * has to been kept alive, so Py_None is returned in these cases. But this
457 * makes inspecting the 'b_objects' list, which is accessible from Python for
458 * debugging, less useful.
459 *
460 * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value
461 * instead of Py_None.
462 */
463
464#ifdef _CTYPES_DEBUG_KEEP
465#define _RET(x) Py_INCREF(x); return x
466#else
467#define _RET(X) Py_RETURN_NONE
468#endif
469
470/*****************************************************************
471 * integer accessor methods, supporting bit fields
472 */
473
474static PyObject *
475b_set(void *ptr, PyObject *value, Py_ssize_t size)
476{
477 long val;
478 if (get_long(value, &val) < 0)
479 return NULL;
480 *(signed char *)ptr = SET(signed char, *(signed char *)ptr, val, size);
481 _RET(value);
482}
483
484
485static PyObject *
486b_get(void *ptr, Py_ssize_t size)
487{
488 signed char val = *(signed char *)ptr;
489 GET_BITFIELD(val, size);
490 return PyLong_FromLong(val);
491}
492
493static PyObject *
494B_set(void *ptr, PyObject *value, Py_ssize_t size)
495{
496 unsigned long val;
497 if (get_ulong(value, &val) < 0)
498 return NULL;
499 *(unsigned char *)ptr = SET(unsigned char, *(unsigned char*)ptr, val, size);
500 _RET(value);
501}
502
503
504static PyObject *
505B_get(void *ptr, Py_ssize_t size)
506{
507 unsigned char val = *(unsigned char *)ptr;
508 GET_BITFIELD(val, size);
509 return PyLong_FromLong(val);
510}
511
512static PyObject *
513h_set(void *ptr, PyObject *value, Py_ssize_t size)
514{
515 long val;
516 short x;
517 if (get_long(value, &val) < 0)
518 return NULL;
519 memcpy(&x, ptr, sizeof(x));
520 x = SET(short, x, val, size);
521 memcpy(ptr, &x, sizeof(x));
522 _RET(value);
523}
524
525
526static PyObject *
527h_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
528{
529 long val;
530 short field;
531 if (get_long(value, &val) < 0) {
532 return NULL;
533 }
534 memcpy(&field, ptr, sizeof(field));
535 field = SWAP_SHORT(field);
536 field = SET(short, field, val, size);
537 field = SWAP_SHORT(field);
538 memcpy(ptr, &field, sizeof(field));
539 _RET(value);
540}
541
542static PyObject *
543h_get(void *ptr, Py_ssize_t size)
544{
545 short val;
546 memcpy(&val, ptr, sizeof(val));
547 GET_BITFIELD(val, size);
548 return PyLong_FromLong((long)val);
549}
550
551static PyObject *
552h_get_sw(void *ptr, Py_ssize_t size)
553{
554 short val;
555 memcpy(&val, ptr, sizeof(val));
556 val = SWAP_SHORT(val);
557 GET_BITFIELD(val, size);
558 return PyLong_FromLong(val);
559}
560
561static PyObject *
562H_set(void *ptr, PyObject *value, Py_ssize_t size)
563{
564 unsigned long val;
565 unsigned short x;
566 if (get_ulong(value, &val) < 0)
567 return NULL;
568 memcpy(&x, ptr, sizeof(x));
569 x = SET(unsigned short, x, val, size);
570 memcpy(ptr, &x, sizeof(x));
571 _RET(value);
572}
573
574static PyObject *
575H_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
576{
577 unsigned long val;
578 unsigned short field;
579 if (get_ulong(value, &val) < 0) {
580 return NULL;
581 }
582 memcpy(&field, ptr, sizeof(field));
583 field = SWAP_SHORT(field);
584 field = SET(unsigned short, field, val, size);
585 field = SWAP_SHORT(field);
586 memcpy(ptr, &field, sizeof(field));
587 _RET(value);
588}
589
590
591static PyObject *
592H_get(void *ptr, Py_ssize_t size)
593{
594 unsigned short val;
595 memcpy(&val, ptr, sizeof(val));
596 GET_BITFIELD(val, size);
597 return PyLong_FromLong(val);
598}
599
600static PyObject *
601H_get_sw(void *ptr, Py_ssize_t size)
602{
603 unsigned short val;
604 memcpy(&val, ptr, sizeof(val));
605 val = SWAP_SHORT(val);
606 GET_BITFIELD(val, size);
607 return PyLong_FromLong(val);
608}
609
610static PyObject *
611i_set(void *ptr, PyObject *value, Py_ssize_t size)
612{
613 long val;
614 int x;
615 if (get_long(value, &val) < 0)
616 return NULL;
617 memcpy(&x, ptr, sizeof(x));
618 x = SET(int, x, val, size);
619 memcpy(ptr, &x, sizeof(x));
620 _RET(value);
621}
622
623static PyObject *
624i_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
625{
626 long val;
627 int field;
628 if (get_long(value, &val) < 0) {
629 return NULL;
630 }
631 memcpy(&field, ptr, sizeof(field));
632 field = SWAP_INT(field);
633 field = SET(int, field, val, size);
634 field = SWAP_INT(field);
635 memcpy(ptr, &field, sizeof(field));
636 _RET(value);
637}
638
639
640static PyObject *
641i_get(void *ptr, Py_ssize_t size)
642{
643 int val;
644 memcpy(&val, ptr, sizeof(val));
645 GET_BITFIELD(val, size);
646 return PyLong_FromLong(val);
647}
648
649static PyObject *
650i_get_sw(void *ptr, Py_ssize_t size)
651{
652 int val;
653 memcpy(&val, ptr, sizeof(val));
654 val = SWAP_INT(val);
655 GET_BITFIELD(val, size);
656 return PyLong_FromLong(val);
657}
658
659#ifndef MS_WIN32
660/* http://msdn.microsoft.com/en-us/library/cc237864.aspx */
661#define VARIANT_FALSE 0x0000
662#define VARIANT_TRUE 0xFFFF
663#endif
664/* short BOOL - VARIANT_BOOL */
665static PyObject *
666vBOOL_set(void *ptr, PyObject *value, Py_ssize_t size)
667{
668 switch (PyObject_IsTrue(value)) {
669 case -1:
670 return NULL;
671 case 0:
672 *(short int *)ptr = VARIANT_FALSE;
673 _RET(value);
674 default:
675 *(short int *)ptr = VARIANT_TRUE;
676 _RET(value);
677 }
678}
679
680static PyObject *
681vBOOL_get(void *ptr, Py_ssize_t size)
682{
683 return PyBool_FromLong((long)*(short int *)ptr);
684}
685
686static PyObject *
687bool_set(void *ptr, PyObject *value, Py_ssize_t size)
688{
689 switch (PyObject_IsTrue(value)) {
690 case -1:
691 return NULL;
692 case 0:
693 *(_Bool *)ptr = 0;
694 _RET(value);
695 default:
696 *(_Bool *)ptr = 1;
697 _RET(value);
698 }
699}
700
701static PyObject *
702bool_get(void *ptr, Py_ssize_t size)
703{
704 return PyBool_FromLong((long)*(_Bool *)ptr);
705}
706
707static PyObject *
708I_set(void *ptr, PyObject *value, Py_ssize_t size)
709{
710 unsigned long val;
711 unsigned int x;
712 if (get_ulong(value, &val) < 0)
713 return NULL;
714 memcpy(&x, ptr, sizeof(x));
715 x = SET(unsigned int, x, val, size);
716 memcpy(ptr, &x, sizeof(x));
717 _RET(value);
718}
719
720static PyObject *
721I_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
722{
723 unsigned long val;
724 unsigned int field;
725 if (get_ulong(value, &val) < 0) {
726 return NULL;
727 }
728 memcpy(&field, ptr, sizeof(field));
729 field = SWAP_INT(field);
730 field = SET(unsigned int, field, (unsigned int)val, size);
731 field = SWAP_INT(field);
732 memcpy(ptr, &field, sizeof(field));
733 _RET(value);
734}
735
736
737static PyObject *
738I_get(void *ptr, Py_ssize_t size)
739{
740 unsigned int val;
741 memcpy(&val, ptr, sizeof(val));
742 GET_BITFIELD(val, size);
743 return PyLong_FromUnsignedLong(val);
744}
745
746static PyObject *
747I_get_sw(void *ptr, Py_ssize_t size)
748{
749 unsigned int val;
750 memcpy(&val, ptr, sizeof(val));
751 val = SWAP_INT(val);
752 GET_BITFIELD(val, size);
753 return PyLong_FromUnsignedLong(val);
754}
755
756static PyObject *
757l_set(void *ptr, PyObject *value, Py_ssize_t size)
758{
759 long val;
760 long x;
761 if (get_long(value, &val) < 0)
762 return NULL;
763 memcpy(&x, ptr, sizeof(x));
764 x = SET(long, x, val, size);
765 memcpy(ptr, &x, sizeof(x));
766 _RET(value);
767}
768
769static PyObject *
770l_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
771{
772 long val;
773 long field;
774 if (get_long(value, &val) < 0) {
775 return NULL;
776 }
777 memcpy(&field, ptr, sizeof(field));
778 field = SWAP_LONG(field);
779 field = SET(long, field, val, size);
780 field = SWAP_LONG(field);
781 memcpy(ptr, &field, sizeof(field));
782 _RET(value);
783}
784
785
786static PyObject *
787l_get(void *ptr, Py_ssize_t size)
788{
789 long val;
790 memcpy(&val, ptr, sizeof(val));
791 GET_BITFIELD(val, size);
792 return PyLong_FromLong(val);
793}
794
795static PyObject *
796l_get_sw(void *ptr, Py_ssize_t size)
797{
798 long val;
799 memcpy(&val, ptr, sizeof(val));
800 val = SWAP_LONG(val);
801 GET_BITFIELD(val, size);
802 return PyLong_FromLong(val);
803}
804
805static PyObject *
806L_set(void *ptr, PyObject *value, Py_ssize_t size)
807{
808 unsigned long val;
809 unsigned long x;
810 if (get_ulong(value, &val) < 0)
811 return NULL;
812 memcpy(&x, ptr, sizeof(x));
813 x = SET(unsigned long, x, val, size);
814 memcpy(ptr, &x, sizeof(x));
815 _RET(value);
816}
817
818static PyObject *
819L_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
820{
821 unsigned long val;
822 unsigned long field;
823 if (get_ulong(value, &val) < 0) {
824 return NULL;
825 }
826 memcpy(&field, ptr, sizeof(field));
827 field = SWAP_LONG(field);
828 field = SET(unsigned long, field, val, size);
829 field = SWAP_LONG(field);
830 memcpy(ptr, &field, sizeof(field));
831 _RET(value);
832}
833
834
835static PyObject *
836L_get(void *ptr, Py_ssize_t size)
837{
838 unsigned long val;
839 memcpy(&val, ptr, sizeof(val));
840 GET_BITFIELD(val, size);
841 return PyLong_FromUnsignedLong(val);
842}
843
844static PyObject *
845L_get_sw(void *ptr, Py_ssize_t size)
846{
847 unsigned long val;
848 memcpy(&val, ptr, sizeof(val));
849 val = SWAP_LONG(val);
850 GET_BITFIELD(val, size);
851 return PyLong_FromUnsignedLong(val);
852}
853
854static PyObject *
855q_set(void *ptr, PyObject *value, Py_ssize_t size)
856{
857 long long val;
858 long long x;
859 if (get_longlong(value, &val) < 0)
860 return NULL;
861 memcpy(&x, ptr, sizeof(x));
862 x = SET(long long, x, val, size);
863 memcpy(ptr, &x, sizeof(x));
864 _RET(value);
865}
866
867static PyObject *
868q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
869{
870 long long val;
871 long long field;
872 if (get_longlong(value, &val) < 0) {
873 return NULL;
874 }
875 memcpy(&field, ptr, sizeof(field));
876 field = SWAP_LONG_LONG(field);
877 field = SET(long long, field, val, size);
878 field = SWAP_LONG_LONG(field);
879 memcpy(ptr, &field, sizeof(field));
880 _RET(value);
881}
882
883static PyObject *
884q_get(void *ptr, Py_ssize_t size)
885{
886 long long val;
887 memcpy(&val, ptr, sizeof(val));
888 GET_BITFIELD(val, size);
889 return PyLong_FromLongLong(val);
890}
891
892static PyObject *
893q_get_sw(void *ptr, Py_ssize_t size)
894{
895 long long val;
896 memcpy(&val, ptr, sizeof(val));
897 val = SWAP_LONG_LONG(val);
898 GET_BITFIELD(val, size);
899 return PyLong_FromLongLong(val);
900}
901
902static PyObject *
903Q_set(void *ptr, PyObject *value, Py_ssize_t size)
904{
905 unsigned long long val;
906 unsigned long long x;
907 if (get_ulonglong(value, &val) < 0)
908 return NULL;
909 memcpy(&x, ptr, sizeof(x));
910 x = SET(long long, x, val, size);
911 memcpy(ptr, &x, sizeof(x));
912 _RET(value);
913}
914
915static PyObject *
916Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
917{
918 unsigned long long val;
919 unsigned long long field;
920 if (get_ulonglong(value, &val) < 0) {
921 return NULL;
922 }
923 memcpy(&field, ptr, sizeof(field));
924 field = SWAP_LONG_LONG(field);
925 field = SET(unsigned long long, field, val, size);
926 field = SWAP_LONG_LONG(field);
927 memcpy(ptr, &field, sizeof(field));
928 _RET(value);
929}
930
931static PyObject *
932Q_get(void *ptr, Py_ssize_t size)
933{
934 unsigned long long val;
935 memcpy(&val, ptr, sizeof(val));
936 GET_BITFIELD(val, size);
937 return PyLong_FromUnsignedLongLong(val);
938}
939
940static PyObject *
941Q_get_sw(void *ptr, Py_ssize_t size)
942{
943 unsigned long long val;
944 memcpy(&val, ptr, sizeof(val));
945 val = SWAP_LONG_LONG(val);
946 GET_BITFIELD(val, size);
947 return PyLong_FromUnsignedLongLong(val);
948}
949
950/*****************************************************************
951 * non-integer accessor methods, not supporting bit fields
952 */
953
954
955static PyObject *
956g_set(void *ptr, PyObject *value, Py_ssize_t size)
957{
958 long double x;
959
960 x = PyFloat_AsDouble(value);
961 if (x == -1 && PyErr_Occurred())
962 return NULL;
963 memcpy(ptr, &x, sizeof(long double));
964 _RET(value);
965}
966
967static PyObject *
968g_get(void *ptr, Py_ssize_t size)
969{
970 long double val;
971 memcpy(&val, ptr, sizeof(long double));
972 return PyFloat_FromDouble(val);
973}
974
975static PyObject *
976d_set(void *ptr, PyObject *value, Py_ssize_t size)
977{
978 double x;
979
980 x = PyFloat_AsDouble(value);
981 if (x == -1 && PyErr_Occurred())
982 return NULL;
983 memcpy(ptr, &x, sizeof(double));
984 _RET(value);
985}
986
987static PyObject *
988d_get(void *ptr, Py_ssize_t size)
989{
990 double val;
991 memcpy(&val, ptr, sizeof(val));
992 return PyFloat_FromDouble(val);
993}
994
995static PyObject *
996d_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
997{
998 double x;
999
1000 x = PyFloat_AsDouble(value);
1001 if (x == -1 && PyErr_Occurred())
1002 return NULL;
1003#ifdef WORDS_BIGENDIAN
1004 if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1))
1005 return NULL;
1006#else
1007 if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0))
1008 return NULL;
1009#endif
1010 _RET(value);
1011}
1012
1013static PyObject *
1014d_get_sw(void *ptr, Py_ssize_t size)
1015{
1016#ifdef WORDS_BIGENDIAN
1017 return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1));
1018#else
1019 return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0));
1020#endif
1021}
1022
1023static PyObject *
1024f_set(void *ptr, PyObject *value, Py_ssize_t size)
1025{
1026 float x;
1027
1028 x = (float)PyFloat_AsDouble(value);
1029 if (x == -1 && PyErr_Occurred())
1030 return NULL;
1031 memcpy(ptr, &x, sizeof(x));
1032 _RET(value);
1033}
1034
1035static PyObject *
1036f_get(void *ptr, Py_ssize_t size)
1037{
1038 float val;
1039 memcpy(&val, ptr, sizeof(val));
1040 return PyFloat_FromDouble(val);
1041}
1042
1043static PyObject *
1044f_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
1045{
1046 float x;
1047
1048 x = (float)PyFloat_AsDouble(value);
1049 if (x == -1 && PyErr_Occurred())
1050 return NULL;
1051#ifdef WORDS_BIGENDIAN
1052 if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1))
1053 return NULL;
1054#else
1055 if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0))
1056 return NULL;
1057#endif
1058 _RET(value);
1059}
1060
1061static PyObject *
1062f_get_sw(void *ptr, Py_ssize_t size)
1063{
1064#ifdef WORDS_BIGENDIAN
1065 return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1));
1066#else
1067 return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0));
1068#endif
1069}
1070
1071/*
1072 py_object refcounts:
1073
1074 1. If we have a py_object instance, O_get must Py_INCREF the returned
1075 object, of course. If O_get is called from a function result, no py_object
1076 instance is created - so callproc.c::GetResult has to call Py_DECREF.
1077
1078 2. The memory block in py_object owns a refcount. So, py_object must call
1079 Py_DECREF on destruction. Maybe only when b_needsfree is non-zero.
1080*/
1081static PyObject *
1082O_get(void *ptr, Py_ssize_t size)
1083{
1084 PyObject *ob = *(PyObject **)ptr;
1085 if (ob == NULL) {
1086 if (!PyErr_Occurred())
1087 /* Set an error if not yet set */
1088 PyErr_SetString(PyExc_ValueError,
1089 "PyObject is NULL");
1090 return NULL;
1091 }
1092 Py_INCREF(ob);
1093 return ob;
1094}
1095
1096static PyObject *
1097O_set(void *ptr, PyObject *value, Py_ssize_t size)
1098{
1099 /* Hm, does the memory block need it's own refcount or not? */
1100 *(PyObject **)ptr = value;
1101 Py_INCREF(value);
1102 return value;
1103}
1104
1105
1106static PyObject *
1107c_set(void *ptr, PyObject *value, Py_ssize_t size)
1108{
1109 if (PyBytes_Check(value) && PyBytes_GET_SIZE(value) == 1) {
1110 *(char *)ptr = PyBytes_AS_STRING(value)[0];
1111 _RET(value);
1112 }
1113 if (PyByteArray_Check(value) && PyByteArray_GET_SIZE(value) == 1) {
1114 *(char *)ptr = PyByteArray_AS_STRING(value)[0];
1115 _RET(value);
1116 }
1117 if (PyLong_Check(value))
1118 {
1119 long longval = PyLong_AsLong(value);
1120 if (longval < 0 || longval >= 256)
1121 goto error;
1122 *(char *)ptr = (char)longval;
1123 _RET(value);
1124 }
1125 error:
1126 PyErr_Format(PyExc_TypeError,
1127 "one character bytes, bytearray or integer expected");
1128 return NULL;
1129}
1130
1131
1132static PyObject *
1133c_get(void *ptr, Py_ssize_t size)
1134{
1135 return PyBytes_FromStringAndSize((char *)ptr, 1);
1136}
1137
1138/* u - a single wchar_t character */
1139static PyObject *
1140u_set(void *ptr, PyObject *value, Py_ssize_t size)
1141{
1142 Py_ssize_t len;
1143 wchar_t chars[2];
1144 if (!PyUnicode_Check(value)) {
1145 PyErr_Format(PyExc_TypeError,
1146 "unicode string expected instead of %s instance",
1147 Py_TYPE(value)->tp_name);
1148 return NULL;
1149 } else
1150 Py_INCREF(value);
1151
1152 len = PyUnicode_AsWideChar(value, chars, 2);
1153 if (len != 1) {
1154 Py_DECREF(value);
1155 PyErr_SetString(PyExc_TypeError,
1156 "one character unicode string expected");
1157 return NULL;
1158 }
1159
1160 *(wchar_t *)ptr = chars[0];
1161 Py_DECREF(value);
1162
1163 _RET(value);
1164}
1165
1166
1167static PyObject *
1168u_get(void *ptr, Py_ssize_t size)
1169{
1170 return PyUnicode_FromWideChar((wchar_t *)ptr, 1);
1171}
1172
1173/* U - a unicode string */
1174static PyObject *
1175U_get(void *ptr, Py_ssize_t size)
1176{
1177 Py_ssize_t len;
1178 wchar_t *p;
1179
1180 size /= sizeof(wchar_t); /* we count character units here, not bytes */
1181
1182 /* We need 'result' to be able to count the characters with wcslen,
1183 since ptr may not be NUL terminated. If the length is smaller (if
1184 it was actually NUL terminated, we construct a new one and throw
1185 away the result.
1186 */
1187 /* chop off at the first NUL character, if any. */
1188 p = (wchar_t*)ptr;
1189 for (len = 0; len < size; ++len) {
1190 if (!p[len])
1191 break;
1192 }
1193
1194 return PyUnicode_FromWideChar((wchar_t *)ptr, len);
1195}
1196
1197static PyObject *
1198U_set(void *ptr, PyObject *value, Py_ssize_t length)
1199{
1200 /* It's easier to calculate in characters than in bytes */
1201 length /= sizeof(wchar_t);
1202
1203 if (!PyUnicode_Check(value)) {
1204 PyErr_Format(PyExc_TypeError,
1205 "unicode string expected instead of %s instance",
1206 Py_TYPE(value)->tp_name);
1207 return NULL;
1208 }
1209
1210 Py_ssize_t size = PyUnicode_AsWideChar(value, NULL, 0);
1211 if (size < 0) {
1212 return NULL;
1213 }
1214 // PyUnicode_AsWideChar() returns number of wchars including trailing null byte,
1215 // when it is called with NULL.
1216 size--;
1217 assert(size >= 0);
1218 if (size > length) {
1219 PyErr_Format(PyExc_ValueError,
1220 "string too long (%zd, maximum length %zd)",
1221 size, length);
1222 return NULL;
1223 }
1224 if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, length) == -1) {
1225 return NULL;
1226 }
1227
1228 Py_INCREF(value);
1229 return value;
1230}
1231
1232
1233static PyObject *
1234s_get(void *ptr, Py_ssize_t size)
1235{
1236 Py_ssize_t i;
1237 char *p;
1238
1239 p = (char *)ptr;
1240 for (i = 0; i < size; ++i) {
1241 if (*p++ == '\0')
1242 break;
1243 }
1244
1245 return PyBytes_FromStringAndSize((char *)ptr, (Py_ssize_t)i);
1246}
1247
1248static PyObject *
1249s_set(void *ptr, PyObject *value, Py_ssize_t length)
1250{
1251 const char *data;
1252 Py_ssize_t size;
1253
1254 if(!PyBytes_Check(value)) {
1255 PyErr_Format(PyExc_TypeError,
1256 "expected bytes, %s found",
1257 Py_TYPE(value)->tp_name);
1258 return NULL;
1259 }
1260
1261 data = PyBytes_AS_STRING(value);
1262 // bpo-39593: Use strlen() to truncate the string at the first null character.
1263 size = strlen(data);
1264
1265 if (size < length) {
1266 /* This will copy the terminating NUL character
1267 * if there is space for it.
1268 */
1269 ++size;
1270 } else if (size > length) {
1271 PyErr_Format(PyExc_ValueError,
1272 "bytes too long (%zd, maximum length %zd)",
1273 size, length);
1274 return NULL;
1275 }
1276 /* Also copy the terminating NUL character if there is space */
1277 memcpy((char *)ptr, data, size);
1278
1279 _RET(value);
1280}
1281
1282static PyObject *
1283z_set(void *ptr, PyObject *value, Py_ssize_t size)
1284{
1285 if (value == Py_None) {
1286 *(char **)ptr = NULL;
1287 Py_INCREF(value);
1288 return value;
1289 }
1290 if (PyBytes_Check(value)) {
1291 *(const char **)ptr = PyBytes_AsString(value);
1292 Py_INCREF(value);
1293 return value;
1294 } else if (PyLong_Check(value)) {
1295#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
1296 *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value);
1297#else
1298 *(char **)ptr = (char *)PyLong_AsUnsignedLongMask(value);
1299#endif
1300 _RET(value);
1301 }
1302 PyErr_Format(PyExc_TypeError,
1303 "bytes or integer address expected instead of %s instance",
1304 Py_TYPE(value)->tp_name);
1305 return NULL;
1306}
1307
1308static PyObject *
1309z_get(void *ptr, Py_ssize_t size)
1310{
1311 /* XXX What about invalid pointers ??? */
1312 if (*(void **)ptr) {
1313 return PyBytes_FromStringAndSize(*(char **)ptr,
1314 strlen(*(char **)ptr));
1315 } else {
1316 Py_RETURN_NONE;
1317 }
1318}
1319
1320static PyObject *
1321Z_set(void *ptr, PyObject *value, Py_ssize_t size)
1322{
1323 PyObject *keep;
1324 wchar_t *buffer;
1325 Py_ssize_t bsize;
1326
1327 if (value == Py_None) {
1328 *(wchar_t **)ptr = NULL;
1329 Py_INCREF(value);
1330 return value;
1331 }
1332 if (PyLong_Check(value)) {
1333#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
1334 *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongLongMask(value);
1335#else
1336 *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongMask(value);
1337#endif
1338 Py_RETURN_NONE;
1339 }
1340 if (!PyUnicode_Check(value)) {
1341 PyErr_Format(PyExc_TypeError,
1342 "unicode string or integer address expected instead of %s instance",
1343 Py_TYPE(value)->tp_name);
1344 return NULL;
1345 }
1346
1347 /* We must create a wchar_t* buffer from the unicode object,
1348 and keep it alive */
1349 buffer = PyUnicode_AsWideCharString(value, &bsize);
1350 if (!buffer)
1351 return NULL;
1352 keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);
1353 if (!keep) {
1354 PyMem_Free(buffer);
1355 return NULL;
1356 }
1357 *(wchar_t **)ptr = buffer;
1358 return keep;
1359}
1360
1361static PyObject *
1362Z_get(void *ptr, Py_ssize_t size)
1363{
1364 wchar_t *p;
1365 p = *(wchar_t **)ptr;
1366 if (p) {
1367 return PyUnicode_FromWideChar(p, wcslen(p));
1368 } else {
1369 Py_RETURN_NONE;
1370 }
1371}
1372
1373
1374#ifdef MS_WIN32
1375static PyObject *
1376BSTR_set(void *ptr, PyObject *value, Py_ssize_t size)
1377{
1378 BSTR bstr;
1379
1380 /* convert value into a PyUnicodeObject or NULL */
1381 if (Py_None == value) {
1382 value = NULL;
1383 } else if (!PyUnicode_Check(value)) {
1384 PyErr_Format(PyExc_TypeError,
1385 "unicode string expected instead of %s instance",
1386 Py_TYPE(value)->tp_name);
1387 return NULL;
1388 }
1389
1390 /* create a BSTR from value */
1391 if (value) {
1392 Py_ssize_t wsize;
1393 wchar_t *wvalue = PyUnicode_AsWideCharString(value, &wsize);
1394 if (wvalue == NULL) {
1395 return NULL;
1396 }
1397 if ((unsigned) wsize != wsize) {
1398 PyErr_SetString(PyExc_ValueError, "String too long for BSTR");
1399 PyMem_Free(wvalue);
1400 return NULL;
1401 }
1402 bstr = SysAllocStringLen(wvalue, (unsigned)wsize);
1403 PyMem_Free(wvalue);
1404 } else
1405 bstr = NULL;
1406
1407 /* free the previous contents, if any */
1408 if (*(BSTR *)ptr)
1409 SysFreeString(*(BSTR *)ptr);
1410
1411 /* and store it */
1412 *(BSTR *)ptr = bstr;
1413
1414 /* We don't need to keep any other object */
1415 _RET(value);
1416}
1417
1418
1419static PyObject *
1420BSTR_get(void *ptr, Py_ssize_t size)
1421{
1422 BSTR p;
1423 p = *(BSTR *)ptr;
1424 if (p)
1425 return PyUnicode_FromWideChar(p, SysStringLen(p));
1426 else {
1427 /* Hm, it seems NULL pointer and zero length string are the
1428 same in BSTR, see Don Box, p 81
1429 */
1430 Py_RETURN_NONE;
1431 }
1432}
1433#endif
1434
1435static PyObject *
1436P_set(void *ptr, PyObject *value, Py_ssize_t size)
1437{
1438 void *v;
1439 if (value == Py_None) {
1440 *(void **)ptr = NULL;
1441 _RET(value);
1442 }
1443
1444 if (!PyLong_Check(value)) {
1445 PyErr_SetString(PyExc_TypeError,
1446 "cannot be converted to pointer");
1447 return NULL;
1448 }
1449
1450#if SIZEOF_VOID_P <= SIZEOF_LONG
1451 v = (void *)PyLong_AsUnsignedLongMask(value);
1452#else
1453#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
1454# error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)"
1455#endif
1456 v = (void *)PyLong_AsUnsignedLongLongMask(value);
1457#endif
1458
1459 if (PyErr_Occurred())
1460 return NULL;
1461
1462 *(void **)ptr = v;
1463 _RET(value);
1464}
1465
1466static PyObject *
1467P_get(void *ptr, Py_ssize_t size)
1468{
1469 if (*(void **)ptr == NULL) {
1470 Py_RETURN_NONE;
1471 }
1472 return PyLong_FromVoidPtr(*(void **)ptr);
1473}
1474
1475static struct fielddesc formattable[] = {
1476 { 's', s_set, s_get, &ffi_type_pointer},
1477 { 'b', b_set, b_get, &ffi_type_schar},
1478 { 'B', B_set, B_get, &ffi_type_uchar},
1479 { 'c', c_set, c_get, &ffi_type_schar},
1480 { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw},
1481 { 'g', g_set, g_get, &ffi_type_longdouble},
1482 { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw},
1483 { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw},
1484 { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw},
1485 { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw},
1486 { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw},
1487/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
1488/* As soon as we can get rid of the type codes, this is no longer a problem */
1489#if SIZEOF_LONG == 4
1490 { 'l', l_set, l_get, &ffi_type_sint32, l_set_sw, l_get_sw},
1491 { 'L', L_set, L_get, &ffi_type_uint32, L_set_sw, L_get_sw},
1492#elif SIZEOF_LONG == 8
1493 { 'l', l_set, l_get, &ffi_type_sint64, l_set_sw, l_get_sw},
1494 { 'L', L_set, L_get, &ffi_type_uint64, L_set_sw, L_get_sw},
1495#else
1496# error
1497#endif
1498#if SIZEOF_LONG_LONG == 8
1499 { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw},
1500 { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw},
1501#else
1502# error
1503#endif
1504 { 'P', P_set, P_get, &ffi_type_pointer},
1505 { 'z', z_set, z_get, &ffi_type_pointer},
1506 { 'u', u_set, u_get, NULL}, /* ffi_type set later */
1507 { 'U', U_set, U_get, &ffi_type_pointer},
1508 { 'Z', Z_set, Z_get, &ffi_type_pointer},
1509#ifdef MS_WIN32
1510 { 'X', BSTR_set, BSTR_get, &ffi_type_pointer},
1511#endif
1512 { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort},
1513#if SIZEOF__BOOL == 1
1514 { '?', bool_set, bool_get, &ffi_type_uchar}, /* Also fallback for no native _Bool support */
1515#elif SIZEOF__BOOL == SIZEOF_SHORT
1516 { '?', bool_set, bool_get, &ffi_type_ushort},
1517#elif SIZEOF__BOOL == SIZEOF_INT
1518 { '?', bool_set, bool_get, &ffi_type_uint, I_set_sw, I_get_sw},
1519#elif SIZEOF__BOOL == SIZEOF_LONG
1520 { '?', bool_set, bool_get, &ffi_type_ulong, L_set_sw, L_get_sw},
1521#elif SIZEOF__BOOL == SIZEOF_LONG_LONG
1522 { '?', bool_set, bool_get, &ffi_type_ulong, Q_set_sw, Q_get_sw},
1523#endif /* SIZEOF__BOOL */
1524 { 'O', O_set, O_get, &ffi_type_pointer},
1525 { 0, NULL, NULL, NULL},
1526};
1527
1528/*
1529 Ideas: Implement VARIANT in this table, using 'V' code.
1530 Use '?' as code for BOOL.
1531*/
1532
1533struct fielddesc *
1534_ctypes_get_fielddesc(const char *fmt)
1535{
1536 static int initialized = 0;
1537 struct fielddesc *table = formattable;
1538
1539 if (!initialized) {
1540 initialized = 1;
1541 if (sizeof(wchar_t) == sizeof(short))
1542 _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort;
1543 else if (sizeof(wchar_t) == sizeof(int))
1544 _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint;
1545 else if (sizeof(wchar_t) == sizeof(long))
1546 _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong;
1547 }
1548
1549 for (; table->code; ++table) {
1550 if (table->code == fmt[0])
1551 return table;
1552 }
1553 return NULL;
1554}
1555
1556typedef struct { char c; char x; } s_char;
1557typedef struct { char c; short x; } s_short;
1558typedef struct { char c; int x; } s_int;
1559typedef struct { char c; long x; } s_long;
1560typedef struct { char c; float x; } s_float;
1561typedef struct { char c; double x; } s_double;
1562typedef struct { char c; long double x; } s_long_double;
1563typedef struct { char c; char *x; } s_char_p;
1564typedef struct { char c; void *x; } s_void_p;
1565
1566/*
1567#define CHAR_ALIGN (sizeof(s_char) - sizeof(char))
1568#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
1569#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
1570*/
1571#define INT_ALIGN (sizeof(s_int) - sizeof(int))
1572#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
1573#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
1574#define LONGDOUBLE_ALIGN (sizeof(s_long_double) - sizeof(long double))
1575
1576/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */
1577#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*))
1578
1579/*
1580#ifdef HAVE_USABLE_WCHAR_T
1581typedef struct { char c; wchar_t x; } s_wchar;
1582typedef struct { char c; wchar_t *x; } s_wchar_p;
1583
1584#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t))
1585#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*))
1586#endif
1587*/
1588
1589typedef struct { char c; long long x; } s_long_long;
1590#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
1591
1592/* from ffi.h:
1593typedef struct _ffi_type
1594{
1595 size_t size;
1596 unsigned short alignment;
1597 unsigned short type;
1598 struct _ffi_type **elements;
1599} ffi_type;
1600*/
1601
1602/* align and size are bogus for void, but they must not be zero */
1603ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
1604
1605ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
1606ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
1607
1608ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
1609ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
1610
1611ffi_type ffi_type_uint32 = { 4, INT_ALIGN, FFI_TYPE_UINT32 };
1612ffi_type ffi_type_sint32 = { 4, INT_ALIGN, FFI_TYPE_SINT32 };
1613
1614ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
1615ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
1616
1617ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
1618ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
1619
1620#ifdef ffi_type_longdouble
1621#undef ffi_type_longdouble
1622#endif
1623 /* This is already defined on OSX */
1624ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN,
1625 FFI_TYPE_LONGDOUBLE };
1626
1627ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
1628
1629/*---------------- EOF ----------------*/
1630