blob: d310ac54828ce13bf2f109ba59693c9b91bca591 [file] [log] [blame]
Thomas Hellerc2da9942006-06-12 20:56:48 +00001/*****************************************************************
2 This file should be kept compatible with Python 2.3, see PEP 291.
3 *****************************************************************/
4
Thomas Hellerd4c93202006-03-08 19:35:11 +00005#include "Python.h"
Thomas Hellerd4c93202006-03-08 19:35:11 +00006
7#include <ffi.h>
8#ifdef MS_WIN32
9#include <windows.h>
10#endif
11#include "ctypes.h"
12
13/******************************************************************/
14/*
15 CField_Type
16*/
17static PyObject *
18CField_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19{
20 CFieldObject *obj;
21 obj = (CFieldObject *)type->tp_alloc(type, 0);
22 return (PyObject *)obj;
23}
24
25/*
26 * Expects the size, index and offset for the current field in *psize and
27 * *poffset, stores the total size so far in *psize, the offset for the next
28 * field in *poffset, the alignment requirements for the current field in
29 * *palign, and returns a field desriptor for this field.
30 */
31/*
32 * bitfields extension:
33 * bitsize != 0: this is a bit field.
34 * pbitofs points to the current bit offset, this will be updated.
35 * prev_desc points to the type of the previous bitfield, if any.
36 */
37PyObject *
38CField_FromDesc(PyObject *desc, int index,
39 int *pfield_size, int bitsize, int *pbitofs,
40 int *psize, int *poffset, int *palign,
41 int pack, int big_endian)
42{
43 CFieldObject *self;
44 PyObject *proto;
45 int size, align, length;
46 SETFUNC setfunc = NULL;
47 GETFUNC getfunc = NULL;
48 StgDictObject *dict;
49 int fieldtype;
50#define NO_BITFIELD 0
51#define NEW_BITFIELD 1
52#define CONT_BITFIELD 2
53#define EXPAND_BITFIELD 3
54
55 self = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type,
56 NULL);
57 if (self == NULL)
58 return NULL;
59 dict = PyType_stgdict(desc);
60 if (!dict) {
61 PyErr_SetString(PyExc_TypeError,
62 "has no _stginfo_");
63 Py_DECREF(self);
64 return NULL;
65 }
66 if (bitsize /* this is a bitfield request */
67 && *pfield_size /* we have a bitfield open */
Thomas Heller9ba7ca82006-07-05 09:13:56 +000068#if defined(MS_WIN32) && !defined(__MINGW32__)
Thomas Hellerd4c93202006-03-08 19:35:11 +000069 && dict->size * 8 == *pfield_size /* MSVC */
70#else
Thomas Heller9ba7ca82006-07-05 09:13:56 +000071 && dict->size * 8 <= *pfield_size /* GCC, MINGW */
Thomas Hellerd4c93202006-03-08 19:35:11 +000072#endif
73 && (*pbitofs + bitsize) <= *pfield_size) {
74 /* continue bit field */
75 fieldtype = CONT_BITFIELD;
76#ifndef MS_WIN32
77 } else if (bitsize /* this is a bitfield request */
78 && *pfield_size /* we have a bitfield open */
79 && dict->size * 8 >= *pfield_size
80 && (*pbitofs + bitsize) <= dict->size * 8) {
81 /* expand bit field */
82 fieldtype = EXPAND_BITFIELD;
83#endif
84 } else if (bitsize) {
85 /* start new bitfield */
86 fieldtype = NEW_BITFIELD;
87 *pbitofs = 0;
88 *pfield_size = dict->size * 8;
89 } else {
90 /* not a bit field */
91 fieldtype = NO_BITFIELD;
92 *pbitofs = 0;
93 *pfield_size = 0;
94 }
95
96 size = dict->size;
97 length = dict->length;
98 proto = desc;
99
100 /* Field descriptors for 'c_char * n' are be scpecial cased to
101 return a Python string instead of an Array object instance...
102 */
103 if (ArrayTypeObject_Check(proto)) {
104 StgDictObject *adict = PyType_stgdict(proto);
105 StgDictObject *idict;
106 if (adict && adict->proto) {
107 idict = PyType_stgdict(adict->proto);
Neal Norwitz6b4953f2006-08-12 02:06:34 +0000108 if (!idict) {
109 PyErr_SetString(PyExc_TypeError,
110 "has no _stginfo_");
111 Py_DECREF(self);
112 return NULL;
113 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000114 if (idict->getfunc == getentry("c")->getfunc) {
115 struct fielddesc *fd = getentry("s");
116 getfunc = fd->getfunc;
117 setfunc = fd->setfunc;
118 }
119#ifdef CTYPES_UNICODE
120 if (idict->getfunc == getentry("u")->getfunc) {
121 struct fielddesc *fd = getentry("U");
122 getfunc = fd->getfunc;
123 setfunc = fd->setfunc;
124 }
125#endif
126 }
127 }
128
129 self->setfunc = setfunc;
130 self->getfunc = getfunc;
131 self->index = index;
132
Neal Norwitz109f9142006-07-16 02:05:35 +0000133 Py_INCREF(proto);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000134 self->proto = proto;
135
136 switch (fieldtype) {
137 case NEW_BITFIELD:
138 if (big_endian)
139 self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
140 else
141 self->size = (bitsize << 16) + *pbitofs;
142 *pbitofs = bitsize;
143 /* fall through */
144 case NO_BITFIELD:
145 if (pack)
146 align = min(pack, dict->align);
147 else
148 align = dict->align;
149 if (align && *poffset % align) {
150 int delta = align - (*poffset % align);
151 *psize += delta;
152 *poffset += delta;
153 }
154
155 if (bitsize == 0)
156 self->size = size;
157 *psize += size;
158
159 self->offset = *poffset;
160 *poffset += size;
161
162 *palign = align;
163 break;
164
165 case EXPAND_BITFIELD:
166 /* XXX needs more */
167 *psize += dict->size - *pfield_size/8;
168
169 *pfield_size = dict->size * 8;
170
171 if (big_endian)
172 self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
173 else
174 self->size = (bitsize << 16) + *pbitofs;
175
176 self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
177 *pbitofs += bitsize;
178 break;
179
180 case CONT_BITFIELD:
181 if (big_endian)
182 self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
183 else
184 self->size = (bitsize << 16) + *pbitofs;
185
186 self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
187 *pbitofs += bitsize;
188 break;
189 }
190
191 return (PyObject *)self;
192}
193
194static int
195CField_set(CFieldObject *self, PyObject *inst, PyObject *value)
196{
197 CDataObject *dst;
198 char *ptr;
199 assert(CDataObject_Check(inst));
200 dst = (CDataObject *)inst;
201 ptr = dst->b_ptr + self->offset;
Thomas Heller8e9e4d82007-12-18 19:00:59 +0000202 if (value == NULL) {
203 PyErr_SetString(PyExc_TypeError,
204 "can't delete attribute");
205 return -1;
206 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000207 return CData_set(inst, self->proto, self->setfunc, value,
208 self->index, self->size, ptr);
209}
210
211static PyObject *
212CField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
213{
214 CDataObject *src;
215 if (inst == NULL) {
216 Py_INCREF(self);
217 return (PyObject *)self;
218 }
219 assert(CDataObject_Check(inst));
220 src = (CDataObject *)inst;
221 return CData_get(self->proto, self->getfunc, inst,
222 self->index, self->size, src->b_ptr + self->offset);
223}
224
Thomas Hellerecc3e672006-06-06 11:34:33 +0000225static PyObject *
226CField_get_offset(PyObject *self, void *data)
227{
228#if (PY_VERSION_HEX < 0x02050000)
229 return PyInt_FromLong(((CFieldObject *)self)->offset);
230#else
231 return PyInt_FromSsize_t(((CFieldObject *)self)->offset);
232#endif
233}
234
235static PyObject *
236CField_get_size(PyObject *self, void *data)
237{
238#if (PY_VERSION_HEX < 0x02050000)
239 return PyInt_FromLong(((CFieldObject *)self)->size);
240#else
241 return PyInt_FromSsize_t(((CFieldObject *)self)->size);
242#endif
243}
244
245static PyGetSetDef CField_getset[] = {
246 { "offset", CField_get_offset, NULL, "offset in bytes of this field" },
Thomas Heller07347d62006-06-06 11:54:32 +0000247 { "size", CField_get_size, NULL, "size in bytes of this field" },
248 { NULL, NULL, NULL, NULL },
Thomas Hellerd4c93202006-03-08 19:35:11 +0000249};
250
251static int
252CField_traverse(CFieldObject *self, visitproc visit, void *arg)
253{
254 Py_VISIT(self->proto);
255 return 0;
256}
257
258static int
259CField_clear(CFieldObject *self)
260{
261 Py_CLEAR(self->proto);
262 return 0;
263}
264
265static void
266CField_dealloc(PyObject *self)
267{
268 CField_clear((CFieldObject *)self);
269 self->ob_type->tp_free((PyObject *)self);
270}
271
272static PyObject *
273CField_repr(CFieldObject *self)
274{
275 PyObject *result;
276 int bits = self->size >> 16;
277 int size = self->size & 0xFFFF;
278 const char *name;
279
280 name = ((PyTypeObject *)self->proto)->tp_name;
281
282 if (bits)
Thomas Heller9998f782006-03-15 21:49:52 +0000283 result = PyString_FromFormat(
284#if (PY_VERSION_HEX < 0x02050000)
285 "<Field type=%s, ofs=%d:%d, bits=%d>",
286#else
287 "<Field type=%s, ofs=%zd:%d, bits=%d>",
288#endif
289 name, self->offset, size, bits);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000290 else
Thomas Heller9998f782006-03-15 21:49:52 +0000291 result = PyString_FromFormat(
292#if (PY_VERSION_HEX < 0x02050000)
293 "<Field type=%s, ofs=%d, size=%d>",
294#else
295 "<Field type=%s, ofs=%zd, size=%d>",
296#endif
297 name, self->offset, size);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000298 return result;
299}
300
301PyTypeObject CField_Type = {
302 PyObject_HEAD_INIT(NULL)
303 0, /* ob_size */
304 "_ctypes.CField", /* tp_name */
305 sizeof(CFieldObject), /* tp_basicsize */
306 0, /* tp_itemsize */
307 CField_dealloc, /* tp_dealloc */
308 0, /* tp_print */
309 0, /* tp_getattr */
310 0, /* tp_setattr */
311 0, /* tp_compare */
312 (reprfunc)CField_repr, /* tp_repr */
313 0, /* tp_as_number */
314 0, /* tp_as_sequence */
315 0, /* tp_as_mapping */
316 0, /* tp_hash */
317 0, /* tp_call */
318 0, /* tp_str */
319 0, /* tp_getattro */
320 0, /* tp_setattro */
321 0, /* tp_as_buffer */
322 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
323 "Structure/Union member", /* tp_doc */
324 (traverseproc)CField_traverse, /* tp_traverse */
325 (inquiry)CField_clear, /* tp_clear */
326 0, /* tp_richcompare */
327 0, /* tp_weaklistoffset */
328 0, /* tp_iter */
329 0, /* tp_iternext */
330 0, /* tp_methods */
Thomas Hellerecc3e672006-06-06 11:34:33 +0000331 0, /* tp_members */
332 CField_getset, /* tp_getset */
Thomas Hellerd4c93202006-03-08 19:35:11 +0000333 0, /* tp_base */
334 0, /* tp_dict */
335 (descrgetfunc)CField_get, /* tp_descr_get */
336 (descrsetfunc)CField_set, /* tp_descr_set */
337 0, /* tp_dictoffset */
338 0, /* tp_init */
339 0, /* tp_alloc */
340 CField_new, /* tp_new */
341 0, /* tp_free */
342};
343
344
345/******************************************************************/
346/*
347 Accessor functions
348*/
349
350/* Derived from Modules/structmodule.c:
351 Helper routine to get a Python integer and raise the appropriate error
352 if it isn't one */
353
354static int
355get_long(PyObject *v, long *p)
356{
357 long x;
Thomas Hellerfe528eb2008-01-24 13:08:54 +0000358 if (PyFloat_Check(v)) {
359 PyErr_SetString(PyExc_TypeError,
360 "int expected instead of float");
Thomas Hellerd4c93202006-03-08 19:35:11 +0000361 return -1;
362 }
363 x = PyInt_AsUnsignedLongMask(v);
364 if (x == -1 && PyErr_Occurred())
365 return -1;
366 *p = x;
367 return 0;
368}
369
370/* Same, but handling unsigned long */
371
372static int
373get_ulong(PyObject *v, unsigned long *p)
374{
375 unsigned long x;
Thomas Hellerfe528eb2008-01-24 13:08:54 +0000376 if (PyFloat_Check(v)) {
377 PyErr_SetString(PyExc_TypeError,
378 "int expected instead of float");
Thomas Hellerd4c93202006-03-08 19:35:11 +0000379 return -1;
380 }
381 x = PyInt_AsUnsignedLongMask(v);
382 if (x == -1 && PyErr_Occurred())
383 return -1;
384 *p = x;
385 return 0;
386}
387
388#ifdef HAVE_LONG_LONG
389
390/* Same, but handling native long long. */
391
392static int
393get_longlong(PyObject *v, PY_LONG_LONG *p)
394{
395 PY_LONG_LONG x;
Thomas Hellerfe528eb2008-01-24 13:08:54 +0000396 if (PyFloat_Check(v)) {
397 PyErr_SetString(PyExc_TypeError,
398 "int expected instead of float");
399 return -1;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000400 }
401 x = PyInt_AsUnsignedLongLongMask(v);
402 if (x == -1 && PyErr_Occurred())
403 return -1;
404 *p = x;
405 return 0;
406}
407
408/* Same, but handling native unsigned long long. */
409
410static int
411get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
412{
413 unsigned PY_LONG_LONG x;
Thomas Hellerfe528eb2008-01-24 13:08:54 +0000414 if (PyFloat_Check(v)) {
415 PyErr_SetString(PyExc_TypeError,
416 "int expected instead of float");
417 return -1;
418 }
Thomas Hellerd4c93202006-03-08 19:35:11 +0000419 x = PyInt_AsUnsignedLongLongMask(v);
420 if (x == -1 && PyErr_Occurred())
421 return -1;
422 *p = x;
423 return 0;
424}
425
426#endif
427
428/*****************************************************************
429 * Integer fields, with bitfield support
430 */
431
432/* how to decode the size field, for integer get/set functions */
433#define LOW_BIT(x) ((x) & 0xFFFF)
434#define NUM_BITS(x) ((x) >> 16)
435
436/* This seems nore a compiler issue than a Windows/non-Windows one */
437#ifdef MS_WIN32
438# define BIT_MASK(size) ((1 << NUM_BITS(size))-1)
439#else
440# define BIT_MASK(size) ((1LL << NUM_BITS(size))-1)
441#endif
442
443/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
444 we must first shift left, then right.
445*/
446#define GET_BITFIELD(v, size) \
447 if (NUM_BITS(size)) { \
448 v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \
449 v >>= (sizeof(v)*8 - NUM_BITS(size)); \
450 }
451
452/* This macro RETURNS the first parameter with the bit field CHANGED. */
453#define SET(x, v, size) \
454 (NUM_BITS(size) ? \
455 ( ( x & ~(BIT_MASK(size) << LOW_BIT(size)) ) | ( (v & BIT_MASK(size)) << LOW_BIT(size) ) ) \
456 : v)
457
458/* byte swapping macros */
459#define SWAP_2(v) \
460 ( ( (v >> 8) & 0x00FF) | \
461 ( (v << 8) & 0xFF00) )
462
463#define SWAP_4(v) \
464 ( ( (v & 0x000000FF) << 24 ) | \
465 ( (v & 0x0000FF00) << 8 ) | \
466 ( (v & 0x00FF0000) >> 8 ) | \
467 ( ((v >> 24) & 0xFF)) )
468
469#ifdef _MSC_VER
470#define SWAP_8(v) \
471 ( ( (v & 0x00000000000000FFL) << 56 ) | \
472 ( (v & 0x000000000000FF00L) << 40 ) | \
473 ( (v & 0x0000000000FF0000L) << 24 ) | \
474 ( (v & 0x00000000FF000000L) << 8 ) | \
475 ( (v & 0x000000FF00000000L) >> 8 ) | \
476 ( (v & 0x0000FF0000000000L) >> 24 ) | \
477 ( (v & 0x00FF000000000000L) >> 40 ) | \
478 ( ((v >> 56) & 0xFF)) )
479#else
480#define SWAP_8(v) \
481 ( ( (v & 0x00000000000000FFLL) << 56 ) | \
482 ( (v & 0x000000000000FF00LL) << 40 ) | \
483 ( (v & 0x0000000000FF0000LL) << 24 ) | \
484 ( (v & 0x00000000FF000000LL) << 8 ) | \
485 ( (v & 0x000000FF00000000LL) >> 8 ) | \
486 ( (v & 0x0000FF0000000000LL) >> 24 ) | \
487 ( (v & 0x00FF000000000000LL) >> 40 ) | \
488 ( ((v >> 56) & 0xFF)) )
489#endif
490
491#define SWAP_INT SWAP_4
492
493#if SIZEOF_LONG == 4
494# define SWAP_LONG SWAP_4
495#elif SIZEOF_LONG == 8
496# define SWAP_LONG SWAP_8
497#endif
498/*****************************************************************
499 * The setter methods return an object which must be kept alive, to keep the
500 * data valid which has been stored in the memory block. The ctypes object
501 * instance inserts this object into its 'b_objects' list.
502 *
503 * For simple Python types like integers or characters, there is nothing that
504 * has to been kept alive, so Py_None is returned in these cases. But this
505 * makes inspecting the 'b_objects' list, which is accessible from Python for
506 * debugging, less useful.
507 *
508 * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value
509 * instead of Py_None.
510 */
511
512#ifdef _CTYPES_DEBUG_KEEP
513#define _RET(x) Py_INCREF(x); return x
514#else
515#define _RET(X) Py_INCREF(Py_None); return Py_None
516#endif
517
518/*****************************************************************
519 * integer accessor methods, supporting bit fields
520 */
521
522static PyObject *
523b_set(void *ptr, PyObject *value, unsigned size)
524{
525 long val;
526 if (get_long(value, &val) < 0)
527 return NULL;
Thomas Heller0890de32006-04-05 19:51:19 +0000528 *(signed char *)ptr = (signed char)SET(*(signed char *)ptr, (signed char)val, size);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000529 _RET(value);
530}
531
532
533static PyObject *
534b_get(void *ptr, unsigned size)
535{
Thomas Heller0890de32006-04-05 19:51:19 +0000536 signed char val = *(signed char *)ptr;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000537 GET_BITFIELD(val, size);
538 return PyInt_FromLong(val);
539}
540
541static PyObject *
542B_set(void *ptr, PyObject *value, unsigned size)
543{
544 unsigned long val;
545 if (get_ulong(value, &val) < 0)
546 return NULL;
547 *(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr,
548 (unsigned short)val, size);
549 _RET(value);
550}
551
552
553static PyObject *
554B_get(void *ptr, unsigned size)
555{
556 unsigned char val = *(unsigned char *)ptr;
557 GET_BITFIELD(val, size);
558 return PyInt_FromLong(val);
559}
560
561static PyObject *
562h_set(void *ptr, PyObject *value, unsigned size)
563{
564 long val;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000565 short x;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000566 if (get_long(value, &val) < 0)
567 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000568 memcpy(&x, ptr, sizeof(x));
569 x = SET(x, (short)val, size);
570 memcpy(ptr, &x, sizeof(x));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000571 _RET(value);
572}
573
574
575static PyObject *
576h_set_sw(void *ptr, PyObject *value, unsigned size)
577{
578 long val;
579 short field;
580 if (get_long(value, &val) < 0)
581 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000582 memcpy(&field, ptr, sizeof(field));
583 field = SWAP_2(field);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000584 field = SET(field, (short)val, size);
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000585 field = SWAP_2(field);
586 memcpy(ptr, &field, sizeof(field));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000587 _RET(value);
588}
589
590static PyObject *
591h_get(void *ptr, unsigned size)
592{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000593 short val;
594 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000595 GET_BITFIELD(val, size);
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000596 return PyInt_FromLong((long)val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000597}
598
599static PyObject *
600h_get_sw(void *ptr, unsigned size)
601{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000602 short val;
603 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000604 val = SWAP_2(val);
605 GET_BITFIELD(val, size);
606 return PyInt_FromLong(val);
607}
608
609static PyObject *
610H_set(void *ptr, PyObject *value, unsigned size)
611{
612 unsigned long val;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000613 unsigned short x;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000614 if (get_ulong(value, &val) < 0)
615 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000616 memcpy(&x, ptr, sizeof(x));
617 x = SET(x, (unsigned short)val, size);
618 memcpy(ptr, &x, sizeof(x));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000619 _RET(value);
620}
621
622static PyObject *
623H_set_sw(void *ptr, PyObject *value, unsigned size)
624{
625 unsigned long val;
626 unsigned short field;
627 if (get_ulong(value, &val) < 0)
628 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000629 memcpy(&field, ptr, sizeof(field));
630 field = SWAP_2(field);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000631 field = SET(field, (unsigned short)val, size);
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000632 field = SWAP_2(field);
633 memcpy(ptr, &field, sizeof(field));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000634 _RET(value);
635}
636
637
638static PyObject *
639H_get(void *ptr, unsigned size)
640{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000641 unsigned short val;
642 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000643 GET_BITFIELD(val, size);
644 return PyInt_FromLong(val);
645}
646
647static PyObject *
648H_get_sw(void *ptr, unsigned size)
649{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000650 unsigned short val;
651 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000652 val = SWAP_2(val);
653 GET_BITFIELD(val, size);
654 return PyInt_FromLong(val);
655}
656
657static PyObject *
658i_set(void *ptr, PyObject *value, unsigned size)
659{
660 long val;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000661 int x;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000662 if (get_long(value, &val) < 0)
663 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000664 memcpy(&x, ptr, sizeof(x));
665 x = SET(x, (int)val, size);
666 memcpy(ptr, &x, sizeof(x));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000667 _RET(value);
668}
669
670static PyObject *
671i_set_sw(void *ptr, PyObject *value, unsigned size)
672{
673 long val;
674 int field;
675 if (get_long(value, &val) < 0)
676 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000677 memcpy(&field, ptr, sizeof(field));
678 field = SWAP_INT(field);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000679 field = SET(field, (int)val, size);
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000680 field = SWAP_INT(field);
681 memcpy(ptr, &field, sizeof(field));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000682 _RET(value);
683}
684
685
686static PyObject *
687i_get(void *ptr, unsigned size)
688{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000689 int val;
690 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000691 GET_BITFIELD(val, size);
692 return PyInt_FromLong(val);
693}
694
695static PyObject *
696i_get_sw(void *ptr, unsigned size)
697{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000698 int val;
699 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000700 val = SWAP_INT(val);
701 GET_BITFIELD(val, size);
702 return PyInt_FromLong(val);
703}
704
705#ifdef MS_WIN32
706/* short BOOL - VARIANT_BOOL */
707static PyObject *
708vBOOL_set(void *ptr, PyObject *value, unsigned size)
709{
710 switch (PyObject_IsTrue(value)) {
711 case -1:
712 return NULL;
713 case 0:
714 *(short int *)ptr = VARIANT_FALSE;
715 _RET(value);
716 default:
717 *(short int *)ptr = VARIANT_TRUE;
718 _RET(value);
719 }
720}
721
722static PyObject *
723vBOOL_get(void *ptr, unsigned size)
724{
725 return PyBool_FromLong((long)*(short int *)ptr);
726}
727#endif
728
729static PyObject *
730I_set(void *ptr, PyObject *value, unsigned size)
731{
732 unsigned long val;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000733 unsigned int x;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000734 if (get_ulong(value, &val) < 0)
735 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000736 memcpy(&x, ptr, sizeof(x));
737 x = SET(x, (unsigned int)val, size);
738 memcpy(ptr, &x, sizeof(x));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000739 _RET(value);
740}
741
742static PyObject *
743I_set_sw(void *ptr, PyObject *value, unsigned size)
744{
745 unsigned long val;
746 unsigned int field;
747 if (get_ulong(value, &val) < 0)
748 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000749 memcpy(&field, ptr, sizeof(field));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000750 field = (unsigned int)SET(field, (unsigned int)val, size);
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000751 field = SWAP_INT(field);
752 memcpy(ptr, &field, sizeof(field));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000753 _RET(value);
754}
755
756
757static PyObject *
758I_get(void *ptr, unsigned size)
759{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000760 unsigned int val;
761 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000762 GET_BITFIELD(val, size);
763 return PyLong_FromUnsignedLong(val);
764}
765
766static PyObject *
767I_get_sw(void *ptr, unsigned size)
768{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000769 unsigned int val;
770 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000771 val = SWAP_INT(val);
772 GET_BITFIELD(val, size);
773 return PyLong_FromUnsignedLong(val);
774}
775
776static PyObject *
777l_set(void *ptr, PyObject *value, unsigned size)
778{
779 long val;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000780 long x;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000781 if (get_long(value, &val) < 0)
782 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000783 memcpy(&x, ptr, sizeof(x));
784 x = SET(x, val, size);
785 memcpy(ptr, &x, sizeof(x));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000786 _RET(value);
787}
788
789static PyObject *
790l_set_sw(void *ptr, PyObject *value, unsigned size)
791{
792 long val;
793 long field;
794 if (get_long(value, &val) < 0)
795 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000796 memcpy(&field, ptr, sizeof(field));
797 field = SWAP_LONG(field);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000798 field = (long)SET(field, val, size);
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000799 field = SWAP_LONG(field);
800 memcpy(ptr, &field, sizeof(field));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000801 _RET(value);
802}
803
804
805static PyObject *
806l_get(void *ptr, unsigned size)
807{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000808 long val;
809 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000810 GET_BITFIELD(val, size);
811 return PyInt_FromLong(val);
812}
813
814static PyObject *
815l_get_sw(void *ptr, unsigned size)
816{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000817 long val;
818 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000819 val = SWAP_LONG(val);
820 GET_BITFIELD(val, size);
821 return PyInt_FromLong(val);
822}
823
824static PyObject *
825L_set(void *ptr, PyObject *value, unsigned size)
826{
827 unsigned long val;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000828 unsigned long x;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000829 if (get_ulong(value, &val) < 0)
830 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000831 memcpy(&x, ptr, sizeof(x));
832 x = SET(x, val, size);
833 memcpy(ptr, &x, sizeof(x));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000834 _RET(value);
835}
836
837static PyObject *
838L_set_sw(void *ptr, PyObject *value, unsigned size)
839{
840 unsigned long val;
841 unsigned long field;
842 if (get_ulong(value, &val) < 0)
843 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000844 memcpy(&field, ptr, sizeof(field));
845 field = SWAP_LONG(field);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000846 field = (unsigned long)SET(field, val, size);
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000847 field = SWAP_LONG(field);
848 memcpy(ptr, &field, sizeof(field));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000849 _RET(value);
850}
851
852
853static PyObject *
854L_get(void *ptr, unsigned size)
855{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000856 unsigned long val;
857 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000858 GET_BITFIELD(val, size);
859 return PyLong_FromUnsignedLong(val);
860}
861
862static PyObject *
863L_get_sw(void *ptr, unsigned size)
864{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000865 unsigned long val;
866 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000867 val = SWAP_LONG(val);
868 GET_BITFIELD(val, size);
869 return PyLong_FromUnsignedLong(val);
870}
871
872#ifdef HAVE_LONG_LONG
873static PyObject *
874q_set(void *ptr, PyObject *value, unsigned size)
875{
876 PY_LONG_LONG val;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000877 PY_LONG_LONG x;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000878 if (get_longlong(value, &val) < 0)
879 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000880 memcpy(&x, ptr, sizeof(x));
881 x = SET(x, val, size);
882 memcpy(ptr, &x, sizeof(x));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000883 _RET(value);
884}
885
886static PyObject *
887q_set_sw(void *ptr, PyObject *value, unsigned size)
888{
889 PY_LONG_LONG val;
890 PY_LONG_LONG field;
891 if (get_longlong(value, &val) < 0)
892 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000893 memcpy(&field, ptr, sizeof(field));
894 field = SWAP_8(field);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000895 field = (PY_LONG_LONG)SET(field, val, size);
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000896 field = SWAP_8(field);
897 memcpy(ptr, &field, sizeof(field));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000898 _RET(value);
899}
900
901static PyObject *
902q_get(void *ptr, unsigned size)
903{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000904 PY_LONG_LONG val;
905 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000906 GET_BITFIELD(val, size);
907 return PyLong_FromLongLong(val);
908}
909
910static PyObject *
911q_get_sw(void *ptr, unsigned size)
912{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000913 PY_LONG_LONG val;
914 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000915 val = SWAP_8(val);
916 GET_BITFIELD(val, size);
917 return PyLong_FromLongLong(val);
918}
919
920static PyObject *
921Q_set(void *ptr, PyObject *value, unsigned size)
922{
923 unsigned PY_LONG_LONG val;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000924 unsigned PY_LONG_LONG x;
Thomas Hellerd4c93202006-03-08 19:35:11 +0000925 if (get_ulonglong(value, &val) < 0)
926 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000927 memcpy(&x, ptr, sizeof(x));
928 x = SET(x, val, size);
929 memcpy(ptr, &x, sizeof(x));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000930 _RET(value);
931}
932
933static PyObject *
934Q_set_sw(void *ptr, PyObject *value, unsigned size)
935{
936 unsigned PY_LONG_LONG val;
937 unsigned PY_LONG_LONG field;
938 if (get_ulonglong(value, &val) < 0)
939 return NULL;
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000940 memcpy(&field, ptr, sizeof(field));
941 field = SWAP_8(field);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000942 field = (unsigned PY_LONG_LONG)SET(field, val, size);
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000943 field = SWAP_8(field);
944 memcpy(ptr, &field, sizeof(field));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000945 _RET(value);
946}
947
948static PyObject *
949Q_get(void *ptr, unsigned size)
950{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000951 unsigned PY_LONG_LONG val;
952 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000953 GET_BITFIELD(val, size);
954 return PyLong_FromUnsignedLongLong(val);
955}
956
957static PyObject *
958Q_get_sw(void *ptr, unsigned size)
959{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000960 unsigned PY_LONG_LONG val;
961 memcpy(&val, ptr, sizeof(val));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000962 val = SWAP_8(val);
963 GET_BITFIELD(val, size);
964 return PyLong_FromUnsignedLongLong(val);
965}
966#endif
967
968/*****************************************************************
969 * non-integer accessor methods, not supporting bit fields
970 */
971
972
973
974static PyObject *
975d_set(void *ptr, PyObject *value, unsigned size)
976{
977 double x;
978
979 x = PyFloat_AsDouble(value);
980 if (x == -1 && PyErr_Occurred()) {
981 PyErr_Format(PyExc_TypeError,
982 " float expected instead of %s instance",
983 value->ob_type->tp_name);
984 return NULL;
985 }
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000986 memcpy(ptr, &x, sizeof(double));
Thomas Hellerd4c93202006-03-08 19:35:11 +0000987 _RET(value);
988}
989
990static PyObject *
991d_get(void *ptr, unsigned size)
992{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +0000993 double val;
994 memcpy(&val, ptr, sizeof(val));
995 return PyFloat_FromDouble(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +0000996}
997
998static PyObject *
999d_set_sw(void *ptr, PyObject *value, unsigned size)
1000{
1001 double x;
1002
1003 x = PyFloat_AsDouble(value);
1004 if (x == -1 && PyErr_Occurred()) {
1005 PyErr_Format(PyExc_TypeError,
1006 " float expected instead of %s instance",
1007 value->ob_type->tp_name);
1008 return NULL;
1009 }
1010#ifdef WORDS_BIGENDIAN
1011 if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1))
1012 return NULL;
1013#else
1014 if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0))
1015 return NULL;
1016#endif
1017 _RET(value);
1018}
1019
1020static PyObject *
1021d_get_sw(void *ptr, unsigned size)
1022{
1023#ifdef WORDS_BIGENDIAN
1024 return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1));
1025#else
1026 return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0));
1027#endif
1028}
1029
1030static PyObject *
1031f_set(void *ptr, PyObject *value, unsigned size)
1032{
1033 float x;
1034
1035 x = (float)PyFloat_AsDouble(value);
1036 if (x == -1 && PyErr_Occurred()) {
1037 PyErr_Format(PyExc_TypeError,
1038 " float expected instead of %s instance",
1039 value->ob_type->tp_name);
1040 return NULL;
1041 }
Thomas Hellerd59ca8f2006-03-20 07:54:01 +00001042 memcpy(ptr, &x, sizeof(x));
Thomas Hellerd4c93202006-03-08 19:35:11 +00001043 _RET(value);
1044}
1045
1046static PyObject *
1047f_get(void *ptr, unsigned size)
1048{
Thomas Hellerd59ca8f2006-03-20 07:54:01 +00001049 float val;
1050 memcpy(&val, ptr, sizeof(val));
1051 return PyFloat_FromDouble(val);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001052}
1053
1054static PyObject *
1055f_set_sw(void *ptr, PyObject *value, unsigned size)
1056{
1057 float x;
1058
1059 x = (float)PyFloat_AsDouble(value);
1060 if (x == -1 && PyErr_Occurred()) {
1061 PyErr_Format(PyExc_TypeError,
1062 " float expected instead of %s instance",
1063 value->ob_type->tp_name);
1064 return NULL;
1065 }
1066#ifdef WORDS_BIGENDIAN
1067 if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1))
1068 return NULL;
1069#else
1070 if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0))
1071 return NULL;
1072#endif
1073 _RET(value);
1074}
1075
1076static PyObject *
1077f_get_sw(void *ptr, unsigned size)
1078{
1079#ifdef WORDS_BIGENDIAN
1080 return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1));
1081#else
1082 return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0));
1083#endif
1084}
1085
1086/*
1087 py_object refcounts:
1088
1089 1. If we have a py_object instance, O_get must Py_INCREF the returned
1090 object, of course. If O_get is called from a function result, no py_object
1091 instance is created - so callproc.c::GetResult has to call Py_DECREF.
1092
1093 2. The memory block in py_object owns a refcount. So, py_object must call
1094 Py_DECREF on destruction. Maybe only when b_needsfree is non-zero.
1095*/
1096static PyObject *
1097O_get(void *ptr, unsigned size)
1098{
1099 PyObject *ob = *(PyObject **)ptr;
1100 if (ob == NULL) {
1101 if (!PyErr_Occurred())
1102 /* Set an error if not yet set */
1103 PyErr_SetString(PyExc_ValueError,
Thomas Hellerb0aa98f2006-08-16 14:07:44 +00001104 "PyObject is NULL");
Thomas Hellerd4c93202006-03-08 19:35:11 +00001105 return NULL;
1106 }
1107 Py_INCREF(ob);
1108 return ob;
1109}
1110
1111static PyObject *
1112O_set(void *ptr, PyObject *value, unsigned size)
1113{
1114 /* Hm, does the memory block need it's own refcount or not? */
1115 *(PyObject **)ptr = value;
1116 Py_INCREF(value);
1117 return value;
1118}
1119
1120
1121static PyObject *
1122c_set(void *ptr, PyObject *value, unsigned size)
1123{
1124 if (!PyString_Check(value) || (1 != PyString_Size(value))) {
1125 PyErr_Format(PyExc_TypeError,
1126 "one character string expected");
1127 return NULL;
1128 }
1129 *(char *)ptr = PyString_AS_STRING(value)[0];
1130 _RET(value);
1131}
1132
1133
1134static PyObject *
1135c_get(void *ptr, unsigned size)
1136{
1137 return PyString_FromStringAndSize((char *)ptr, 1);
1138}
1139
1140#ifdef CTYPES_UNICODE
1141/* u - a single wchar_t character */
1142static PyObject *
1143u_set(void *ptr, PyObject *value, unsigned size)
1144{
1145 int len;
1146
1147 if (PyString_Check(value)) {
1148 value = PyUnicode_FromEncodedObject(value,
1149 conversion_mode_encoding,
1150 conversion_mode_errors);
1151 if (!value)
1152 return NULL;
1153 } else if (!PyUnicode_Check(value)) {
1154 PyErr_Format(PyExc_TypeError,
1155 "unicode string expected instead of %s instance",
1156 value->ob_type->tp_name);
1157 return NULL;
1158 } else
1159 Py_INCREF(value);
1160
1161 len = PyUnicode_GET_SIZE(value);
1162 if (len != 1) {
1163 Py_DECREF(value);
1164 PyErr_SetString(PyExc_TypeError,
1165 "one character unicode string expected");
1166 return NULL;
1167 }
1168
1169 *(wchar_t *)ptr = PyUnicode_AS_UNICODE(value)[0];
1170 Py_DECREF(value);
1171
1172 _RET(value);
1173}
1174
1175
1176static PyObject *
1177u_get(void *ptr, unsigned size)
1178{
1179 return PyUnicode_FromWideChar((wchar_t *)ptr, 1);
1180}
1181
1182/* U - a unicode string */
1183static PyObject *
1184U_get(void *ptr, unsigned size)
1185{
1186 PyObject *result;
1187 unsigned int len;
1188 Py_UNICODE *p;
1189
1190 size /= sizeof(wchar_t); /* we count character units here, not bytes */
1191
1192 result = PyUnicode_FromWideChar((wchar_t *)ptr, size);
1193 if (!result)
1194 return NULL;
1195 /* We need 'result' to be able to count the characters with wcslen,
1196 since ptr may not be NUL terminated. If the length is smaller (if
1197 it was actually NUL terminated, we construct a new one and throw
1198 away the result.
1199 */
1200 /* chop off at the first NUL character, if any. */
1201 p = PyUnicode_AS_UNICODE(result);
1202 for (len = 0; len < size; ++len)
1203 if (!p[len])
1204 break;
1205
1206 if (len < size) {
1207 PyObject *ob = PyUnicode_FromWideChar((wchar_t *)ptr, len);
1208 Py_DECREF(result);
1209 return ob;
1210 }
1211 return result;
1212}
1213
1214static PyObject *
1215U_set(void *ptr, PyObject *value, unsigned length)
1216{
1217 unsigned int size;
1218
1219 /* It's easier to calculate in characters than in bytes */
1220 length /= sizeof(wchar_t);
1221
1222 if (PyString_Check(value)) {
1223 value = PyUnicode_FromEncodedObject(value,
1224 conversion_mode_encoding,
1225 conversion_mode_errors);
1226 if (!value)
1227 return NULL;
1228 } else if (!PyUnicode_Check(value)) {
1229 PyErr_Format(PyExc_TypeError,
1230 "unicode string expected instead of %s instance",
1231 value->ob_type->tp_name);
1232 return NULL;
1233 } else
1234 Py_INCREF(value);
1235 size = PyUnicode_GET_SIZE(value);
1236 if (size > length) {
1237 PyErr_Format(PyExc_ValueError,
1238 "string too long (%d, maximum length %d)",
1239 size, length);
1240 Py_DECREF(value);
1241 return NULL;
1242 } else if (size < length-1)
1243 /* copy terminating NUL character if there is space */
1244 size += 1;
1245 PyUnicode_AsWideChar((PyUnicodeObject *)value, (wchar_t *)ptr, size);
1246 return value;
1247}
1248
1249#endif
1250
1251static PyObject *
1252s_get(void *ptr, unsigned size)
1253{
1254 PyObject *result;
1255
1256 result = PyString_FromString((char *)ptr);
1257 if (!result)
1258 return NULL;
1259 /* chop off at the first NUL character, if any.
1260 * On error, result will be deallocated and set to NULL.
1261 */
1262 size = min(size, strlen(PyString_AS_STRING(result)));
1263 if (result->ob_refcnt == 1) {
1264 /* shorten the result */
1265 _PyString_Resize(&result, size);
1266 return result;
1267 } else
1268 /* cannot shorten the result */
1269 return PyString_FromStringAndSize(ptr, size);
1270}
1271
1272static PyObject *
1273s_set(void *ptr, PyObject *value, unsigned length)
1274{
1275 char *data;
1276 unsigned size;
1277
1278 data = PyString_AsString(value);
1279 if (!data)
1280 return NULL;
1281 size = strlen(data);
1282 if (size < length) {
1283 /* This will copy the leading NUL character
1284 * if there is space for it.
1285 */
1286 ++size;
1287 } else if (size > length) {
1288 PyErr_Format(PyExc_ValueError,
1289 "string too long (%d, maximum length %d)",
1290 size, length);
1291 return NULL;
1292 }
1293 /* Also copy the terminating NUL character if there is space */
1294 memcpy((char *)ptr, data, size);
1295 _RET(value);
1296}
1297
1298static PyObject *
1299z_set(void *ptr, PyObject *value, unsigned size)
1300{
1301 if (value == Py_None) {
1302 *(char **)ptr = NULL;
1303 Py_INCREF(value);
1304 return value;
1305 }
1306 if (PyString_Check(value)) {
1307 *(char **)ptr = PyString_AS_STRING(value);
1308 Py_INCREF(value);
1309 return value;
1310 } else if (PyUnicode_Check(value)) {
1311 PyObject *str = PyUnicode_AsEncodedString(value,
1312 conversion_mode_encoding,
1313 conversion_mode_errors);
1314 if (str == NULL)
1315 return NULL;
1316 *(char **)ptr = PyString_AS_STRING(str);
1317 return str;
1318 } else if (PyInt_Check(value) || PyLong_Check(value)) {
1319 *(char **)ptr = (char *)PyInt_AsUnsignedLongMask(value);
1320 _RET(value);
1321 }
1322 PyErr_Format(PyExc_TypeError,
1323 "string or integer address expected instead of %s instance",
1324 value->ob_type->tp_name);
1325 return NULL;
1326}
1327
1328static PyObject *
1329z_get(void *ptr, unsigned size)
1330{
1331 /* XXX What about invalid pointers ??? */
1332 if (*(void **)ptr) {
1333#if defined(MS_WIN32) && !defined(_WIN32_WCE)
1334 if (IsBadStringPtrA(*(char **)ptr, -1)) {
1335 PyErr_Format(PyExc_ValueError,
1336 "invalid string pointer %p",
Thomas Heller412b20b2007-05-02 19:41:16 +00001337 *(char **)ptr);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001338 return NULL;
1339 }
1340#endif
1341 return PyString_FromString(*(char **)ptr);
1342 } else {
1343 Py_INCREF(Py_None);
1344 return Py_None;
1345 }
1346}
1347
1348#ifdef CTYPES_UNICODE
1349static PyObject *
1350Z_set(void *ptr, PyObject *value, unsigned size)
1351{
1352 if (value == Py_None) {
1353 *(wchar_t **)ptr = NULL;
1354 Py_INCREF(value);
1355 return value;
1356 }
1357 if (PyString_Check(value)) {
1358 value = PyUnicode_FromEncodedObject(value,
1359 conversion_mode_encoding,
1360 conversion_mode_errors);
1361 if (!value)
1362 return NULL;
1363 } else if (PyInt_Check(value) || PyLong_Check(value)) {
1364 *(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongMask(value);
1365 Py_INCREF(Py_None);
1366 return Py_None;
1367 } else if (!PyUnicode_Check(value)) {
1368 PyErr_Format(PyExc_TypeError,
1369 "unicode string or integer address expected instead of %s instance",
1370 value->ob_type->tp_name);
1371 return NULL;
1372 } else
1373 Py_INCREF(value);
1374#ifdef HAVE_USABLE_WCHAR_T
1375 /* HAVE_USABLE_WCHAR_T means that Py_UNICODE and wchar_t is the same
1376 type. So we can copy directly. Hm, are unicode objects always NUL
1377 terminated in Python, internally?
1378 */
1379 *(wchar_t **)ptr = PyUnicode_AS_UNICODE(value);
1380 return value;
1381#else
1382 {
1383 /* We must create a wchar_t* buffer from the unicode object,
1384 and keep it alive */
1385 PyObject *keep;
1386 wchar_t *buffer;
1387
1388 int size = PyUnicode_GET_SIZE(value);
1389 size += 1; /* terminating NUL */
1390 size *= sizeof(wchar_t);
1391 buffer = (wchar_t *)PyMem_Malloc(size);
1392 if (!buffer)
Thomas Hellerf69fa172007-04-30 15:58:51 +00001393 return PyErr_NoMemory();
Thomas Hellerd4c93202006-03-08 19:35:11 +00001394 memset(buffer, 0, size);
1395 keep = PyCObject_FromVoidPtr(buffer, PyMem_Free);
1396 if (!keep) {
1397 PyMem_Free(buffer);
1398 return NULL;
1399 }
1400 *(wchar_t **)ptr = (wchar_t *)buffer;
1401 if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)value,
1402 buffer, PyUnicode_GET_SIZE(value))) {
1403 Py_DECREF(value);
Thomas Heller0c6b0e92006-03-16 20:02:36 +00001404 Py_DECREF(keep);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001405 return NULL;
1406 }
1407 Py_DECREF(value);
1408 return keep;
1409 }
1410#endif
1411}
1412
1413static PyObject *
1414Z_get(void *ptr, unsigned size)
1415{
1416 wchar_t *p;
1417 p = *(wchar_t **)ptr;
Thomas Heller412b20b2007-05-02 19:41:16 +00001418 if (p) {
1419#if defined(MS_WIN32) && !defined(_WIN32_WCE)
1420 if (IsBadStringPtrW(*(wchar_t **)ptr, -1)) {
1421 PyErr_Format(PyExc_ValueError,
1422 "invalid string pointer %p",
1423 *(wchar_t **)ptr);
1424 return NULL;
1425 }
1426#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +00001427 return PyUnicode_FromWideChar(p, wcslen(p));
Thomas Heller412b20b2007-05-02 19:41:16 +00001428 } else {
Thomas Hellerd4c93202006-03-08 19:35:11 +00001429 Py_INCREF(Py_None);
1430 return Py_None;
1431 }
1432}
1433#endif
1434
1435#ifdef MS_WIN32
1436static PyObject *
1437BSTR_set(void *ptr, PyObject *value, unsigned size)
1438{
1439 BSTR bstr;
1440
1441 /* convert value into a PyUnicodeObject or NULL */
1442 if (Py_None == value) {
1443 value = NULL;
1444 } else if (PyString_Check(value)) {
1445 value = PyUnicode_FromEncodedObject(value,
1446 conversion_mode_encoding,
1447 conversion_mode_errors);
1448 if (!value)
1449 return NULL;
1450 } else if (PyUnicode_Check(value)) {
1451 Py_INCREF(value); /* for the descref below */
1452 } else {
1453 PyErr_Format(PyExc_TypeError,
1454 "unicode string expected instead of %s instance",
1455 value->ob_type->tp_name);
1456 return NULL;
1457 }
1458
1459 /* create a BSTR from value */
1460 if (value) {
1461 bstr = SysAllocStringLen(PyUnicode_AS_UNICODE(value),
1462 PyUnicode_GET_SIZE(value));
1463 Py_DECREF(value);
1464 } else
1465 bstr = NULL;
1466
Thomas Heller02b8fee2007-03-22 19:43:37 +00001467 /* free the previous contents, if any */
1468 if (*(BSTR *)ptr)
1469 SysFreeString(*(BSTR *)ptr);
1470
1471 /* and store it */
Thomas Heller817b4892007-01-25 19:19:35 +00001472 *(BSTR *)ptr = bstr;
Thomas Heller02b8fee2007-03-22 19:43:37 +00001473
1474 /* We don't need to keep any other object */
1475 _RET(value);
Thomas Hellerd4c93202006-03-08 19:35:11 +00001476}
1477
1478
1479static PyObject *
1480BSTR_get(void *ptr, unsigned size)
1481{
1482 BSTR p;
1483 p = *(BSTR *)ptr;
1484 if (p)
1485 return PyUnicode_FromWideChar(p, SysStringLen(p));
1486 else {
1487 /* Hm, it seems NULL pointer and zero length string are the
1488 same in BSTR, see Don Box, p 81
1489 */
1490 Py_INCREF(Py_None);
1491 return Py_None;
1492 }
1493}
1494#endif
1495
1496static PyObject *
1497P_set(void *ptr, PyObject *value, unsigned size)
1498{
1499 void *v;
1500 if (value == Py_None) {
1501 *(void **)ptr = NULL;
1502 _RET(value);
1503 }
Thomas Hellerdda068d2006-07-10 09:10:28 +00001504
1505 if (!PyInt_Check(value) && !PyLong_Check(value)) {
1506 PyErr_SetString(PyExc_TypeError,
1507 "cannot be converted to pointer");
Thomas Hellerd4c93202006-03-08 19:35:11 +00001508 return NULL;
1509 }
Thomas Hellerdda068d2006-07-10 09:10:28 +00001510
1511#if SIZEOF_VOID_P <= SIZEOF_LONG
1512 v = (void *)PyInt_AsUnsignedLongMask(value);
1513#else
1514#ifndef HAVE_LONG_LONG
1515# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
1516#elif SIZEOF_LONG_LONG < SIZEOF_VOID_P
1517# error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
1518#endif
1519 v = (void *)PyInt_AsUnsignedLongLongMask(value);
1520#endif
1521
1522 if (PyErr_Occurred())
1523 return NULL;
1524
Thomas Hellerd4c93202006-03-08 19:35:11 +00001525 *(void **)ptr = v;
1526 _RET(value);
1527}
1528
1529static PyObject *
1530P_get(void *ptr, unsigned size)
1531{
1532 if (*(void **)ptr == NULL) {
1533 Py_INCREF(Py_None);
1534 return Py_None;
1535 }
1536 return PyLong_FromVoidPtr(*(void **)ptr);
1537}
1538
1539static struct fielddesc formattable[] = {
1540 { 's', s_set, s_get, &ffi_type_pointer},
1541 { 'b', b_set, b_get, &ffi_type_schar},
1542 { 'B', B_set, B_get, &ffi_type_uchar},
1543 { 'c', c_set, c_get, &ffi_type_schar},
1544 { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw},
1545 { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw},
1546 { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw},
1547 { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw},
1548 { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw},
1549 { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw},
1550/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
1551/* As soon as we can get rid of the type codes, this is no longer a problem */
1552#if SIZEOF_LONG == 4
Thomas Hellerd6f63812007-10-12 06:53:32 +00001553 { 'l', l_set, l_get, &ffi_type_sint32, l_set_sw, l_get_sw},
1554 { 'L', L_set, L_get, &ffi_type_uint32, L_set_sw, L_get_sw},
Thomas Hellerd4c93202006-03-08 19:35:11 +00001555#elif SIZEOF_LONG == 8
Thomas Hellerd6f63812007-10-12 06:53:32 +00001556 { 'l', l_set, l_get, &ffi_type_sint64, l_set_sw, l_get_sw},
1557 { 'L', L_set, L_get, &ffi_type_uint64, L_set_sw, L_get_sw},
Thomas Hellerd4c93202006-03-08 19:35:11 +00001558#else
1559# error
1560#endif
1561#ifdef HAVE_LONG_LONG
Thomas Hellerd6f63812007-10-12 06:53:32 +00001562#if SIZEOF_LONG_LONG == 8
1563 { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw},
1564 { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw},
1565#else
1566# error
1567#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +00001568#endif
1569 { 'P', P_set, P_get, &ffi_type_pointer},
1570 { 'z', z_set, z_get, &ffi_type_pointer},
1571#ifdef CTYPES_UNICODE
1572 { 'u', u_set, u_get, NULL}, /* ffi_type set later */
1573 { 'U', U_set, U_get, &ffi_type_pointer},
1574 { 'Z', Z_set, Z_get, &ffi_type_pointer},
1575#endif
1576#ifdef MS_WIN32
1577 { 'X', BSTR_set, BSTR_get, &ffi_type_pointer},
1578 { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort},
1579#endif
1580 { 'O', O_set, O_get, &ffi_type_pointer},
1581 { 0, NULL, NULL, NULL},
1582};
1583
1584/*
1585 Ideas: Implement VARIANT in this table, using 'V' code.
1586 Use '?' as code for BOOL.
1587*/
1588
1589struct fielddesc *
1590getentry(char *fmt)
1591{
1592 static int initialized = 0;
1593 struct fielddesc *table = formattable;
1594
1595 if (!initialized) {
1596 initialized = 1;
1597#ifdef CTYPES_UNICODE
1598 if (sizeof(wchar_t) == sizeof(short))
1599 getentry("u")->pffi_type = &ffi_type_sshort;
1600 else if (sizeof(wchar_t) == sizeof(int))
1601 getentry("u")->pffi_type = &ffi_type_sint;
1602 else if (sizeof(wchar_t) == sizeof(long))
1603 getentry("u")->pffi_type = &ffi_type_slong;
1604#endif
1605 }
1606
1607 for (; table->code; ++table) {
1608 if (table->code == fmt[0])
1609 return table;
1610 }
1611 return NULL;
1612}
1613
1614typedef struct { char c; char x; } s_char;
1615typedef struct { char c; short x; } s_short;
1616typedef struct { char c; int x; } s_int;
1617typedef struct { char c; long x; } s_long;
1618typedef struct { char c; float x; } s_float;
1619typedef struct { char c; double x; } s_double;
1620typedef struct { char c; char *x; } s_char_p;
1621typedef struct { char c; void *x; } s_void_p;
1622
1623/*
1624#define CHAR_ALIGN (sizeof(s_char) - sizeof(char))
1625#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
1626#define INT_ALIGN (sizeof(s_int) - sizeof(int))
1627#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
1628*/
1629#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
1630#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
1631/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */
1632#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*))
1633
1634/*
1635#ifdef HAVE_USABLE_WCHAR_T
1636typedef struct { char c; wchar_t x; } s_wchar;
1637typedef struct { char c; wchar_t *x; } s_wchar_p;
1638
1639#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t))
1640#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*))
1641#endif
1642*/
1643
1644#ifdef HAVE_LONG_LONG
1645typedef struct { char c; PY_LONG_LONG x; } s_long_long;
1646#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
1647#endif
1648
1649/* from ffi.h:
1650typedef struct _ffi_type
1651{
1652 size_t size;
1653 unsigned short alignment;
1654 unsigned short type;
1655 struct _ffi_type **elements;
1656} ffi_type;
1657*/
1658
1659/* align and size are bogus for void, but they must not be zero */
1660ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
1661
1662ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
1663ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
1664
1665ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
1666ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
1667
1668ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 };
1669ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 };
1670
1671ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
1672ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
1673
1674ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
1675ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
1676
1677/* ffi_type ffi_type_longdouble */
1678
1679ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
1680
1681/*---------------- EOF ----------------*/