cfield.c 47.8 KB
Newer Older
1 2 3 4
/*****************************************************************
  This file should be kept compatible with Python 2.3, see PEP 291.
 *****************************************************************/

5 6 7 8 9 10 11 12
#include "Python.h"

#include <ffi.h>
#ifdef MS_WIN32
#include <windows.h>
#endif
#include "ctypes.h"

13 14 15 16 17

#define CTYPES_CAPSULE_WCHAR_T "_ctypes/cfield.c wchar_t buffer from unicode"
CTYPES_CAPSULE_INSTANTIATE_DESTRUCTOR(CTYPES_CAPSULE_WCHAR_T)


18 19
/******************************************************************/
/*
20
  PyCField_Type
21 22
*/
static PyObject *
23
PyCField_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
24
{
25 26 27
    CFieldObject *obj;
    obj = (CFieldObject *)type->tp_alloc(type, 0);
    return (PyObject *)obj;
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
}

/*
 * Expects the size, index and offset for the current field in *psize and
 * *poffset, stores the total size so far in *psize, the offset for the next
 * field in *poffset, the alignment requirements for the current field in
 * *palign, and returns a field desriptor for this field.
 */
/*
 * bitfields extension:
 * bitsize != 0: this is a bit field.
 * pbitofs points to the current bit offset, this will be updated.
 * prev_desc points to the type of the previous bitfield, if any.
 */
PyObject *
43
PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
44 45 46 47 48 49 50 51 52 53 54
                Py_ssize_t *pfield_size, int bitsize, int *pbitofs,
                Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign,
                int pack, int big_endian)
{
    CFieldObject *self;
    PyObject *proto;
    Py_ssize_t size, align, length;
    SETFUNC setfunc = NULL;
    GETFUNC getfunc = NULL;
    StgDictObject *dict;
    int fieldtype;
55 56 57 58 59
#define NO_BITFIELD 0
#define NEW_BITFIELD 1
#define CONT_BITFIELD 2
#define EXPAND_BITFIELD 3

60 61 62 63 64 65 66 67 68 69 70 71 72
    self = (CFieldObject *)PyObject_CallObject((PyObject *)&PyCField_Type,
                                               NULL);
    if (self == NULL)
        return NULL;
    dict = PyType_stgdict(desc);
    if (!dict) {
        PyErr_SetString(PyExc_TypeError,
                        "has no _stginfo_");
        Py_DECREF(self);
        return NULL;
    }
    if (bitsize /* this is a bitfield request */
        && *pfield_size /* we have a bitfield open */
73
#ifdef MS_WIN32
74 75
        /* MSVC, GCC with -mms-bitfields */
        && dict->size * 8 == *pfield_size
76
#else
77 78
        /* GCC */
        && dict->size * 8 <= *pfield_size
79
#endif
80 81 82
        && (*pbitofs + bitsize) <= *pfield_size) {
        /* continue bit field */
        fieldtype = CONT_BITFIELD;
83
#ifndef MS_WIN32
84 85 86 87 88 89
    } else if (bitsize /* this is a bitfield request */
        && *pfield_size /* we have a bitfield open */
        && dict->size * 8 >= *pfield_size
        && (*pbitofs + bitsize) <= dict->size * 8) {
        /* expand bit field */
        fieldtype = EXPAND_BITFIELD;
90
#endif
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
    } else if (bitsize) {
        /* start new bitfield */
        fieldtype = NEW_BITFIELD;
        *pbitofs = 0;
        *pfield_size = dict->size * 8;
    } else {
        /* not a bit field */
        fieldtype = NO_BITFIELD;
        *pbitofs = 0;
        *pfield_size = 0;
    }

    size = dict->size;
    length = dict->length;
    proto = desc;

    /*  Field descriptors for 'c_char * n' are be scpecial cased to
        return a Python string instead of an Array object instance...
    */
    if (PyCArrayTypeObject_Check(proto)) {
        StgDictObject *adict = PyType_stgdict(proto);
        StgDictObject *idict;
        if (adict && adict->proto) {
            idict = PyType_stgdict(adict->proto);
            if (!idict) {
                PyErr_SetString(PyExc_TypeError,
                                "has no _stginfo_");
                Py_DECREF(self);
                return NULL;
            }
            if (idict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
                struct fielddesc *fd = _ctypes_get_fielddesc("s");
                getfunc = fd->getfunc;
                setfunc = fd->setfunc;
            }
126
#ifdef CTYPES_UNICODE
127 128 129 130 131
            if (idict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
                struct fielddesc *fd = _ctypes_get_fielddesc("U");
                getfunc = fd->getfunc;
                setfunc = fd->setfunc;
            }
132
#endif
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
        }
    }

    self->setfunc = setfunc;
    self->getfunc = getfunc;
    self->index = index;

    Py_INCREF(proto);
    self->proto = proto;

    switch (fieldtype) {
    case NEW_BITFIELD:
        if (big_endian)
            self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
        else
            self->size = (bitsize << 16) + *pbitofs;
        *pbitofs = bitsize;
        /* fall through */
    case NO_BITFIELD:
        if (pack)
            align = min(pack, dict->align);
        else
            align = dict->align;
        if (align && *poffset % align) {
            Py_ssize_t delta = align - (*poffset % align);
            *psize += delta;
            *poffset += delta;
        }

        if (bitsize == 0)
            self->size = size;
        *psize += size;

        self->offset = *poffset;
        *poffset += size;

        *palign = align;
        break;

    case EXPAND_BITFIELD:
        *poffset += dict->size - *pfield_size/8;
        *psize += dict->size - *pfield_size/8;

        *pfield_size = dict->size * 8;

        if (big_endian)
            self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
        else
            self->size = (bitsize << 16) + *pbitofs;

        self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
        *pbitofs += bitsize;
        break;

    case CONT_BITFIELD:
        if (big_endian)
            self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
        else
            self->size = (bitsize << 16) + *pbitofs;

        self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
        *pbitofs += bitsize;
        break;
    }

    return (PyObject *)self;
199 200 201
}

static int
202
PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
203
{
204 205 206 207 208 209 210 211 212 213 214 215
    CDataObject *dst;
    char *ptr;
    assert(CDataObject_Check(inst));
    dst = (CDataObject *)inst;
    ptr = dst->b_ptr + self->offset;
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "can't delete attribute");
        return -1;
    }
    return PyCData_set(inst, self->proto, self->setfunc, value,
                     self->index, self->size, ptr);
216 217 218
}

static PyObject *
219
PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
220
{
221 222 223 224 225 226 227 228 229
    CDataObject *src;
    if (inst == NULL) {
        Py_INCREF(self);
        return (PyObject *)self;
    }
    assert(CDataObject_Check(inst));
    src = (CDataObject *)inst;
    return PyCData_get(self->proto, self->getfunc, inst,
                     self->index, self->size, src->b_ptr + self->offset);
230 231
}

232
static PyObject *
233
PyCField_get_offset(PyObject *self, void *data)
234
{
235
    return PyInt_FromSsize_t(((CFieldObject *)self)->offset);
236 237 238
}

static PyObject *
239
PyCField_get_size(PyObject *self, void *data)
240
{
241
    return PyInt_FromSsize_t(((CFieldObject *)self)->size);
242 243
}

244
static PyGetSetDef PyCField_getset[] = {
245 246 247
    { "offset", PyCField_get_offset, NULL, "offset in bytes of this field" },
    { "size", PyCField_get_size, NULL, "size in bytes of this field" },
    { NULL, NULL, NULL, NULL },
248 249 250
};

static int
251
PyCField_traverse(CFieldObject *self, visitproc visit, void *arg)
252
{
253 254
    Py_VISIT(self->proto);
    return 0;
255 256 257
}

static int
258
PyCField_clear(CFieldObject *self)
259
{
260 261
    Py_CLEAR(self->proto);
    return 0;
262 263 264
}

static void
265
PyCField_dealloc(PyObject *self)
266
{
267 268
    PyCField_clear((CFieldObject *)self);
    self->ob_type->tp_free((PyObject *)self);
269 270 271
}

static PyObject *
272
PyCField_repr(CFieldObject *self)
273
{
274 275 276 277
    PyObject *result;
    Py_ssize_t bits = self->size >> 16;
    Py_ssize_t size = self->size & 0xFFFF;
    const char *name;
278

279
    name = ((PyTypeObject *)self->proto)->tp_name;
280

281 282
    if (bits)
        result = PyString_FromFormat(
283
#if (PY_VERSION_HEX < 0x02050000)
284
            "<Field type=%s, ofs=%d:%d, bits=%d>",
285
#else
286
            "<Field type=%s, ofs=%zd:%zd, bits=%zd>",
287
#endif
288 289 290
            name, self->offset, size, bits);
    else
        result = PyString_FromFormat(
291
#if (PY_VERSION_HEX < 0x02050000)
292
            "<Field type=%s, ofs=%d, size=%d>",
293
#else
294
            "<Field type=%s, ofs=%zd, size=%zd>",
295
#endif
296 297
            name, self->offset, size);
    return result;
298 299
}

300
PyTypeObject PyCField_Type = {
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.CField",                                   /* tp_name */
    sizeof(CFieldObject),                       /* tp_basicsize */
    0,                                          /* tp_itemsize */
    PyCField_dealloc,                                   /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_compare */
    (reprfunc)PyCField_repr,                            /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
    "Structure/Union member",                   /* tp_doc */
    (traverseproc)PyCField_traverse,                    /* tp_traverse */
    (inquiry)PyCField_clear,                            /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    0,                                          /* tp_members */
    PyCField_getset,                                    /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    (descrgetfunc)PyCField_get,                 /* tp_descr_get */
    (descrsetfunc)PyCField_set,                 /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    PyCField_new,                               /* tp_new */
    0,                                          /* tp_free */
340 341
};

342

343 344 345 346 347 348 349 350 351 352 353 354
/******************************************************************/
/*
  Accessor functions
*/

/* Derived from Modules/structmodule.c:
   Helper routine to get a Python integer and raise the appropriate error
   if it isn't one */

static int
get_long(PyObject *v, long *p)
{
355 356 357 358 359 360 361 362 363 364 365
    long x;
    if (PyFloat_Check(v)) {
        PyErr_SetString(PyExc_TypeError,
                        "int expected instead of float");
        return -1;
    }
    x = PyInt_AsUnsignedLongMask(v);
    if (x == -1 && PyErr_Occurred())
        return -1;
    *p = x;
    return 0;
366 367 368 369 370 371 372
}

/* Same, but handling unsigned long */

static int
get_ulong(PyObject *v, unsigned long *p)
{
373 374 375 376 377 378 379 380 381 382 383
    unsigned long x;
    if (PyFloat_Check(v)) {
        PyErr_SetString(PyExc_TypeError,
                        "int expected instead of float");
        return -1;
    }
    x = PyInt_AsUnsignedLongMask(v);
    if (x == (unsigned long)-1 && PyErr_Occurred())
        return -1;
    *p = x;
    return 0;
384 385 386 387 388 389 390 391 392
}

#ifdef HAVE_LONG_LONG

/* Same, but handling native long long. */

static int
get_longlong(PyObject *v, PY_LONG_LONG *p)
{
393 394 395 396 397 398 399 400 401 402 403
    PY_LONG_LONG x;
    if (PyFloat_Check(v)) {
        PyErr_SetString(PyExc_TypeError,
                        "int expected instead of float");
        return -1;
    }
    x = PyInt_AsUnsignedLongLongMask(v);
    if (x == -1 && PyErr_Occurred())
        return -1;
    *p = x;
    return 0;
404 405 406 407 408 409 410
}

/* Same, but handling native unsigned long long. */

static int
get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
{
411 412 413 414 415 416 417 418 419 420 421
    unsigned PY_LONG_LONG x;
    if (PyFloat_Check(v)) {
        PyErr_SetString(PyExc_TypeError,
                        "int expected instead of float");
        return -1;
    }
    x = PyInt_AsUnsignedLongLongMask(v);
    if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
        return -1;
    *p = x;
    return 0;
422 423 424 425 426 427 428 429 430 431 432 433
}

#endif

/*****************************************************************
 * Integer fields, with bitfield support
 */

/* how to decode the size field, for integer get/set functions */
#define LOW_BIT(x)  ((x) & 0xFFFF)
#define NUM_BITS(x) ((x) >> 16)

434
/* This seems nore a compiler issue than a Windows/non-Windows one */
435
#ifdef MS_WIN32
436
#  define BIT_MASK(size) ((1 << NUM_BITS(size))-1)
437 438 439 440 441 442 443
#else
#  define BIT_MASK(size) ((1LL << NUM_BITS(size))-1)
#endif

/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
   we must first shift left, then right.
*/
444 445 446 447 448
#define GET_BITFIELD(v, size)                                           \
    if (NUM_BITS(size)) {                                               \
        v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size));           \
        v >>= (sizeof(v)*8 - NUM_BITS(size));                           \
    }
449 450

/* This macro RETURNS the first parameter with the bit field CHANGED. */
451 452 453 454
#define SET(x, v, size)                                                 \
    (NUM_BITS(size) ?                                                   \
     ( ( x & ~(BIT_MASK(size) << LOW_BIT(size)) ) | ( (v & BIT_MASK(size)) << LOW_BIT(size) ) ) \
     : v)
455 456

/* byte swapping macros */
457 458 459
#define SWAP_2(v)                               \
    ( ( (v >> 8) & 0x00FF) |                    \
      ( (v << 8) & 0xFF00) )
460

461 462 463 464 465
#define SWAP_4(v)                       \
    ( ( (v & 0x000000FF) << 24 ) |  \
      ( (v & 0x0000FF00) <<  8 ) |  \
      ( (v & 0x00FF0000) >>  8 ) |  \
      ( ((v >> 24) & 0xFF)) )
466 467

#ifdef _MSC_VER
468 469 470 471 472 473 474 475 476
#define SWAP_8(v)                               \
    ( ( (v & 0x00000000000000FFL) << 56 ) |  \
      ( (v & 0x000000000000FF00L) << 40 ) |  \
      ( (v & 0x0000000000FF0000L) << 24 ) |  \
      ( (v & 0x00000000FF000000L) <<  8 ) |  \
      ( (v & 0x000000FF00000000L) >>  8 ) |  \
      ( (v & 0x0000FF0000000000L) >> 24 ) |  \
      ( (v & 0x00FF000000000000L) >> 40 ) |  \
      ( ((v >> 56) & 0xFF)) )
477
#else
478 479 480 481 482 483 484 485 486
#define SWAP_8(v)                               \
    ( ( (v & 0x00000000000000FFLL) << 56 ) |  \
      ( (v & 0x000000000000FF00LL) << 40 ) |  \
      ( (v & 0x0000000000FF0000LL) << 24 ) |  \
      ( (v & 0x00000000FF000000LL) <<  8 ) |  \
      ( (v & 0x000000FF00000000LL) >>  8 ) |  \
      ( (v & 0x0000FF0000000000LL) >> 24 ) |  \
      ( (v & 0x00FF000000000000LL) >> 40 ) |  \
      ( ((v >> 56) & 0xFF)) )
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
#endif

#define SWAP_INT SWAP_4

#if SIZEOF_LONG == 4
# define SWAP_LONG SWAP_4
#elif SIZEOF_LONG == 8
# define SWAP_LONG SWAP_8
#endif
/*****************************************************************
 * The setter methods return an object which must be kept alive, to keep the
 * data valid which has been stored in the memory block.  The ctypes object
 * instance inserts this object into its 'b_objects' list.
 *
 * For simple Python types like integers or characters, there is nothing that
 * has to been kept alive, so Py_None is returned in these cases.  But this
 * makes inspecting the 'b_objects' list, which is accessible from Python for
 * debugging, less useful.
 *
 * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value
 * instead of Py_None.
 */

#ifdef _CTYPES_DEBUG_KEEP
#define _RET(x) Py_INCREF(x); return x
#else
#define _RET(X) Py_INCREF(Py_None); return Py_None
#endif

/*****************************************************************
 * integer accessor methods, supporting bit fields
 */

static PyObject *
521
b_set(void *ptr, PyObject *value, Py_ssize_t size)
522
{
523 524 525 526 527
    long val;
    if (get_long(value, &val) < 0)
        return NULL;
    *(signed char *)ptr = (signed char)SET(*(signed char *)ptr, (signed char)val, size);
    _RET(value);
528 529 530 531
}


static PyObject *
532
b_get(void *ptr, Py_ssize_t size)
533
{
534 535 536
    signed char val = *(signed char *)ptr;
    GET_BITFIELD(val, size);
    return PyInt_FromLong(val);
537 538 539
}

static PyObject *
540
B_set(void *ptr, PyObject *value, Py_ssize_t size)
541
{
542 543 544 545 546 547
    unsigned long val;
    if (get_ulong(value, &val) < 0)
        return NULL;
    *(unsigned char *)ptr = (unsigned char)SET(*(unsigned char*)ptr,
                                               (unsigned short)val, size);
    _RET(value);
548 549 550 551
}


static PyObject *
552
B_get(void *ptr, Py_ssize_t size)
553
{
554 555 556
    unsigned char val = *(unsigned char *)ptr;
    GET_BITFIELD(val, size);
    return PyInt_FromLong(val);
557 558 559
}

static PyObject *
560
h_set(void *ptr, PyObject *value, Py_ssize_t size)
561
{
562 563 564 565 566 567 568 569
    long val;
    short x;
    if (get_long(value, &val) < 0)
        return NULL;
    memcpy(&x, ptr, sizeof(x));
    x = SET(x, (short)val, size);
    memcpy(ptr, &x, sizeof(x));
    _RET(value);
570 571 572 573
}


static PyObject *
574
h_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
575
{
576 577 578 579 580 581 582 583 584 585
    long val;
    short field;
    if (get_long(value, &val) < 0)
        return NULL;
    memcpy(&field, ptr, sizeof(field));
    field = SWAP_2(field);
    field = SET(field, (short)val, size);
    field = SWAP_2(field);
    memcpy(ptr, &field, sizeof(field));
    _RET(value);
586 587 588
}

static PyObject *
589
h_get(void *ptr, Py_ssize_t size)
590
{
591 592 593 594
    short val;
    memcpy(&val, ptr, sizeof(val));
    GET_BITFIELD(val, size);
    return PyInt_FromLong((long)val);
595 596 597
}

static PyObject *
598
h_get_sw(void *ptr, Py_ssize_t size)
599
{
600 601 602 603 604
    short val;
    memcpy(&val, ptr, sizeof(val));
    val = SWAP_2(val);
    GET_BITFIELD(val, size);
    return PyInt_FromLong(val);
605 606 607
}

static PyObject *
608
H_set(void *ptr, PyObject *value, Py_ssize_t size)
609
{
610 611 612 613 614 615 616 617
    unsigned long val;
    unsigned short x;
    if (get_ulong(value, &val) < 0)
        return NULL;
    memcpy(&x, ptr, sizeof(x));
    x = SET(x, (unsigned short)val, size);
    memcpy(ptr, &x, sizeof(x));
    _RET(value);
618 619 620
}

static PyObject *
621
H_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
622
{
623 624 625 626 627 628 629 630 631 632
    unsigned long val;
    unsigned short field;
    if (get_ulong(value, &val) < 0)
        return NULL;
    memcpy(&field, ptr, sizeof(field));
    field = SWAP_2(field);
    field = SET(field, (unsigned short)val, size);
    field = SWAP_2(field);
    memcpy(ptr, &field, sizeof(field));
    _RET(value);
633 634 635 636
}


static PyObject *
637
H_get(void *ptr, Py_ssize_t size)
638
{
639 640 641 642
    unsigned short val;
    memcpy(&val, ptr, sizeof(val));
    GET_BITFIELD(val, size);
    return PyInt_FromLong(val);
643 644 645
}

static PyObject *
646
H_get_sw(void *ptr, Py_ssize_t size)
647
{
648 649 650 651 652
    unsigned short val;
    memcpy(&val, ptr, sizeof(val));
    val = SWAP_2(val);
    GET_BITFIELD(val, size);
    return PyInt_FromLong(val);
653 654 655
}

static PyObject *
656
i_set(void *ptr, PyObject *value, Py_ssize_t size)
657
{
658 659 660 661 662 663 664 665
    long val;
    int x;
    if (get_long(value, &val) < 0)
        return NULL;
    memcpy(&x, ptr, sizeof(x));
    x = SET(x, (int)val, size);
    memcpy(ptr, &x, sizeof(x));
    _RET(value);
666 667 668
}

static PyObject *
669
i_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
670
{
671 672 673 674 675 676 677 678 679 680
    long val;
    int field;
    if (get_long(value, &val) < 0)
        return NULL;
    memcpy(&field, ptr, sizeof(field));
    field = SWAP_INT(field);
    field = SET(field, (int)val, size);
    field = SWAP_INT(field);
    memcpy(ptr, &field, sizeof(field));
    _RET(value);
681 682 683 684
}


static PyObject *
685
i_get(void *ptr, Py_ssize_t size)
686
{
687 688 689 690
    int val;
    memcpy(&val, ptr, sizeof(val));
    GET_BITFIELD(val, size);
    return PyInt_FromLong(val);
691 692 693
}

static PyObject *
694
i_get_sw(void *ptr, Py_ssize_t size)
695
{
696 697 698 699 700
    int val;
    memcpy(&val, ptr, sizeof(val));
    val = SWAP_INT(val);
    GET_BITFIELD(val, size);
    return PyInt_FromLong(val);
701 702 703 704 705
}

#ifdef MS_WIN32
/* short BOOL - VARIANT_BOOL */
static PyObject *
706
vBOOL_set(void *ptr, PyObject *value, Py_ssize_t size)
707
{
708 709 710 711 712 713 714 715 716 717
    switch (PyObject_IsTrue(value)) {
    case -1:
        return NULL;
    case 0:
        *(short int *)ptr = VARIANT_FALSE;
        _RET(value);
    default:
        *(short int *)ptr = VARIANT_TRUE;
        _RET(value);
    }
718 719 720
}

static PyObject *
721
vBOOL_get(void *ptr, Py_ssize_t size)
722
{
723
    return PyBool_FromLong((long)*(short int *)ptr);
724 725 726
}
#endif

727 728 729 730 731 732 733 734 735
#ifdef HAVE_C99_BOOL
#define BOOL_TYPE _Bool
#else
#define BOOL_TYPE char
#undef SIZEOF__BOOL
#define SIZEOF__BOOL 1
#endif

static PyObject *
736
bool_set(void *ptr, PyObject *value, Py_ssize_t size)
737
{
738 739 740 741 742 743 744 745 746 747
    switch (PyObject_IsTrue(value)) {
    case -1:
        return NULL;
    case 0:
        *(BOOL_TYPE *)ptr = 0;
        _RET(value);
    default:
        *(BOOL_TYPE *)ptr = 1;
        _RET(value);
    }
748 749 750
}

static PyObject *
751
bool_get(void *ptr, Py_ssize_t size)
752
{
753
    return PyBool_FromLong((long)*(BOOL_TYPE *)ptr);
754 755
}

756
static PyObject *
757
I_set(void *ptr, PyObject *value, Py_ssize_t size)
758
{
759 760 761 762 763 764 765 766
    unsigned long val;
    unsigned int x;
    if (get_ulong(value, &val) < 0)
        return  NULL;
    memcpy(&x, ptr, sizeof(x));
    x = SET(x, (unsigned int)val, size);
    memcpy(ptr, &x, sizeof(x));
    _RET(value);
767 768 769
}

static PyObject *
770
I_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
771
{
772 773 774 775 776 777 778 779 780
    unsigned long val;
    unsigned int field;
    if (get_ulong(value, &val) < 0)
        return  NULL;
    memcpy(&field, ptr, sizeof(field));
    field = (unsigned int)SET(field, (unsigned int)val, size);
    field = SWAP_INT(field);
    memcpy(ptr, &field, sizeof(field));
    _RET(value);
781 782 783 784
}


static PyObject *
785
I_get(void *ptr, Py_ssize_t size)
786
{
787 788 789 790
    unsigned int val;
    memcpy(&val, ptr, sizeof(val));
    GET_BITFIELD(val, size);
    return PyLong_FromUnsignedLong(val);
791 792 793
}

static PyObject *
794
I_get_sw(void *ptr, Py_ssize_t size)
795
{
796 797 798 799 800
    unsigned int val;
    memcpy(&val, ptr, sizeof(val));
    val = SWAP_INT(val);
    GET_BITFIELD(val, size);
    return PyLong_FromUnsignedLong(val);
801 802 803
}

static PyObject *
804
l_set(void *ptr, PyObject *value, Py_ssize_t size)
805
{
806 807 808 809 810 811 812 813
    long val;
    long x;
    if (get_long(value, &val) < 0)
        return NULL;
    memcpy(&x, ptr, sizeof(x));
    x = SET(x, val, size);
    memcpy(ptr, &x, sizeof(x));
    _RET(value);
814 815 816
}

static PyObject *
817
l_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
818
{
819 820 821 822 823 824 825 826 827 828
    long val;
    long field;
    if (get_long(value, &val) < 0)
        return NULL;
    memcpy(&field, ptr, sizeof(field));
    field = SWAP_LONG(field);
    field = (long)SET(field, val, size);
    field = SWAP_LONG(field);
    memcpy(ptr, &field, sizeof(field));
    _RET(value);
829 830 831 832
}


static PyObject *
833
l_get(void *ptr, Py_ssize_t size)
834
{
835 836 837 838
    long val;
    memcpy(&val, ptr, sizeof(val));
    GET_BITFIELD(val, size);
    return PyInt_FromLong(val);
839 840 841
}

static PyObject *
842
l_get_sw(void *ptr, Py_ssize_t size)
843
{
844 845 846 847 848
    long val;
    memcpy(&val, ptr, sizeof(val));
    val = SWAP_LONG(val);
    GET_BITFIELD(val, size);
    return PyInt_FromLong(val);
849 850 851
}

static PyObject *
852
L_set(void *ptr, PyObject *value, Py_ssize_t size)
853
{
854 855 856 857 858 859 860 861
    unsigned long val;
    unsigned long x;
    if (get_ulong(value, &val) < 0)
        return  NULL;
    memcpy(&x, ptr, sizeof(x));
    x = SET(x, val, size);
    memcpy(ptr, &x, sizeof(x));
    _RET(value);
862 863 864
}

static PyObject *
865
L_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
866
{
867 868 869 870 871 872 873 874 875 876
    unsigned long val;
    unsigned long field;
    if (get_ulong(value, &val) < 0)
        return  NULL;
    memcpy(&field, ptr, sizeof(field));
    field = SWAP_LONG(field);
    field = (unsigned long)SET(field, val, size);
    field = SWAP_LONG(field);
    memcpy(ptr, &field, sizeof(field));
    _RET(value);
877 878 879 880
}


static PyObject *
881
L_get(void *ptr, Py_ssize_t size)
882
{
883 884 885 886
    unsigned long val;
    memcpy(&val, ptr, sizeof(val));
    GET_BITFIELD(val, size);
    return PyLong_FromUnsignedLong(val);
887 888 889
}

static PyObject *
890
L_get_sw(void *ptr, Py_ssize_t size)
891
{
892 893 894 895 896
    unsigned long val;
    memcpy(&val, ptr, sizeof(val));
    val = SWAP_LONG(val);
    GET_BITFIELD(val, size);
    return PyLong_FromUnsignedLong(val);
897 898 899 900
}

#ifdef HAVE_LONG_LONG
static PyObject *
901
q_set(void *ptr, PyObject *value, Py_ssize_t size)
902
{
903 904 905 906 907 908 909 910
    PY_LONG_LONG val;
    PY_LONG_LONG x;
    if (get_longlong(value, &val) < 0)
        return NULL;
    memcpy(&x, ptr, sizeof(x));
    x = SET(x, val, size);
    memcpy(ptr, &x, sizeof(x));
    _RET(value);
911 912 913
}

static PyObject *
914
q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
915
{
916 917 918 919 920 921 922 923 924 925
    PY_LONG_LONG val;
    PY_LONG_LONG field;
    if (get_longlong(value, &val) < 0)
        return NULL;
    memcpy(&field, ptr, sizeof(field));
    field = SWAP_8(field);
    field = (PY_LONG_LONG)SET(field, val, size);
    field = SWAP_8(field);
    memcpy(ptr, &field, sizeof(field));
    _RET(value);
926 927 928
}

static PyObject *
929
q_get(void *ptr, Py_ssize_t size)
930
{
931 932 933 934
    PY_LONG_LONG val;
    memcpy(&val, ptr, sizeof(val));
    GET_BITFIELD(val, size);
    return PyLong_FromLongLong(val);
935 936 937
}

static PyObject *
938
q_get_sw(void *ptr, Py_ssize_t size)
939
{
940 941 942 943 944
    PY_LONG_LONG val;
    memcpy(&val, ptr, sizeof(val));
    val = SWAP_8(val);
    GET_BITFIELD(val, size);
    return PyLong_FromLongLong(val);
945 946 947
}

static PyObject *
948
Q_set(void *ptr, PyObject *value, Py_ssize_t size)
949
{
950 951 952 953 954 955 956 957
    unsigned PY_LONG_LONG val;
    unsigned PY_LONG_LONG x;
    if (get_ulonglong(value, &val) < 0)
        return NULL;
    memcpy(&x, ptr, sizeof(x));
    x = SET(x, val, size);
    memcpy(ptr, &x, sizeof(x));
    _RET(value);
958 959 960
}

static PyObject *
961
Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
962
{
963 964 965 966 967 968 969 970 971 972
    unsigned PY_LONG_LONG val;
    unsigned PY_LONG_LONG field;
    if (get_ulonglong(value, &val) < 0)
        return NULL;
    memcpy(&field, ptr, sizeof(field));
    field = SWAP_8(field);
    field = (unsigned PY_LONG_LONG)SET(field, val, size);
    field = SWAP_8(field);
    memcpy(ptr, &field, sizeof(field));
    _RET(value);
973 974 975
}

static PyObject *
976
Q_get(void *ptr, Py_ssize_t size)
977
{
978 979 980 981
    unsigned PY_LONG_LONG val;
    memcpy(&val, ptr, sizeof(val));
    GET_BITFIELD(val, size);
    return PyLong_FromUnsignedLongLong(val);
982 983 984
}

static PyObject *
985
Q_get_sw(void *ptr, Py_ssize_t size)
986
{
987 988 989 990 991
    unsigned PY_LONG_LONG val;
    memcpy(&val, ptr, sizeof(val));
    val = SWAP_8(val);
    GET_BITFIELD(val, size);
    return PyLong_FromUnsignedLongLong(val);
992 993 994 995 996 997 998 999
}
#endif

/*****************************************************************
 * non-integer accessor methods, not supporting bit fields
 */


1000
static PyObject *
1001
g_set(void *ptr, PyObject *value, Py_ssize_t size)
1002
{
1003
    long double x;
1004

1005 1006 1007 1008 1009 1010 1011 1012 1013
    x = PyFloat_AsDouble(value);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_Format(PyExc_TypeError,
                     " float expected instead of %s instance",
                     value->ob_type->tp_name);
        return NULL;
    }
    memcpy(ptr, &x, sizeof(long double));
    _RET(value);
1014 1015 1016
}

static PyObject *
1017
g_get(void *ptr, Py_ssize_t size)
1018
{
1019 1020 1021
    long double val;
    memcpy(&val, ptr, sizeof(long double));
    return PyFloat_FromDouble(val);
1022
}
1023 1024

static PyObject *
1025
d_set(void *ptr, PyObject *value, Py_ssize_t size)
1026
{
1027
    double x;
1028

1029 1030 1031 1032 1033 1034 1035 1036 1037
    x = PyFloat_AsDouble(value);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_Format(PyExc_TypeError,
                     " float expected instead of %s instance",
                     value->ob_type->tp_name);
        return NULL;
    }
    memcpy(ptr, &x, sizeof(double));
    _RET(value);
1038 1039 1040
}

static PyObject *
1041
d_get(void *ptr, Py_ssize_t size)
1042
{
1043 1044 1045
    double val;
    memcpy(&val, ptr, sizeof(val));
    return PyFloat_FromDouble(val);
1046 1047 1048
}

static PyObject *
1049
d_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
1050
{
1051
    double x;
1052

1053 1054 1055 1056 1057 1058 1059
    x = PyFloat_AsDouble(value);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_Format(PyExc_TypeError,
                     " float expected instead of %s instance",
                     value->ob_type->tp_name);
        return NULL;
    }
1060
#ifdef WORDS_BIGENDIAN
1061 1062
    if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1))
        return NULL;
1063
#else
1064 1065
    if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0))
        return NULL;
1066
#endif
1067
    _RET(value);
1068 1069 1070
}

static PyObject *
1071
d_get_sw(void *ptr, Py_ssize_t size)
1072 1073
{
#ifdef WORDS_BIGENDIAN
1074
    return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1));
1075
#else
1076
    return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0));
1077 1078 1079 1080
#endif
}

static PyObject *
1081
f_set(void *ptr, PyObject *value, Py_ssize_t size)
1082
{
1083
    float x;
1084

1085 1086 1087 1088 1089 1090 1091 1092 1093
    x = (float)PyFloat_AsDouble(value);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_Format(PyExc_TypeError,
                     " float expected instead of %s instance",
                     value->ob_type->tp_name);
        return NULL;
    }
    memcpy(ptr, &x, sizeof(x));
    _RET(value);
1094 1095 1096
}

static PyObject *
1097
f_get(void *ptr, Py_ssize_t size)
1098
{
1099 1100 1101
    float val;
    memcpy(&val, ptr, sizeof(val));
    return PyFloat_FromDouble(val);
1102 1103 1104
}

static PyObject *
1105
f_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
1106
{
1107
    float x;
1108

1109 1110 1111 1112 1113 1114 1115
    x = (float)PyFloat_AsDouble(value);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_Format(PyExc_TypeError,
                     " float expected instead of %s instance",
                     value->ob_type->tp_name);
        return NULL;
    }
1116
#ifdef WORDS_BIGENDIAN
1117 1118
    if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1))
        return NULL;
1119
#else
1120 1121
    if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0))
        return NULL;
1122
#endif
1123
    _RET(value);
1124 1125 1126
}

static PyObject *
1127
f_get_sw(void *ptr, Py_ssize_t size)
1128 1129
{
#ifdef WORDS_BIGENDIAN
1130
    return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1));
1131
#else
1132
    return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0));
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
#endif
}

/*
  py_object refcounts:

  1. If we have a py_object instance, O_get must Py_INCREF the returned
  object, of course.  If O_get is called from a function result, no py_object
  instance is created - so callproc.c::GetResult has to call Py_DECREF.

  2. The memory block in py_object owns a refcount.  So, py_object must call
  Py_DECREF on destruction.  Maybe only when b_needsfree is non-zero.
*/
static PyObject *
1147
O_get(void *ptr, Py_ssize_t size)
1148
{
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158
    PyObject *ob = *(PyObject **)ptr;
    if (ob == NULL) {
        if (!PyErr_Occurred())
            /* Set an error if not yet set */
            PyErr_SetString(PyExc_ValueError,
                            "PyObject is NULL");
        return NULL;
    }
    Py_INCREF(ob);
    return ob;
1159 1160 1161
}

static PyObject *
1162
O_set(void *ptr, PyObject *value, Py_ssize_t size)
1163
{
1164 1165 1166 1167
    /* Hm, does the memory block need it's own refcount or not? */
    *(PyObject **)ptr = value;
    Py_INCREF(value);
    return value;
1168 1169 1170 1171
}


static PyObject *
1172
c_set(void *ptr, PyObject *value, Py_ssize_t size)
1173
{
1174 1175 1176 1177 1178 1179 1180
    if (!PyString_Check(value) || (1 != PyString_Size(value))) {
        PyErr_Format(PyExc_TypeError,
                     "one character string expected");
        return NULL;
    }
    *(char *)ptr = PyString_AS_STRING(value)[0];
    _RET(value);
1181 1182 1183 1184
}


static PyObject *
1185
c_get(void *ptr, Py_ssize_t size)
1186
{
1187
    return PyString_FromStringAndSize((char *)ptr, 1);
1188 1189 1190 1191 1192
}

#ifdef CTYPES_UNICODE
/* u - a single wchar_t character */
static PyObject *
1193
u_set(void *ptr, PyObject *value, Py_ssize_t size)
1194
{
1195
    Py_ssize_t len;
1196

1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
    if (PyString_Check(value)) {
        value = PyUnicode_FromEncodedObject(value,
                                            _ctypes_conversion_encoding,
                                            _ctypes_conversion_errors);
        if (!value)
            return NULL;
    } else if (!PyUnicode_Check(value)) {
        PyErr_Format(PyExc_TypeError,
                        "unicode string expected instead of %s instance",
                        value->ob_type->tp_name);
        return NULL;
    } else
        Py_INCREF(value);
1210

1211 1212 1213 1214 1215 1216 1217
    len = PyUnicode_GET_SIZE(value);
    if (len != 1) {
        Py_DECREF(value);
        PyErr_SetString(PyExc_TypeError,
                        "one character unicode string expected");
        return NULL;
    }
1218

1219 1220
    *(wchar_t *)ptr = PyUnicode_AS_UNICODE(value)[0];
    Py_DECREF(value);
1221

1222
    _RET(value);
1223 1224 1225 1226
}


static PyObject *
1227
u_get(void *ptr, Py_ssize_t size)
1228
{
1229
    return PyUnicode_FromWideChar((wchar_t *)ptr, 1);
1230 1231 1232 1233
}

/* U - a unicode string */
static PyObject *
1234
U_get(void *ptr, Py_ssize_t size)
1235
{
1236 1237 1238
    PyObject *result;
    Py_ssize_t len;
    Py_UNICODE *p;
1239

1240
    size /= sizeof(wchar_t); /* we count character units here, not bytes */
1241

1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
    result = PyUnicode_FromWideChar((wchar_t *)ptr, size);
    if (!result)
        return NULL;
    /* We need 'result' to be able to count the characters with wcslen,
       since ptr may not be NUL terminated.  If the length is smaller (if
       it was actually NUL terminated, we construct a new one and throw
       away the result.
    */
    /* chop off at the first NUL character, if any. */
    p = PyUnicode_AS_UNICODE(result);
    for (len = 0; len < size; ++len)
        if (!p[len])
            break;
1255

1256 1257 1258 1259 1260 1261
    if (len < size) {
        PyObject *ob = PyUnicode_FromWideChar((wchar_t *)ptr, len);
        Py_DECREF(result);
        return ob;
    }
    return result;
1262 1263 1264
}

static PyObject *
1265
U_set(void *ptr, PyObject *value, Py_ssize_t length)
1266
{
1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287
    Py_ssize_t size;

    /* It's easier to calculate in characters than in bytes */
    length /= sizeof(wchar_t);

    if (PyString_Check(value)) {
        value = PyUnicode_FromEncodedObject(value,
                                            _ctypes_conversion_encoding,
                                            _ctypes_conversion_errors);
        if (!value)
            return NULL;
    } else if (!PyUnicode_Check(value)) {
        PyErr_Format(PyExc_TypeError,
                        "unicode string expected instead of %s instance",
                        value->ob_type->tp_name);
        return NULL;
    } else
        Py_INCREF(value);
    size = PyUnicode_GET_SIZE(value);
    if (size > length) {
        PyErr_Format(PyExc_ValueError,
1288
#if (PY_VERSION_HEX < 0x02050000)
1289
                     "string too long (%d, maximum length %d)",
1290
#else
1291
                     "string too long (%zd, maximum length %zd)",
1292
#endif
1293 1294 1295 1296 1297 1298 1299 1300
                     size, length);
        Py_DECREF(value);
        return NULL;
    } else if (size < length-1)
        /* copy terminating NUL character if there is space */
        size += 1;
    PyUnicode_AsWideChar((PyUnicodeObject *)value, (wchar_t *)ptr, size);
    return value;
1301 1302 1303 1304 1305
}

#endif

static PyObject *
1306
s_get(void *ptr, Py_ssize_t size)
1307
{
1308 1309
    PyObject *result;
    size_t slen;
1310

1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325
    result = PyString_FromString((char *)ptr);
    if (!result)
        return NULL;
    /* chop off at the first NUL character, if any.
     * On error, result will be deallocated and set to NULL.
     */
    slen = strlen(PyString_AS_STRING(result));
    size = min(size, (Py_ssize_t)slen);
    if (result->ob_refcnt == 1) {
        /* shorten the result */
        _PyString_Resize(&result, size);
        return result;
    } else
        /* cannot shorten the result */
        return PyString_FromStringAndSize(ptr, size);
1326 1327 1328
}

static PyObject *
1329
s_set(void *ptr, PyObject *value, Py_ssize_t length)
1330
{
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
    char *data;
    Py_ssize_t size;

    data = PyString_AsString(value);
    if (!data)
        return NULL;
    size = strlen(data);
    if (size < length) {
        /* This will copy the leading NUL character
         * if there is space for it.
         */
        ++size;
    } else if (size > length) {
        PyErr_Format(PyExc_ValueError,
1345
#if (PY_VERSION_HEX < 0x02050000)
1346
                     "string too long (%d, maximum length %d)",
1347
#else
1348
                     "string too long (%zd, maximum length %zd)",
1349
#endif
1350 1351 1352 1353 1354 1355
                     size, length);
        return NULL;
    }
    /* Also copy the terminating NUL character if there is space */
    memcpy((char *)ptr, data, size);
    _RET(value);
1356 1357 1358
}

static PyObject *
1359
z_set(void *ptr, PyObject *value, Py_ssize_t size)
1360
{
1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378
    if (value == Py_None) {
        *(char **)ptr = NULL;
        Py_INCREF(value);
        return value;
    }
    if (PyString_Check(value)) {
        *(char **)ptr = PyString_AS_STRING(value);
        Py_INCREF(value);
        return value;
    } else if (PyUnicode_Check(value)) {
        PyObject *str = PyUnicode_AsEncodedString(value,
                                                  _ctypes_conversion_encoding,
                                                  _ctypes_conversion_errors);
        if (str == NULL)
            return NULL;
        *(char **)ptr = PyString_AS_STRING(str);
        return str;
    } else if (PyInt_Check(value) || PyLong_Check(value)) {
1379
#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
1380
        *(char **)ptr = (char *)PyInt_AsUnsignedLongLongMask(value);
1381
#else
1382
        *(char **)ptr = (char *)PyInt_AsUnsignedLongMask(value);
1383
#endif
1384 1385 1386 1387 1388 1389
        _RET(value);
    }
    PyErr_Format(PyExc_TypeError,
                 "string or integer address expected instead of %s instance",
                 value->ob_type->tp_name);
    return NULL;
1390 1391 1392
}

static PyObject *
1393
z_get(void *ptr, Py_ssize_t size)
1394
{
1395 1396
    /* XXX What about invalid pointers ??? */
    if (*(void **)ptr) {
1397
#if defined(MS_WIN32) && !defined(_WIN32_WCE)
1398 1399 1400 1401 1402 1403
        if (IsBadStringPtrA(*(char **)ptr, -1)) {
            PyErr_Format(PyExc_ValueError,
                         "invalid string pointer %p",
                         *(char **)ptr);
            return NULL;
        }
1404
#endif
1405 1406 1407 1408 1409
        return PyString_FromString(*(char **)ptr);
    } else {
        Py_INCREF(Py_None);
        return Py_None;
    }
1410 1411 1412 1413
}

#ifdef CTYPES_UNICODE
static PyObject *
1414
Z_set(void *ptr, PyObject *value, Py_ssize_t size)
1415
{
1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427
    if (value == Py_None) {
        *(wchar_t **)ptr = NULL;
        Py_INCREF(value);
        return value;
    }
    if (PyString_Check(value)) {
        value = PyUnicode_FromEncodedObject(value,
                                            _ctypes_conversion_encoding,
                                            _ctypes_conversion_errors);
        if (!value)
            return NULL;
    } else if (PyInt_Check(value) || PyLong_Check(value)) {
1428
#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
1429
        *(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongLongMask(value);
1430
#else
1431
        *(wchar_t **)ptr = (wchar_t *)PyInt_AsUnsignedLongMask(value);
1432
#endif
1433 1434 1435 1436 1437 1438 1439 1440 1441
        Py_INCREF(Py_None);
        return Py_None;
    } else if (!PyUnicode_Check(value)) {
        PyErr_Format(PyExc_TypeError,
                     "unicode string or integer address expected instead of %s instance",
                     value->ob_type->tp_name);
        return NULL;
    } else
        Py_INCREF(value);
1442
#ifdef HAVE_USABLE_WCHAR_T
1443 1444 1445 1446 1447 1448
    /* HAVE_USABLE_WCHAR_T means that Py_UNICODE and wchar_t is the same
       type.  So we can copy directly.  Hm, are unicode objects always NUL
       terminated in Python, internally?
     */
    *(wchar_t **)ptr = PyUnicode_AS_UNICODE(value);
    return value;
1449
#else
1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480
    {
        /* We must create a wchar_t* buffer from the unicode object,
           and keep it alive */
        PyObject *keep;
        wchar_t *buffer;

        int size = PyUnicode_GET_SIZE(value);
        size += 1; /* terminating NUL */
        size *= sizeof(wchar_t);
        buffer = (wchar_t *)PyMem_Malloc(size);
        if (!buffer) {
            Py_DECREF(value);
            return PyErr_NoMemory();
        }
        memset(buffer, 0, size);
        keep = CAPSULE_NEW(buffer, CTYPES_CAPSULE_WCHAR_T);
        if (!keep) {
            Py_DECREF(value);
            PyMem_Free(buffer);
            return NULL;
        }
        *(wchar_t **)ptr = (wchar_t *)buffer;
        if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)value,
                                       buffer, PyUnicode_GET_SIZE(value))) {
            Py_DECREF(value);
            Py_DECREF(keep);
            return NULL;
        }
        Py_DECREF(value);
        return keep;
    }
1481 1482 1483 1484
#endif
}

static PyObject *
1485
Z_get(void *ptr, Py_ssize_t size)
1486
{
1487 1488 1489
    wchar_t *p;
    p = *(wchar_t **)ptr;
    if (p) {
1490
#if defined(MS_WIN32) && !defined(_WIN32_WCE)
1491 1492 1493 1494 1495 1496
        if (IsBadStringPtrW(*(wchar_t **)ptr, -1)) {
            PyErr_Format(PyExc_ValueError,
                         "invalid string pointer %p",
                         *(wchar_t **)ptr);
            return NULL;
        }
1497
#endif
1498 1499 1500 1501 1502
        return PyUnicode_FromWideChar(p, wcslen(p));
    } else {
        Py_INCREF(Py_None);
        return Py_None;
    }
1503 1504 1505 1506 1507
}
#endif

#ifdef MS_WIN32
static PyObject *
1508
BSTR_set(void *ptr, PyObject *value, Py_ssize_t size)
1509
{
1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551
    BSTR bstr;

    /* convert value into a PyUnicodeObject or NULL */
    if (Py_None == value) {
        value = NULL;
    } else if (PyString_Check(value)) {
        value = PyUnicode_FromEncodedObject(value,
                                            _ctypes_conversion_encoding,
                                            _ctypes_conversion_errors);
        if (!value)
            return NULL;
    } else if (PyUnicode_Check(value)) {
        Py_INCREF(value); /* for the descref below */
    } else {
        PyErr_Format(PyExc_TypeError,
                        "unicode string expected instead of %s instance",
                        value->ob_type->tp_name);
        return NULL;
    }

    /* create a BSTR from value */
    if (value) {
        Py_ssize_t size = PyUnicode_GET_SIZE(value);
        if ((unsigned) size != size) {
            PyErr_SetString(PyExc_ValueError, "String too long for BSTR");
            return NULL;
        }
        bstr = SysAllocStringLen(PyUnicode_AS_UNICODE(value),
                                 (unsigned)size);
        Py_DECREF(value);
    } else
        bstr = NULL;

    /* free the previous contents, if any */
    if (*(BSTR *)ptr)
        SysFreeString(*(BSTR *)ptr);

    /* and store it */
    *(BSTR *)ptr = bstr;

    /* We don't need to keep any other object */
    _RET(value);
1552 1553 1554 1555
}


static PyObject *
1556
BSTR_get(void *ptr, Py_ssize_t size)
1557
{
1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
    BSTR p;
    p = *(BSTR *)ptr;
    if (p)
        return PyUnicode_FromWideChar(p, SysStringLen(p));
    else {
        /* Hm, it seems NULL pointer and zero length string are the
           same in BSTR, see Don Box, p 81
        */
        Py_INCREF(Py_None);
        return Py_None;
    }
1569 1570 1571 1572
}
#endif

static PyObject *
1573
P_set(void *ptr, PyObject *value, Py_ssize_t size)
1574
{
1575 1576 1577 1578 1579
    void *v;
    if (value == Py_None) {
        *(void **)ptr = NULL;
        _RET(value);
    }
1580

1581 1582 1583 1584 1585
    if (!PyInt_Check(value) && !PyLong_Check(value)) {
        PyErr_SetString(PyExc_TypeError,
                        "cannot be converted to pointer");
        return NULL;
    }
1586 1587

#if SIZEOF_VOID_P <= SIZEOF_LONG
1588
    v = (void *)PyInt_AsUnsignedLongMask(value);
1589 1590 1591 1592 1593 1594
#else
#ifndef HAVE_LONG_LONG
#   error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
#elif SIZEOF_LONG_LONG < SIZEOF_VOID_P
#   error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
#endif
1595
    v = (void *)PyInt_AsUnsignedLongLongMask(value);
1596 1597
#endif

1598 1599
    if (PyErr_Occurred())
        return NULL;
1600

1601 1602
    *(void **)ptr = v;
    _RET(value);
1603 1604 1605
}

static PyObject *
1606
P_get(void *ptr, Py_ssize_t size)
1607
{
1608 1609 1610 1611 1612
    if (*(void **)ptr == NULL) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    return PyLong_FromVoidPtr(*(void **)ptr);
1613 1614 1615
}

static struct fielddesc formattable[] = {
1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626
    { 's', s_set, s_get, &ffi_type_pointer},
    { 'b', b_set, b_get, &ffi_type_schar},
    { 'B', B_set, B_get, &ffi_type_uchar},
    { 'c', c_set, c_get, &ffi_type_schar},
    { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw},
    { 'g', g_set, g_get, &ffi_type_longdouble},
    { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw},
    { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw},
    { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw},
    { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw},
    { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw},
1627 1628 1629
/* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
/* As soon as we can get rid of the type codes, this is no longer a problem */
#if SIZEOF_LONG == 4
1630 1631
    { 'l', l_set, l_get, &ffi_type_sint32, l_set_sw, l_get_sw},
    { 'L', L_set, L_get, &ffi_type_uint32, L_set_sw, L_get_sw},
1632
#elif SIZEOF_LONG == 8
1633 1634
    { 'l', l_set, l_get, &ffi_type_sint64, l_set_sw, l_get_sw},
    { 'L', L_set, L_get, &ffi_type_uint64, L_set_sw, L_get_sw},
1635 1636 1637 1638
#else
# error
#endif
#ifdef HAVE_LONG_LONG
1639
#if SIZEOF_LONG_LONG == 8
1640 1641
    { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw},
    { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw},
1642 1643 1644
#else
# error
#endif
1645
#endif
1646 1647
    { 'P', P_set, P_get, &ffi_type_pointer},
    { 'z', z_set, z_get, &ffi_type_pointer},
1648
#ifdef CTYPES_UNICODE
1649 1650 1651
    { 'u', u_set, u_get, NULL}, /* ffi_type set later */
    { 'U', U_set, U_get, &ffi_type_pointer},
    { 'Z', Z_set, Z_get, &ffi_type_pointer},
1652 1653
#endif
#ifdef MS_WIN32
1654 1655
    { 'X', BSTR_set, BSTR_get, &ffi_type_pointer},
    { 'v', vBOOL_set, vBOOL_get, &ffi_type_sshort},
1656
#endif
1657
#if SIZEOF__BOOL == 1
1658
    { '?', bool_set, bool_get, &ffi_type_uchar}, /* Also fallback for no native _Bool support */
1659
#elif SIZEOF__BOOL == SIZEOF_SHORT
1660
    { '?', bool_set, bool_get, &ffi_type_ushort},
1661
#elif SIZEOF__BOOL == SIZEOF_INT
1662
    { '?', bool_set, bool_get, &ffi_type_uint, I_set_sw, I_get_sw},
1663
#elif SIZEOF__BOOL == SIZEOF_LONG
1664
    { '?', bool_set, bool_get, &ffi_type_ulong, L_set_sw, L_get_sw},
1665
#elif SIZEOF__BOOL == SIZEOF_LONG_LONG
1666
    { '?', bool_set, bool_get, &ffi_type_ulong, Q_set_sw, Q_get_sw},
1667
#endif /* SIZEOF__BOOL */
1668 1669
    { 'O', O_set, O_get, &ffi_type_pointer},
    { 0, NULL, NULL, NULL},
1670 1671 1672 1673 1674 1675 1676 1677
};

/*
  Ideas: Implement VARIANT in this table, using 'V' code.
  Use '?' as code for BOOL.
*/

struct fielddesc *
1678
_ctypes_get_fielddesc(char *fmt)
1679
{
1680 1681
    static int initialized = 0;
    struct fielddesc *table = formattable;
1682

1683 1684
    if (!initialized) {
        initialized = 1;
1685
#ifdef CTYPES_UNICODE
1686 1687 1688 1689 1690 1691
        if (sizeof(wchar_t) == sizeof(short))
            _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort;
        else if (sizeof(wchar_t) == sizeof(int))
            _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint;
        else if (sizeof(wchar_t) == sizeof(long))
            _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong;
1692
#endif
1693
    }
1694

1695 1696 1697 1698 1699
    for (; table->code; ++table) {
        if (table->code == fmt[0])
            return table;
    }
    return NULL;
1700 1701 1702 1703 1704 1705 1706 1707
}

typedef struct { char c; char x; } s_char;
typedef struct { char c; short x; } s_short;
typedef struct { char c; int x; } s_int;
typedef struct { char c; long x; } s_long;
typedef struct { char c; float x; } s_float;
typedef struct { char c; double x; } s_double;
1708
typedef struct { char c; long double x; } s_long_double;
1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719
typedef struct { char c; char *x; } s_char_p;
typedef struct { char c; void *x; } s_void_p;

/*
#define CHAR_ALIGN (sizeof(s_char) - sizeof(char))
#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
#define INT_ALIGN (sizeof(s_int) - sizeof(int))
#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
*/
#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
1720 1721
#define LONGDOUBLE_ALIGN (sizeof(s_long_double) - sizeof(long double))

1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742
/* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */
#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*))

/*
#ifdef HAVE_USABLE_WCHAR_T
typedef struct { char c; wchar_t x; } s_wchar;
typedef struct { char c; wchar_t *x; } s_wchar_p;

#define WCHAR_ALIGN (sizeof(s_wchar) - sizeof(wchar_t))
#define WCHAR_P_ALIGN (sizeof(s_wchar_p) - sizeof(wchar_t*))
#endif
*/

#ifdef HAVE_LONG_LONG
typedef struct { char c; PY_LONG_LONG x; } s_long_long;
#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
#endif

/* from ffi.h:
typedef struct _ffi_type
{
1743 1744 1745 1746
    size_t size;
    unsigned short alignment;
    unsigned short type;
    struct _ffi_type **elements;
1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766
} ffi_type;
*/

/* align and size are bogus for void, but they must not be zero */
ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };

ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };

ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };

ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 };
ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 };

ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };

ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
1767 1768 1769 1770

#ifdef ffi_type_longdouble
#undef ffi_type_longdouble
#endif
1771
  /* This is already defined on OSX */
1772
ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN,
1773
                                 FFI_TYPE_LONGDOUBLE };
1774 1775 1776 1777

ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };

/*---------------- EOF ----------------*/