Python-2.7.3/Modules/_ctypes/_ctypes.c

No issues found

   1 /*****************************************************************
   2   This file should be kept compatible with Python 2.3, see PEP 291.
   3  *****************************************************************/
   4 
   5 
   6 /*
   7   ToDo:
   8 
   9   Get rid of the checker (and also the converters) field in PyCFuncPtrObject and
  10   StgDictObject, and replace them by slot functions in StgDictObject.
  11 
  12   think about a buffer-like object (memory? bytes?)
  13 
  14   Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
  15   What about c_char and c_wchar arrays then?
  16 
  17   Add from_mmap, from_file, from_string metaclass methods.
  18 
  19   Maybe we can get away with from_file (calls read) and with a from_buffer
  20   method?
  21 
  22   And what about the to_mmap, to_file, to_str(?) methods?  They would clobber
  23   the namespace, probably. So, functions instead? And we already have memmove...
  24 */
  25 
  26 /*
  27 
  28 Name                    methods, members, getsets
  29 ==============================================================================
  30 
  31 PyCStructType_Type              __new__(), from_address(), __mul__(), from_param()
  32 UnionType_Type          __new__(), from_address(), __mul__(), from_param()
  33 PyCPointerType_Type     __new__(), from_address(), __mul__(), from_param(), set_type()
  34 PyCArrayType_Type               __new__(), from_address(), __mul__(), from_param()
  35 PyCSimpleType_Type              __new__(), from_address(), __mul__(), from_param()
  36 
  37 PyCData_Type
  38   Struct_Type           __new__(), __init__()
  39   PyCPointer_Type               __new__(), __init__(), _as_parameter_, contents
  40   PyCArray_Type         __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
  41   Simple_Type           __new__(), __init__(), _as_parameter_
  42 
  43 PyCField_Type
  44 PyCStgDict_Type
  45 
  46 ==============================================================================
  47 
  48 class methods
  49 -------------
  50 
  51 It has some similarity to the byref() construct compared to pointer()
  52 from_address(addr)
  53     - construct an instance from a given memory block (sharing this memory block)
  54 
  55 from_param(obj)
  56     - typecheck and convert a Python object into a C function call parameter
  57       the result may be an instance of the type, or an integer or tuple
  58       (typecode, value[, obj])
  59 
  60 instance methods/properties
  61 ---------------------------
  62 
  63 _as_parameter_
  64     - convert self into a C function call parameter
  65       This is either an integer, or a 3-tuple (typecode, value, obj)
  66 
  67 functions
  68 ---------
  69 
  70 sizeof(cdata)
  71     - return the number of bytes the buffer contains
  72 
  73 sizeof(ctype)
  74     - return the number of bytes the buffer of an instance would contain
  75 
  76 byref(cdata)
  77 
  78 addressof(cdata)
  79 
  80 pointer(cdata)
  81 
  82 POINTER(ctype)
  83 
  84 bytes(cdata)
  85     - return the buffer contents as a sequence of bytes (which is currently a string)
  86 
  87 */
  88 
  89 /*
  90  * PyCStgDict_Type
  91  * PyCStructType_Type
  92  * UnionType_Type
  93  * PyCPointerType_Type
  94  * PyCArrayType_Type
  95  * PyCSimpleType_Type
  96  *
  97  * PyCData_Type
  98  * Struct_Type
  99  * Union_Type
 100  * PyCArray_Type
 101  * Simple_Type
 102  * PyCPointer_Type
 103  * PyCField_Type
 104  *
 105  */
 106 
 107 #define PY_SSIZE_T_CLEAN
 108 
 109 #include "Python.h"
 110 #include "structmember.h"
 111 
 112 #include <ffi.h>
 113 #ifdef MS_WIN32
 114 #include <windows.h>
 115 #include <malloc.h>
 116 #ifndef IS_INTRESOURCE
 117 #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
 118 #endif
 119 # ifdef _WIN32_WCE
 120 /* Unlike desktop Windows, WinCE has both W and A variants of
 121    GetProcAddress, but the default W version is not what we want */
 122 #  undef GetProcAddress
 123 #  define GetProcAddress GetProcAddressA
 124 # endif
 125 #else
 126 #include "ctypes_dlfcn.h"
 127 #endif
 128 #include "ctypes.h"
 129 
 130 PyObject *PyExc_ArgError;
 131 
 132 /* This dict maps ctypes types to POINTER types */
 133 PyObject *_ctypes_ptrtype_cache;
 134 
 135 static PyTypeObject Simple_Type;
 136 
 137 /* a callable object used for unpickling */
 138 static PyObject *_unpickle;
 139 
 140 char *_ctypes_conversion_encoding = NULL;
 141 char *_ctypes_conversion_errors = NULL;
 142 
 143 
 144 /****************************************************************/
 145 
 146 #if (PY_VERSION_HEX < 0x02040000)
 147 /* Only in Python 2.4 and up */
 148 static PyObject *
 149 PyTuple_Pack(int n, ...)
 150 {
 151     int i;
 152     PyObject *o;
 153     PyObject *result;
 154     PyObject **items;
 155     va_list vargs;
 156 
 157     va_start(vargs, n);
 158     result = PyTuple_New(n);
 159     if (result == NULL)
 160         return NULL;
 161     items = ((PyTupleObject *)result)->ob_item;
 162     for (i = 0; i < n; i++) {
 163         o = va_arg(vargs, PyObject *);
 164         Py_INCREF(o);
 165         items[i] = o;
 166     }
 167     va_end(vargs);
 168     return result;
 169 }
 170 #endif
 171 
 172 /****************************************************************/
 173 
 174 typedef struct {
 175     PyObject_HEAD
 176     PyObject *key;
 177     PyObject *dict;
 178 } DictRemoverObject;
 179 
 180 static void
 181 _DictRemover_dealloc(PyObject *_self)
 182 {
 183     DictRemoverObject *self = (DictRemoverObject *)_self;
 184     Py_XDECREF(self->key);
 185     Py_XDECREF(self->dict);
 186     Py_TYPE(self)->tp_free(_self);
 187 }
 188 
 189 static PyObject *
 190 _DictRemover_call(PyObject *_self, PyObject *args, PyObject *kw)
 191 {
 192     DictRemoverObject *self = (DictRemoverObject *)_self;
 193     if (self->key && self->dict) {
 194         if (-1 == PyDict_DelItem(self->dict, self->key))
 195             /* XXX Error context */
 196             PyErr_WriteUnraisable(Py_None);
 197         Py_DECREF(self->key);
 198         self->key = NULL;
 199         Py_DECREF(self->dict);
 200         self->dict = NULL;
 201     }
 202     Py_INCREF(Py_None);
 203     return Py_None;
 204 }
 205 
 206 static PyTypeObject DictRemover_Type = {
 207     PyVarObject_HEAD_INIT(NULL, 0)
 208     "_ctypes.DictRemover",                      /* tp_name */
 209     sizeof(DictRemoverObject),                  /* tp_basicsize */
 210     0,                                          /* tp_itemsize */
 211     _DictRemover_dealloc,                       /* tp_dealloc */
 212     0,                                          /* tp_print */
 213     0,                                          /* tp_getattr */
 214     0,                                          /* tp_setattr */
 215     0,                                          /* tp_compare */
 216     0,                                          /* tp_repr */
 217     0,                                          /* tp_as_number */
 218     0,                                          /* tp_as_sequence */
 219     0,                                          /* tp_as_mapping */
 220     0,                                          /* tp_hash */
 221     _DictRemover_call,                          /* tp_call */
 222     0,                                          /* tp_str */
 223     0,                                          /* tp_getattro */
 224     0,                                          /* tp_setattro */
 225     0,                                          /* tp_as_buffer */
 226 /* XXX should participate in GC? */
 227     Py_TPFLAGS_DEFAULT,                         /* tp_flags */
 228     "deletes a key from a dictionary",          /* tp_doc */
 229     0,                                          /* tp_traverse */
 230     0,                                          /* tp_clear */
 231     0,                                          /* tp_richcompare */
 232     0,                                          /* tp_weaklistoffset */
 233     0,                                          /* tp_iter */
 234     0,                                          /* tp_iternext */
 235     0,                                          /* tp_methods */
 236     0,                                          /* tp_members */
 237     0,                                          /* tp_getset */
 238     0,                                          /* tp_base */
 239     0,                                          /* tp_dict */
 240     0,                                          /* tp_descr_get */
 241     0,                                          /* tp_descr_set */
 242     0,                                          /* tp_dictoffset */
 243     0,                                          /* tp_init */
 244     0,                                          /* tp_alloc */
 245     0,                                          /* tp_new */
 246     0,                                          /* tp_free */
 247 };
 248 
 249 int
 250 PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item)
 251 {
 252     PyObject *obj;
 253     DictRemoverObject *remover;
 254     PyObject *proxy;
 255     int result;
 256 
 257     obj = PyObject_CallObject((PyObject *)&DictRemover_Type, NULL);
 258     if (obj == NULL)
 259         return -1;
 260 
 261     remover = (DictRemoverObject *)obj;
 262     assert(remover->key == NULL);
 263     assert(remover->dict == NULL);
 264     Py_INCREF(key);
 265     remover->key = key;
 266     Py_INCREF(dict);
 267     remover->dict = dict;
 268 
 269     proxy = PyWeakref_NewProxy(item, obj);
 270     Py_DECREF(obj);
 271     if (proxy == NULL)
 272         return -1;
 273 
 274     result = PyDict_SetItem(dict, key, proxy);
 275     Py_DECREF(proxy);
 276     return result;
 277 }
 278 
 279 PyObject *
 280 PyDict_GetItemProxy(PyObject *dict, PyObject *key)
 281 {
 282     PyObject *result;
 283     PyObject *item = PyDict_GetItem(dict, key);
 284 
 285     if (item == NULL)
 286         return NULL;
 287     if (!PyWeakref_CheckProxy(item))
 288         return item;
 289     result = PyWeakref_GET_OBJECT(item);
 290     if (result == Py_None)
 291         return NULL;
 292     return result;
 293 }
 294 
 295 /******************************************************************/
 296 /*
 297   Allocate a memory block for a pep3118 format string, copy prefix (if
 298   non-null) and suffix into it.  Returns NULL on failure, with the error
 299   indicator set.  If called with a suffix of NULL the error indicator must
 300   already be set.
 301  */
 302 char *
 303 _ctypes_alloc_format_string(const char *prefix, const char *suffix)
 304 {
 305     size_t len;
 306     char *result;
 307 
 308     if (suffix == NULL) {
 309         assert(PyErr_Occurred());
 310         return NULL;
 311     }
 312     len = strlen(suffix);
 313     if (prefix)
 314         len += strlen(prefix);
 315     result = PyMem_Malloc(len + 1);
 316     if (result == NULL)
 317         return NULL;
 318     if (prefix)
 319         strcpy(result, prefix);
 320     else
 321         result[0] = '\0';
 322     strcat(result, suffix);
 323     return result;
 324 }
 325 
 326 /*
 327   PyCStructType_Type - a meta type/class.  Creating a new class using this one as
 328   __metaclass__ will call the contructor StructUnionType_new.  It replaces the
 329   tp_dict member with a new instance of StgDict, and initializes the C
 330   accessible fields somehow.
 331 */
 332 
 333 static PyCArgObject *
 334 StructUnionType_paramfunc(CDataObject *self)
 335 {
 336     PyCArgObject *parg;
 337     StgDictObject *stgdict;
 338 
 339     parg = PyCArgObject_new();
 340     if (parg == NULL)
 341         return NULL;
 342 
 343     parg->tag = 'V';
 344     stgdict = PyObject_stgdict((PyObject *)self);
 345     assert(stgdict); /* Cannot be NULL for structure/union instances */
 346     parg->pffi_type = &stgdict->ffi_type_pointer;
 347     /* For structure parameters (by value), parg->value doesn't contain the structure
 348        data itself, instead parg->value.p *points* to the structure's data
 349        See also _ctypes.c, function _call_function_pointer().
 350     */
 351     parg->value.p = self->b_ptr;
 352     parg->size = self->b_size;
 353     Py_INCREF(self);
 354     parg->obj = (PyObject *)self;
 355     return parg;
 356 }
 357 
 358 static PyObject *
 359 StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
 360 {
 361     PyTypeObject *result;
 362     PyObject *fields;
 363     StgDictObject *dict;
 364 
 365     /* create the new instance (which is a class,
 366        since we are a metatype!) */
 367     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
 368     if (!result)
 369         return NULL;
 370 
 371     /* keep this for bw compatibility */
 372     if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
 373         return (PyObject *)result;
 374 
 375     dict = (StgDictObject *)PyObject_CallObject((PyObject *)&PyCStgDict_Type, NULL);
 376     if (!dict) {
 377         Py_DECREF(result);
 378         return NULL;
 379     }
 380     /* replace the class dict by our updated stgdict, which holds info
 381        about storage requirements of the instances */
 382     if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
 383         Py_DECREF(result);
 384         Py_DECREF((PyObject *)dict);
 385         return NULL;
 386     }
 387     Py_DECREF(result->tp_dict);
 388     result->tp_dict = (PyObject *)dict;
 389     dict->format = _ctypes_alloc_format_string(NULL, "B");
 390     if (dict->format == NULL) {
 391         Py_DECREF(result);
 392         return NULL;
 393     }
 394 
 395     dict->paramfunc = StructUnionType_paramfunc;
 396 
 397     fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
 398     if (!fields) {
 399         StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
 400 
 401         if (basedict == NULL)
 402             return (PyObject *)result;
 403         /* copy base dict */
 404         if (-1 == PyCStgDict_clone(dict, basedict)) {
 405             Py_DECREF(result);
 406             return NULL;
 407         }
 408         dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
 409         basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
 410         return (PyObject *)result;
 411     }
 412 
 413     if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
 414         Py_DECREF(result);
 415         return NULL;
 416     }
 417     return (PyObject *)result;
 418 }
 419 
 420 static PyObject *
 421 PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 422 {
 423     return StructUnionType_new(type, args, kwds, 1);
 424 }
 425 
 426 static PyObject *
 427 UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 428 {
 429     return StructUnionType_new(type, args, kwds, 0);
 430 }
 431 
 432 static char from_address_doc[] =
 433 "C.from_address(integer) -> C instance\naccess a C instance at the specified address";
 434 
 435 static PyObject *
 436 CDataType_from_address(PyObject *type, PyObject *value)
 437 {
 438     void *buf;
 439     if (!PyInt_Check(value) && !PyLong_Check(value)) {
 440         PyErr_SetString(PyExc_TypeError,
 441                         "integer expected");
 442         return NULL;
 443     }
 444     buf = (void *)PyLong_AsVoidPtr(value);
 445     if (PyErr_Occurred())
 446         return NULL;
 447     return PyCData_AtAddress(type, buf);
 448 }
 449 
 450 static char from_buffer_doc[] =
 451 "C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer";
 452 
 453 static int
 454 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);
 455 
 456 static PyObject *
 457 CDataType_from_buffer(PyObject *type, PyObject *args)
 458 {
 459     void *buffer;
 460     Py_ssize_t buffer_len;
 461     Py_ssize_t offset = 0;
 462     PyObject *obj, *result;
 463     StgDictObject *dict = PyType_stgdict(type);
 464     assert (dict);
 465 
 466     if (!PyArg_ParseTuple(args,
 467 #if (PY_VERSION_HEX < 0x02050000)
 468                           "O|i:from_buffer",
 469 #else
 470                           "O|n:from_buffer",
 471 #endif
 472                           &obj, &offset))
 473         return NULL;
 474 
 475     if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len))
 476         return NULL;
 477 
 478     if (offset < 0) {
 479         PyErr_SetString(PyExc_ValueError,
 480                         "offset cannot be negative");
 481         return NULL;
 482     }
 483     if (dict->size > buffer_len - offset) {
 484         PyErr_Format(PyExc_ValueError,
 485 #if (PY_VERSION_HEX < 0x02050000)
 486                      "Buffer size too small (%d instead of at least %d bytes)",
 487 #else
 488                      "Buffer size too small (%zd instead of at least %zd bytes)",
 489 #endif
 490                      buffer_len, dict->size + offset);
 491         return NULL;
 492     }
 493 
 494     result = PyCData_AtAddress(type, (char *)buffer + offset);
 495     if (result == NULL)
 496         return NULL;
 497 
 498     Py_INCREF(obj);
 499     if (-1 == KeepRef((CDataObject *)result, -1, obj)) {
 500         Py_DECREF(result);
 501         return NULL;
 502     }
 503     return result;
 504 }
 505 
 506 static char from_buffer_copy_doc[] =
 507 "C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer";
 508 
 509 static PyObject *
 510 GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
 511 
 512 static PyObject *
 513 CDataType_from_buffer_copy(PyObject *type, PyObject *args)
 514 {
 515     const void *buffer;
 516     Py_ssize_t buffer_len;
 517     Py_ssize_t offset = 0;
 518     PyObject *obj, *result;
 519     StgDictObject *dict = PyType_stgdict(type);
 520     assert (dict);
 521 
 522     if (!PyArg_ParseTuple(args,
 523 #if (PY_VERSION_HEX < 0x02050000)
 524                           "O|i:from_buffer",
 525 #else
 526                           "O|n:from_buffer",
 527 #endif
 528                           &obj, &offset))
 529         return NULL;
 530 
 531     if (-1 == PyObject_AsReadBuffer(obj, &buffer, &buffer_len))
 532         return NULL;
 533 
 534     if (offset < 0) {
 535         PyErr_SetString(PyExc_ValueError,
 536                         "offset cannot be negative");
 537         return NULL;
 538     }
 539 
 540     if (dict->size > buffer_len - offset) {
 541         PyErr_Format(PyExc_ValueError,
 542 #if (PY_VERSION_HEX < 0x02050000)
 543                      "Buffer size too small (%d instead of at least %d bytes)",
 544 #else
 545                      "Buffer size too small (%zd instead of at least %zd bytes)",
 546 #endif
 547                      buffer_len, dict->size + offset);
 548         return NULL;
 549     }
 550 
 551     result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL);
 552     if (result == NULL)
 553         return NULL;
 554     memcpy(((CDataObject *)result)->b_ptr,
 555            (char *)buffer+offset, dict->size);
 556     return result;
 557 }
 558 
 559 static char in_dll_doc[] =
 560 "C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
 561 
 562 static PyObject *
 563 CDataType_in_dll(PyObject *type, PyObject *args)
 564 {
 565     PyObject *dll;
 566     char *name;
 567     PyObject *obj;
 568     void *handle;
 569     void *address;
 570 
 571     if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
 572         return NULL;
 573 
 574     obj = PyObject_GetAttrString(dll, "_handle");
 575     if (!obj)
 576         return NULL;
 577     if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
 578         PyErr_SetString(PyExc_TypeError,
 579                         "the _handle attribute of the second argument must be an integer");
 580         Py_DECREF(obj);
 581         return NULL;
 582     }
 583     handle = (void *)PyLong_AsVoidPtr(obj);
 584     Py_DECREF(obj);
 585     if (PyErr_Occurred()) {
 586         PyErr_SetString(PyExc_ValueError,
 587                         "could not convert the _handle attribute to a pointer");
 588         return NULL;
 589     }
 590 
 591 #ifdef MS_WIN32
 592     address = (void *)GetProcAddress(handle, name);
 593     if (!address) {
 594         PyErr_Format(PyExc_ValueError,
 595                      "symbol '%s' not found",
 596                      name);
 597         return NULL;
 598     }
 599 #else
 600     address = (void *)ctypes_dlsym(handle, name);
 601     if (!address) {
 602 #ifdef __CYGWIN__
 603 /* dlerror() isn't very helpful on cygwin */
 604         PyErr_Format(PyExc_ValueError,
 605                      "symbol '%s' not found (%s) ",
 606                      name);
 607 #else
 608         PyErr_SetString(PyExc_ValueError, ctypes_dlerror());
 609 #endif
 610         return NULL;
 611     }
 612 #endif
 613     return PyCData_AtAddress(type, address);
 614 }
 615 
 616 static char from_param_doc[] =
 617 "Convert a Python object into a function call parameter.";
 618 
 619 static PyObject *
 620 CDataType_from_param(PyObject *type, PyObject *value)
 621 {
 622     PyObject *as_parameter;
 623     int res = PyObject_IsInstance(value, type);
 624     if (res == -1)
 625         return NULL;
 626     if (res) {
 627         Py_INCREF(value);
 628         return value;
 629     }
 630     if (PyCArg_CheckExact(value)) {
 631         PyCArgObject *p = (PyCArgObject *)value;
 632         PyObject *ob = p->obj;
 633         const char *ob_name;
 634         StgDictObject *dict;
 635         dict = PyType_stgdict(type);
 636 
 637         /* If we got a PyCArgObject, we must check if the object packed in it
 638            is an instance of the type's dict->proto */
 639         if(dict && ob) {
 640             res = PyObject_IsInstance(ob, dict->proto);
 641             if (res == -1)
 642                 return NULL;
 643             if (res) {
 644                 Py_INCREF(value);
 645                 return value;
 646             }
 647         }
 648         ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
 649         PyErr_Format(PyExc_TypeError,
 650                      "expected %s instance instead of pointer to %s",
 651                      ((PyTypeObject *)type)->tp_name, ob_name);
 652         return NULL;
 653     }
 654 
 655     as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
 656     if (as_parameter) {
 657         value = CDataType_from_param(type, as_parameter);
 658         Py_DECREF(as_parameter);
 659         return value;
 660     }
 661     PyErr_Format(PyExc_TypeError,
 662                  "expected %s instance instead of %s",
 663                  ((PyTypeObject *)type)->tp_name,
 664                  Py_TYPE(value)->tp_name);
 665     return NULL;
 666 }
 667 
 668 static PyMethodDef CDataType_methods[] = {
 669     { "from_param", CDataType_from_param, METH_O, from_param_doc },
 670     { "from_address", CDataType_from_address, METH_O, from_address_doc },
 671     { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
 672     { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
 673     { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
 674     { NULL, NULL },
 675 };
 676 
 677 static PyObject *
 678 CDataType_repeat(PyObject *self, Py_ssize_t length)
 679 {
 680     if (length < 0)
 681         return PyErr_Format(PyExc_ValueError,
 682 #if (PY_VERSION_HEX < 0x02050000)
 683                             "Array length must be >= 0, not %d",
 684 #else
 685                             "Array length must be >= 0, not %zd",
 686 #endif
 687                             length);
 688     return PyCArrayType_from_ctype(self, length);
 689 }
 690 
 691 static PySequenceMethods CDataType_as_sequence = {
 692     0,                          /* inquiry sq_length; */
 693     0,                          /* binaryfunc sq_concat; */
 694     CDataType_repeat,           /* intargfunc sq_repeat; */
 695     0,                          /* intargfunc sq_item; */
 696     0,                          /* intintargfunc sq_slice; */
 697     0,                          /* intobjargproc sq_ass_item; */
 698     0,                          /* intintobjargproc sq_ass_slice; */
 699     0,                          /* objobjproc sq_contains; */
 700 
 701     0,                          /* binaryfunc sq_inplace_concat; */
 702     0,                          /* intargfunc sq_inplace_repeat; */
 703 };
 704 
 705 static int
 706 CDataType_clear(PyTypeObject *self)
 707 {
 708     StgDictObject *dict = PyType_stgdict((PyObject *)self);
 709     if (dict)
 710         Py_CLEAR(dict->proto);
 711     return PyType_Type.tp_clear((PyObject *)self);
 712 }
 713 
 714 static int
 715 CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
 716 {
 717     StgDictObject *dict = PyType_stgdict((PyObject *)self);
 718     if (dict)
 719         Py_VISIT(dict->proto);
 720     return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
 721 }
 722 
 723 static int
 724 PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
 725 {
 726     /* XXX Should we disallow deleting _fields_? */
 727     if (-1 == PyType_Type.tp_setattro(self, key, value))
 728         return -1;
 729 
 730     if (value && PyString_Check(key) &&
 731         0 == strcmp(PyString_AS_STRING(key), "_fields_"))
 732         return PyCStructUnionType_update_stgdict(self, value, 1);
 733     return 0;
 734 }
 735 
 736 
 737 static int
 738 UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
 739 {
 740     /* XXX Should we disallow deleting _fields_? */
 741     if (-1 == PyObject_GenericSetAttr(self, key, value))
 742         return -1;
 743 
 744     if (PyString_Check(key) &&
 745         0 == strcmp(PyString_AS_STRING(key), "_fields_"))
 746         return PyCStructUnionType_update_stgdict(self, value, 0);
 747     return 0;
 748 }
 749 
 750 
 751 PyTypeObject PyCStructType_Type = {
 752     PyVarObject_HEAD_INIT(NULL, 0)
 753     "_ctypes.PyCStructType",                            /* tp_name */
 754     0,                                          /* tp_basicsize */
 755     0,                                          /* tp_itemsize */
 756     0,                                          /* tp_dealloc */
 757     0,                                          /* tp_print */
 758     0,                                          /* tp_getattr */
 759     0,                                          /* tp_setattr */
 760     0,                                          /* tp_compare */
 761     0,                                          /* tp_repr */
 762     0,                                          /* tp_as_number */
 763     &CDataType_as_sequence,                     /* tp_as_sequence */
 764     0,                                          /* tp_as_mapping */
 765     0,                                          /* tp_hash */
 766     0,                                          /* tp_call */
 767     0,                                          /* tp_str */
 768     0,                                          /* tp_getattro */
 769     PyCStructType_setattro,                     /* tp_setattro */
 770     0,                                          /* tp_as_buffer */
 771     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 772     "metatype for the CData Objects",           /* tp_doc */
 773     (traverseproc)CDataType_traverse,           /* tp_traverse */
 774     (inquiry)CDataType_clear,                   /* tp_clear */
 775     0,                                          /* tp_richcompare */
 776     0,                                          /* tp_weaklistoffset */
 777     0,                                          /* tp_iter */
 778     0,                                          /* tp_iternext */
 779     CDataType_methods,                          /* tp_methods */
 780     0,                                          /* tp_members */
 781     0,                                          /* tp_getset */
 782     0,                                          /* tp_base */
 783     0,                                          /* tp_dict */
 784     0,                                          /* tp_descr_get */
 785     0,                                          /* tp_descr_set */
 786     0,                                          /* tp_dictoffset */
 787     0,                                          /* tp_init */
 788     0,                                          /* tp_alloc */
 789     PyCStructType_new,                                  /* tp_new */
 790     0,                                          /* tp_free */
 791 };
 792 
 793 static PyTypeObject UnionType_Type = {
 794     PyVarObject_HEAD_INIT(NULL, 0)
 795     "_ctypes.UnionType",                        /* tp_name */
 796     0,                                          /* tp_basicsize */
 797     0,                                          /* tp_itemsize */
 798     0,                                          /* tp_dealloc */
 799     0,                                          /* tp_print */
 800     0,                                          /* tp_getattr */
 801     0,                                          /* tp_setattr */
 802     0,                                          /* tp_compare */
 803     0,                                          /* tp_repr */
 804     0,                                          /* tp_as_number */
 805     &CDataType_as_sequence,             /* tp_as_sequence */
 806     0,                                          /* tp_as_mapping */
 807     0,                                          /* tp_hash */
 808     0,                                          /* tp_call */
 809     0,                                          /* tp_str */
 810     0,                                          /* tp_getattro */
 811     UnionType_setattro,                         /* tp_setattro */
 812     0,                                          /* tp_as_buffer */
 813     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 814     "metatype for the CData Objects",           /* tp_doc */
 815     (traverseproc)CDataType_traverse,           /* tp_traverse */
 816     (inquiry)CDataType_clear,                   /* tp_clear */
 817     0,                                          /* tp_richcompare */
 818     0,                                          /* tp_weaklistoffset */
 819     0,                                          /* tp_iter */
 820     0,                                          /* tp_iternext */
 821     CDataType_methods,                          /* tp_methods */
 822     0,                                          /* tp_members */
 823     0,                                          /* tp_getset */
 824     0,                                          /* tp_base */
 825     0,                                          /* tp_dict */
 826     0,                                          /* tp_descr_get */
 827     0,                                          /* tp_descr_set */
 828     0,                                          /* tp_dictoffset */
 829     0,                                          /* tp_init */
 830     0,                                          /* tp_alloc */
 831     UnionType_new,                              /* tp_new */
 832     0,                                          /* tp_free */
 833 };
 834 
 835 
 836 /******************************************************************/
 837 
 838 /*
 839 
 840 The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be
 841 created. It must check for a _type_ attribute in the class. Since are no
 842 runtime created properties, a CField is probably *not* needed ?
 843 
 844 class IntPointer(Pointer):
 845     _type_ = "i"
 846 
 847 The PyCPointer_Type provides the functionality: a contents method/property, a
 848 size property/method, and the sequence protocol.
 849 
 850 */
 851 
 852 static int
 853 PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
 854 {
 855     if (!proto || !PyType_Check(proto)) {
 856         PyErr_SetString(PyExc_TypeError,
 857                         "_type_ must be a type");
 858         return -1;
 859     }
 860     if (!PyType_stgdict(proto)) {
 861         PyErr_SetString(PyExc_TypeError,
 862                         "_type_ must have storage info");
 863         return -1;
 864     }
 865     Py_INCREF(proto);
 866     Py_XDECREF(stgdict->proto);
 867     stgdict->proto = proto;
 868     return 0;
 869 }
 870 
 871 static PyCArgObject *
 872 PyCPointerType_paramfunc(CDataObject *self)
 873 {
 874     PyCArgObject *parg;
 875 
 876     parg = PyCArgObject_new();
 877     if (parg == NULL)
 878         return NULL;
 879 
 880     parg->tag = 'P';
 881     parg->pffi_type = &ffi_type_pointer;
 882     Py_INCREF(self);
 883     parg->obj = (PyObject *)self;
 884     parg->value.p = *(void **)self->b_ptr;
 885     return parg;
 886 }
 887 
 888 static PyObject *
 889 PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 890 {
 891     PyTypeObject *result;
 892     StgDictObject *stgdict;
 893     PyObject *proto;
 894     PyObject *typedict;
 895 
 896     typedict = PyTuple_GetItem(args, 2);
 897     if (!typedict)
 898         return NULL;
 899 /*
 900   stgdict items size, align, length contain info about pointers itself,
 901   stgdict->proto has info about the pointed to type!
 902 */
 903     stgdict = (StgDictObject *)PyObject_CallObject(
 904         (PyObject *)&PyCStgDict_Type, NULL);
 905     if (!stgdict)
 906         return NULL;
 907     stgdict->size = sizeof(void *);
 908     stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
 909     stgdict->length = 1;
 910     stgdict->ffi_type_pointer = ffi_type_pointer;
 911     stgdict->paramfunc = PyCPointerType_paramfunc;
 912     stgdict->flags |= TYPEFLAG_ISPOINTER;
 913 
 914     proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
 915     if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) {
 916         Py_DECREF((PyObject *)stgdict);
 917         return NULL;
 918     }
 919 
 920     if (proto) {
 921         StgDictObject *itemdict = PyType_stgdict(proto);
 922         assert(itemdict);
 923         /* If itemdict->format is NULL, then this is a pointer to an
 924            incomplete type.  We create a generic format string
 925            'pointer to bytes' in this case.  XXX Better would be to
 926            fix the format string later...
 927         */
 928         stgdict->format = _ctypes_alloc_format_string("&",
 929                       itemdict->format ? itemdict->format : "B");
 930         if (stgdict->format == NULL) {
 931             Py_DECREF((PyObject *)stgdict);
 932             return NULL;
 933         }
 934     }
 935 
 936     /* create the new instance (which is a class,
 937        since we are a metatype!) */
 938     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
 939     if (result == NULL) {
 940         Py_DECREF((PyObject *)stgdict);
 941         return NULL;
 942     }
 943 
 944     /* replace the class dict by our updated spam dict */
 945     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
 946         Py_DECREF(result);
 947         Py_DECREF((PyObject *)stgdict);
 948         return NULL;
 949     }
 950     Py_DECREF(result->tp_dict);
 951     result->tp_dict = (PyObject *)stgdict;
 952 
 953     return (PyObject *)result;
 954 }
 955 
 956 
 957 static PyObject *
 958 PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
 959 {
 960     StgDictObject *dict;
 961 
 962     dict = PyType_stgdict((PyObject *)self);
 963     assert(dict);
 964 
 965     if (-1 == PyCPointerType_SetProto(dict, type))
 966         return NULL;
 967 
 968     if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
 969         return NULL;
 970 
 971     Py_INCREF(Py_None);
 972     return Py_None;
 973 }
 974 
 975 staticforward PyObject *_byref(PyObject *);
 976 
 977 static PyObject *
 978 PyCPointerType_from_param(PyObject *type, PyObject *value)
 979 {
 980     StgDictObject *typedict;
 981 
 982     if (value == Py_None) {
 983         /* ConvParam will convert to a NULL pointer later */
 984         Py_INCREF(value);
 985         return value;
 986     }
 987 
 988     typedict = PyType_stgdict(type);
 989     assert(typedict); /* Cannot be NULL for pointer types */
 990 
 991     /* If we expect POINTER(<type>), but receive a <type> instance, accept
 992        it by calling byref(<type>).
 993     */
 994     switch (PyObject_IsInstance(value, typedict->proto)) {
 995     case 1:
 996         Py_INCREF(value); /* _byref steals a refcount */
 997         return _byref(value);
 998     case -1:
 999         return NULL;
1000     default:
1001         break;
1002     }
1003 
1004     if (PointerObject_Check(value) || ArrayObject_Check(value)) {
1005         /* Array instances are also pointers when
1006            the item types are the same.
1007         */
1008         StgDictObject *v = PyObject_stgdict(value);
1009         assert(v); /* Cannot be NULL for pointer or array objects */
1010         if (PyObject_IsSubclass(v->proto, typedict->proto)) {
1011             Py_INCREF(value);
1012             return value;
1013         }
1014     }
1015     return CDataType_from_param(type, value);
1016 }
1017 
1018 static PyMethodDef PyCPointerType_methods[] = {
1019     { "from_address", CDataType_from_address, METH_O, from_address_doc },
1020     { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
1021     { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
1022     { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
1023     { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc},
1024     { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O },
1025     { NULL, NULL },
1026 };
1027 
1028 PyTypeObject PyCPointerType_Type = {
1029     PyVarObject_HEAD_INIT(NULL, 0)
1030     "_ctypes.PyCPointerType",                                   /* tp_name */
1031     0,                                          /* tp_basicsize */
1032     0,                                          /* tp_itemsize */
1033     0,                                          /* tp_dealloc */
1034     0,                                          /* tp_print */
1035     0,                                          /* tp_getattr */
1036     0,                                          /* tp_setattr */
1037     0,                                          /* tp_compare */
1038     0,                                          /* tp_repr */
1039     0,                                          /* tp_as_number */
1040     &CDataType_as_sequence,             /* tp_as_sequence */
1041     0,                                          /* tp_as_mapping */
1042     0,                                          /* tp_hash */
1043     0,                                          /* tp_call */
1044     0,                                          /* tp_str */
1045     0,                                          /* tp_getattro */
1046     0,                                          /* tp_setattro */
1047     0,                                          /* tp_as_buffer */
1048     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1049     "metatype for the Pointer Objects",         /* tp_doc */
1050     (traverseproc)CDataType_traverse,           /* tp_traverse */
1051     (inquiry)CDataType_clear,                   /* tp_clear */
1052     0,                                          /* tp_richcompare */
1053     0,                                          /* tp_weaklistoffset */
1054     0,                                          /* tp_iter */
1055     0,                                          /* tp_iternext */
1056     PyCPointerType_methods,                     /* tp_methods */
1057     0,                                          /* tp_members */
1058     0,                                          /* tp_getset */
1059     0,                                          /* tp_base */
1060     0,                                          /* tp_dict */
1061     0,                                          /* tp_descr_get */
1062     0,                                          /* tp_descr_set */
1063     0,                                          /* tp_dictoffset */
1064     0,                                          /* tp_init */
1065     0,                                          /* tp_alloc */
1066     PyCPointerType_new,                         /* tp_new */
1067     0,                                          /* tp_free */
1068 };
1069 
1070 
1071 /******************************************************************/
1072 /*
1073   PyCArrayType_Type
1074 */
1075 /*
1076   PyCArrayType_new ensures that the new Array subclass created has a _length_
1077   attribute, and a _type_ attribute.
1078 */
1079 
1080 static int
1081 CharArray_set_raw(CDataObject *self, PyObject *value)
1082 {
1083     char *ptr;
1084     Py_ssize_t size;
1085 #if (PY_VERSION_HEX >= 0x02060000)
1086     Py_buffer view = { 0 };
1087 #endif
1088     if (PyBuffer_Check(value)) {
1089         size = Py_TYPE(value)->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
1090         if (size < 0)
1091             goto fail;
1092     } else {
1093 #if (PY_VERSION_HEX >= 0x02060000)
1094         if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
1095             goto fail;
1096         size = view.len;
1097         ptr = view.buf;
1098 #else
1099         if (-1 == PyString_AsStringAndSize(value, &ptr, &size))
1100             goto fail;
1101 #endif
1102     }
1103     if (size > self->b_size) {
1104         PyErr_SetString(PyExc_ValueError,
1105                         "string too long");
1106         goto fail;
1107     }
1108 
1109     memcpy(self->b_ptr, ptr, size);
1110 
1111 #if (PY_VERSION_HEX >= 0x02060000)
1112     PyBuffer_Release(&view);
1113 #endif
1114     return 0;
1115     fail:
1116 
1117 #if (PY_VERSION_HEX >= 0x02060000)
1118     PyBuffer_Release(&view);
1119 #endif
1120     return -1;
1121 }
1122 
1123 static PyObject *
1124 CharArray_get_raw(CDataObject *self)
1125 {
1126     return PyString_FromStringAndSize(self->b_ptr, self->b_size);
1127 }
1128 
1129 static PyObject *
1130 CharArray_get_value(CDataObject *self)
1131 {
1132     int i;
1133     char *ptr = self->b_ptr;
1134     for (i = 0; i < self->b_size; ++i)
1135         if (*ptr++ == '\0')
1136             break;
1137     return PyString_FromStringAndSize(self->b_ptr, i);
1138 }
1139 
1140 static int
1141 CharArray_set_value(CDataObject *self, PyObject *value)
1142 {
1143     char *ptr;
1144     Py_ssize_t size;
1145 
1146     if (value == NULL) {
1147         PyErr_SetString(PyExc_TypeError,
1148                         "can't delete attribute");
1149         return -1;
1150     }
1151 
1152     if (PyUnicode_Check(value)) {
1153         value = PyUnicode_AsEncodedString(value,
1154                                           _ctypes_conversion_encoding,
1155                                           _ctypes_conversion_errors);
1156         if (!value)
1157             return -1;
1158     } else if (!PyString_Check(value)) {
1159         PyErr_Format(PyExc_TypeError,
1160                      "string expected instead of %s instance",
1161                      Py_TYPE(value)->tp_name);
1162         return -1;
1163     } else
1164         Py_INCREF(value);
1165     size = PyString_GET_SIZE(value);
1166     if (size > self->b_size) {
1167         PyErr_SetString(PyExc_ValueError,
1168                         "string too long");
1169         Py_DECREF(value);
1170         return -1;
1171     }
1172 
1173     ptr = PyString_AS_STRING(value);
1174     memcpy(self->b_ptr, ptr, size);
1175     if (size < self->b_size)
1176         self->b_ptr[size] = '\0';
1177     Py_DECREF(value);
1178 
1179     return 0;
1180 }
1181 
1182 static PyGetSetDef CharArray_getsets[] = {
1183     { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
1184       "value", NULL },
1185     { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
1186       "string value"},
1187     { NULL, NULL }
1188 };
1189 
1190 #ifdef CTYPES_UNICODE
1191 static PyObject *
1192 WCharArray_get_value(CDataObject *self)
1193 {
1194     unsigned int i;
1195     wchar_t *ptr = (wchar_t *)self->b_ptr;
1196     for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
1197         if (*ptr++ == (wchar_t)0)
1198             break;
1199     return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
1200 }
1201 
1202 static int
1203 WCharArray_set_value(CDataObject *self, PyObject *value)
1204 {
1205     Py_ssize_t result = 0;
1206 
1207     if (value == NULL) {
1208         PyErr_SetString(PyExc_TypeError,
1209                         "can't delete attribute");
1210         return -1;
1211     }
1212     if (PyString_Check(value)) {
1213         value = PyUnicode_FromEncodedObject(value,
1214                                             _ctypes_conversion_encoding,
1215                                             _ctypes_conversion_errors);
1216         if (!value)
1217             return -1;
1218     } else if (!PyUnicode_Check(value)) {
1219         PyErr_Format(PyExc_TypeError,
1220                         "unicode string expected instead of %s instance",
1221                         Py_TYPE(value)->tp_name);
1222         return -1;
1223     } else
1224         Py_INCREF(value);
1225     if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
1226         PyErr_SetString(PyExc_ValueError,
1227                         "string too long");
1228         result = -1;
1229         goto done;
1230     }
1231     result = PyUnicode_AsWideChar((PyUnicodeObject *)value,
1232                                   (wchar_t *)self->b_ptr,
1233                                   self->b_size/sizeof(wchar_t));
1234     if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
1235         ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
1236   done:
1237     Py_DECREF(value);
1238 
1239     return result >= 0 ? 0 : -1;
1240 }
1241 
1242 static PyGetSetDef WCharArray_getsets[] = {
1243     { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
1244       "string value"},
1245     { NULL, NULL }
1246 };
1247 #endif
1248 
1249 /*
1250   The next three functions copied from Python's typeobject.c.
1251 
1252   They are used to attach methods, members, or getsets to a type *after* it
1253   has been created: Arrays of characters have additional getsets to treat them
1254   as strings.
1255  */
1256 /*
1257 static int
1258 add_methods(PyTypeObject *type, PyMethodDef *meth)
1259 {
1260     PyObject *dict = type->tp_dict;
1261     for (; meth->ml_name != NULL; meth++) {
1262         PyObject *descr;
1263         descr = PyDescr_NewMethod(type, meth);
1264         if (descr == NULL)
1265             return -1;
1266         if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
1267             return -1;
1268         Py_DECREF(descr);
1269     }
1270     return 0;
1271 }
1272 
1273 static int
1274 add_members(PyTypeObject *type, PyMemberDef *memb)
1275 {
1276     PyObject *dict = type->tp_dict;
1277     for (; memb->name != NULL; memb++) {
1278         PyObject *descr;
1279         descr = PyDescr_NewMember(type, memb);
1280         if (descr == NULL)
1281             return -1;
1282         if (PyDict_SetItemString(dict, memb->name, descr) < 0)
1283             return -1;
1284         Py_DECREF(descr);
1285     }
1286     return 0;
1287 }
1288 */
1289 
1290 static int
1291 add_getset(PyTypeObject *type, PyGetSetDef *gsp)
1292 {
1293     PyObject *dict = type->tp_dict;
1294     for (; gsp->name != NULL; gsp++) {
1295         PyObject *descr;
1296         descr = PyDescr_NewGetSet(type, gsp);
1297         if (descr == NULL)
1298             return -1;
1299         if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
1300             return -1;
1301         Py_DECREF(descr);
1302     }
1303     return 0;
1304 }
1305 
1306 static PyCArgObject *
1307 PyCArrayType_paramfunc(CDataObject *self)
1308 {
1309     PyCArgObject *p = PyCArgObject_new();
1310     if (p == NULL)
1311         return NULL;
1312     p->tag = 'P';
1313     p->pffi_type = &ffi_type_pointer;
1314     p->value.p = (char *)self->b_ptr;
1315     Py_INCREF(self);
1316     p->obj = (PyObject *)self;
1317     return p;
1318 }
1319 
1320 static PyObject *
1321 PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1322 {
1323     PyTypeObject *result;
1324     StgDictObject *stgdict;
1325     StgDictObject *itemdict;
1326     PyObject *proto;
1327     PyObject *typedict;
1328     long length;
1329 
1330     Py_ssize_t itemsize, itemalign;
1331     char buf[32];
1332 
1333     typedict = PyTuple_GetItem(args, 2);
1334     if (!typedict)
1335         return NULL;
1336 
1337     proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
1338     if (!proto || !PyInt_Check(proto)) {
1339         PyErr_SetString(PyExc_AttributeError,
1340                         "class must define a '_length_' attribute, "
1341                         "which must be a positive integer");
1342         return NULL;
1343     }
1344     length = PyInt_AS_LONG(proto);
1345 
1346     proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
1347     if (!proto) {
1348         PyErr_SetString(PyExc_AttributeError,
1349                         "class must define a '_type_' attribute");
1350         return NULL;
1351     }
1352 
1353     stgdict = (StgDictObject *)PyObject_CallObject(
1354         (PyObject *)&PyCStgDict_Type, NULL);
1355     if (!stgdict)
1356         return NULL;
1357 
1358     itemdict = PyType_stgdict(proto);
1359     if (!itemdict) {
1360         PyErr_SetString(PyExc_TypeError,
1361                         "_type_ must have storage info");
1362         Py_DECREF((PyObject *)stgdict);
1363         return NULL;
1364     }
1365 
1366     assert(itemdict->format);
1367     if (itemdict->format[0] == '(') {
1368         sprintf(buf, "(%ld,", length);
1369         stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1);
1370     } else {
1371         sprintf(buf, "(%ld)", length);
1372         stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format);
1373     }
1374     if (stgdict->format == NULL) {
1375         Py_DECREF((PyObject *)stgdict);
1376         return NULL;
1377     }
1378     stgdict->ndim = itemdict->ndim + 1;
1379     stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t *) * stgdict->ndim);
1380     if (stgdict->shape == NULL) {
1381         Py_DECREF((PyObject *)stgdict);
1382         return NULL;
1383     }
1384     stgdict->shape[0] = length;
1385     memmove(&stgdict->shape[1], itemdict->shape,
1386         sizeof(Py_ssize_t) * (stgdict->ndim - 1));
1387 
1388     itemsize = itemdict->size;
1389     if (length * itemsize < 0) {
1390         PyErr_SetString(PyExc_OverflowError,
1391                         "array too large");
1392         return NULL;
1393     }
1394 
1395     itemalign = itemdict->align;
1396 
1397     if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
1398         stgdict->flags |= TYPEFLAG_HASPOINTER;
1399 
1400     stgdict->size = itemsize * length;
1401     stgdict->align = itemalign;
1402     stgdict->length = length;
1403     Py_INCREF(proto);
1404     stgdict->proto = proto;
1405 
1406     stgdict->paramfunc = &PyCArrayType_paramfunc;
1407 
1408     /* Arrays are passed as pointers to function calls. */
1409     stgdict->ffi_type_pointer = ffi_type_pointer;
1410 
1411     /* create the new instance (which is a class,
1412        since we are a metatype!) */
1413     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1414     if (result == NULL)
1415         return NULL;
1416 
1417     /* replace the class dict by our updated spam dict */
1418     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1419         Py_DECREF(result);
1420         Py_DECREF((PyObject *)stgdict);
1421         return NULL;
1422     }
1423     Py_DECREF(result->tp_dict);
1424     result->tp_dict = (PyObject *)stgdict;
1425 
1426     /* Special case for character arrays.
1427        A permanent annoyance: char arrays are also strings!
1428     */
1429     if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
1430         if (-1 == add_getset(result, CharArray_getsets))
1431             return NULL;
1432 #ifdef CTYPES_UNICODE
1433     } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
1434         if (-1 == add_getset(result, WCharArray_getsets))
1435             return NULL;
1436 #endif
1437     }
1438 
1439     return (PyObject *)result;
1440 }
1441 
1442 PyTypeObject PyCArrayType_Type = {
1443     PyVarObject_HEAD_INIT(NULL, 0)
1444     "_ctypes.PyCArrayType",                     /* tp_name */
1445     0,                                          /* tp_basicsize */
1446     0,                                          /* tp_itemsize */
1447     0,                                          /* tp_dealloc */
1448     0,                                          /* tp_print */
1449     0,                                          /* tp_getattr */
1450     0,                                          /* tp_setattr */
1451     0,                                          /* tp_compare */
1452     0,                                          /* tp_repr */
1453     0,                                          /* tp_as_number */
1454     &CDataType_as_sequence,                     /* tp_as_sequence */
1455     0,                                          /* tp_as_mapping */
1456     0,                                          /* tp_hash */
1457     0,                                          /* tp_call */
1458     0,                                          /* tp_str */
1459     0,                                          /* tp_getattro */
1460     0,                                          /* tp_setattro */
1461     0,                                          /* tp_as_buffer */
1462     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1463     "metatype for the Array Objects",           /* tp_doc */
1464     0,                                          /* tp_traverse */
1465     0,                                          /* tp_clear */
1466     0,                                          /* tp_richcompare */
1467     0,                                          /* tp_weaklistoffset */
1468     0,                                          /* tp_iter */
1469     0,                                          /* tp_iternext */
1470     CDataType_methods,                          /* tp_methods */
1471     0,                                          /* tp_members */
1472     0,                                          /* tp_getset */
1473     0,                                          /* tp_base */
1474     0,                                          /* tp_dict */
1475     0,                                          /* tp_descr_get */
1476     0,                                          /* tp_descr_set */
1477     0,                                          /* tp_dictoffset */
1478     0,                                          /* tp_init */
1479     0,                                          /* tp_alloc */
1480     PyCArrayType_new,                                   /* tp_new */
1481     0,                                          /* tp_free */
1482 };
1483 
1484 
1485 /******************************************************************/
1486 /*
1487   PyCSimpleType_Type
1488 */
1489 /*
1490 
1491 PyCSimpleType_new ensures that the new Simple_Type subclass created has a valid
1492 _type_ attribute.
1493 
1494 */
1495 
1496 static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv?g";
1497 
1498 static PyObject *
1499 c_wchar_p_from_param(PyObject *type, PyObject *value)
1500 {
1501     PyObject *as_parameter;
1502     int res;
1503 #if (PYTHON_API_VERSION < 1012)
1504 # error not supported
1505 #endif
1506     if (value == Py_None) {
1507         Py_INCREF(Py_None);
1508         return Py_None;
1509     }
1510     if (PyUnicode_Check(value) || PyString_Check(value)) {
1511         PyCArgObject *parg;
1512         struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1513 
1514         parg = PyCArgObject_new();
1515         if (parg == NULL)
1516             return NULL;
1517         parg->pffi_type = &ffi_type_pointer;
1518         parg->tag = 'Z';
1519         parg->obj = fd->setfunc(&parg->value, value, 0);
1520         if (parg->obj == NULL) {
1521             Py_DECREF(parg);
1522             return NULL;
1523         }
1524         return (PyObject *)parg;
1525     }
1526     res = PyObject_IsInstance(value, type);
1527     if (res == -1)
1528         return NULL;
1529     if (res) {
1530         Py_INCREF(value);
1531         return value;
1532     }
1533     if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1534         /* c_wchar array instance or pointer(c_wchar(...)) */
1535         StgDictObject *dt = PyObject_stgdict(value);
1536         StgDictObject *dict;
1537         assert(dt); /* Cannot be NULL for pointer or array objects */
1538         dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1539         if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1540             Py_INCREF(value);
1541             return value;
1542         }
1543     }
1544     if (PyCArg_CheckExact(value)) {
1545         /* byref(c_char(...)) */
1546         PyCArgObject *a = (PyCArgObject *)value;
1547         StgDictObject *dict = PyObject_stgdict(a->obj);
1548         if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1549             Py_INCREF(value);
1550             return value;
1551         }
1552     }
1553 
1554     as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1555     if (as_parameter) {
1556         value = c_wchar_p_from_param(type, as_parameter);
1557         Py_DECREF(as_parameter);
1558         return value;
1559     }
1560     /* XXX better message */
1561     PyErr_SetString(PyExc_TypeError,
1562                     "wrong type");
1563     return NULL;
1564 }
1565 
1566 static PyObject *
1567 c_char_p_from_param(PyObject *type, PyObject *value)
1568 {
1569     PyObject *as_parameter;
1570     int res;
1571 #if (PYTHON_API_VERSION < 1012)
1572 # error not supported
1573 #endif
1574     if (value == Py_None) {
1575         Py_INCREF(Py_None);
1576         return Py_None;
1577     }
1578     if (PyString_Check(value) || PyUnicode_Check(value)) {
1579         PyCArgObject *parg;
1580         struct fielddesc *fd = _ctypes_get_fielddesc("z");
1581 
1582         parg = PyCArgObject_new();
1583         if (parg == NULL)
1584             return NULL;
1585         parg->pffi_type = &ffi_type_pointer;
1586         parg->tag = 'z';
1587         parg->obj = fd->setfunc(&parg->value, value, 0);
1588         if (parg->obj == NULL) {
1589             Py_DECREF(parg);
1590             return NULL;
1591         }
1592         return (PyObject *)parg;
1593     }
1594     res = PyObject_IsInstance(value, type);
1595     if (res == -1)
1596         return NULL;
1597     if (res) {
1598         Py_INCREF(value);
1599         return value;
1600     }
1601     if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1602         /* c_char array instance or pointer(c_char(...)) */
1603         StgDictObject *dt = PyObject_stgdict(value);
1604         StgDictObject *dict;
1605         assert(dt); /* Cannot be NULL for pointer or array objects */
1606         dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1607         if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1608             Py_INCREF(value);
1609             return value;
1610         }
1611     }
1612     if (PyCArg_CheckExact(value)) {
1613         /* byref(c_char(...)) */
1614         PyCArgObject *a = (PyCArgObject *)value;
1615         StgDictObject *dict = PyObject_stgdict(a->obj);
1616         if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1617             Py_INCREF(value);
1618             return value;
1619         }
1620     }
1621 
1622     as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1623     if (as_parameter) {
1624         value = c_char_p_from_param(type, as_parameter);
1625         Py_DECREF(as_parameter);
1626         return value;
1627     }
1628     /* XXX better message */
1629     PyErr_SetString(PyExc_TypeError,
1630                     "wrong type");
1631     return NULL;
1632 }
1633 
1634 static PyObject *
1635 c_void_p_from_param(PyObject *type, PyObject *value)
1636 {
1637     StgDictObject *stgd;
1638     PyObject *as_parameter;
1639     int res;
1640 #if (PYTHON_API_VERSION < 1012)
1641 # error not supported
1642 #endif
1643 
1644 /* None */
1645     if (value == Py_None) {
1646         Py_INCREF(Py_None);
1647         return Py_None;
1648     }
1649     /* Should probably allow buffer interface as well */
1650 /* int, long */
1651     if (PyInt_Check(value) || PyLong_Check(value)) {
1652         PyCArgObject *parg;
1653         struct fielddesc *fd = _ctypes_get_fielddesc("P");
1654 
1655         parg = PyCArgObject_new();
1656         if (parg == NULL)
1657             return NULL;
1658         parg->pffi_type = &ffi_type_pointer;
1659         parg->tag = 'P';
1660         parg->obj = fd->setfunc(&parg->value, value, 0);
1661         if (parg->obj == NULL) {
1662             Py_DECREF(parg);
1663             return NULL;
1664         }
1665         return (PyObject *)parg;
1666     }
1667 /* string */
1668     if (PyString_Check(value)) {
1669         PyCArgObject *parg;
1670         struct fielddesc *fd = _ctypes_get_fielddesc("z");
1671 
1672         parg = PyCArgObject_new();
1673         if (parg == NULL)
1674             return NULL;
1675         parg->pffi_type = &ffi_type_pointer;
1676         parg->tag = 'z';
1677         parg->obj = fd->setfunc(&parg->value, value, 0);
1678         if (parg->obj == NULL) {
1679             Py_DECREF(parg);
1680             return NULL;
1681         }
1682         return (PyObject *)parg;
1683     }
1684 /* unicode */
1685     if (PyUnicode_Check(value)) {
1686         PyCArgObject *parg;
1687         struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1688 
1689         parg = PyCArgObject_new();
1690         if (parg == NULL)
1691             return NULL;
1692         parg->pffi_type = &ffi_type_pointer;
1693         parg->tag = 'Z';
1694         parg->obj = fd->setfunc(&parg->value, value, 0);
1695         if (parg->obj == NULL) {
1696             Py_DECREF(parg);
1697             return NULL;
1698         }
1699         return (PyObject *)parg;
1700     }
1701 /* c_void_p instance (or subclass) */
1702     res = PyObject_IsInstance(value, type);
1703     if (res == -1)
1704         return NULL;
1705     if (res) {
1706         /* c_void_p instances */
1707         Py_INCREF(value);
1708         return value;
1709     }
1710 /* ctypes array or pointer instance */
1711     if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1712         /* Any array or pointer is accepted */
1713         Py_INCREF(value);
1714         return value;
1715     }
1716 /* byref(...) */
1717     if (PyCArg_CheckExact(value)) {
1718         /* byref(c_xxx()) */
1719         PyCArgObject *a = (PyCArgObject *)value;
1720         if (a->tag == 'P') {
1721             Py_INCREF(value);
1722             return value;
1723         }
1724     }
1725 /* function pointer */
1726     if (PyCFuncPtrObject_Check(value)) {
1727         PyCArgObject *parg;
1728         PyCFuncPtrObject *func;
1729         func = (PyCFuncPtrObject *)value;
1730         parg = PyCArgObject_new();
1731         if (parg == NULL)
1732             return NULL;
1733         parg->pffi_type = &ffi_type_pointer;
1734         parg->tag = 'P';
1735         Py_INCREF(value);
1736         parg->value.p = *(void **)func->b_ptr;
1737         parg->obj = value;
1738         return (PyObject *)parg;
1739     }
1740 /* c_char_p, c_wchar_p */
1741     stgd = PyObject_stgdict(value);
1742     if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
1743         PyCArgObject *parg;
1744 
1745         switch (PyString_AS_STRING(stgd->proto)[0]) {
1746         case 'z': /* c_char_p */
1747         case 'Z': /* c_wchar_p */
1748             parg = PyCArgObject_new();
1749             if (parg == NULL)
1750                 return NULL;
1751             parg->pffi_type = &ffi_type_pointer;
1752             parg->tag = 'Z';
1753             Py_INCREF(value);
1754             parg->obj = value;
1755             /* Remember: b_ptr points to where the pointer is stored! */
1756             parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
1757             return (PyObject *)parg;
1758         }
1759     }
1760 
1761     as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
1762     if (as_parameter) {
1763         value = c_void_p_from_param(type, as_parameter);
1764         Py_DECREF(as_parameter);
1765         return value;
1766     }
1767     /* XXX better message */
1768     PyErr_SetString(PyExc_TypeError,
1769                     "wrong type");
1770     return NULL;
1771 }
1772 #if (PYTHON_API_VERSION >= 1012)
1773 
1774 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1775 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
1776 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1777 
1778 #else
1779 #error
1780 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_VARARGS };
1781 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_VARARGS };
1782 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_VARARGS };
1783 
1784 #endif
1785 
1786 static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
1787                                    PyObject *proto, struct fielddesc *fmt)
1788 {
1789     PyTypeObject *result;
1790     StgDictObject *stgdict;
1791     PyObject *name = PyTuple_GET_ITEM(args, 0);
1792     PyObject *swapped_args;
1793     static PyObject *suffix;
1794     Py_ssize_t i;
1795 
1796     swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
1797     if (!swapped_args)
1798         return NULL;
1799 
1800     if (suffix == NULL)
1801 #ifdef WORDS_BIGENDIAN
1802         suffix = PyString_InternFromString("_le");
1803 #else
1804         suffix = PyString_InternFromString("_be");
1805 #endif
1806 
1807     Py_INCREF(name);
1808     PyString_Concat(&name, suffix);
1809     if (name == NULL)
1810         return NULL;
1811 
1812     PyTuple_SET_ITEM(swapped_args, 0, name);
1813     for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
1814         PyObject *v = PyTuple_GET_ITEM(args, i);
1815         Py_INCREF(v);
1816         PyTuple_SET_ITEM(swapped_args, i, v);
1817     }
1818 
1819     /* create the new instance (which is a class,
1820        since we are a metatype!) */
1821     result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
1822     Py_DECREF(swapped_args);
1823     if (result == NULL)
1824         return NULL;
1825 
1826     stgdict = (StgDictObject *)PyObject_CallObject(
1827         (PyObject *)&PyCStgDict_Type, NULL);
1828     if (!stgdict) /* XXX leaks result! */
1829         return NULL;
1830 
1831     stgdict->ffi_type_pointer = *fmt->pffi_type;
1832     stgdict->align = fmt->pffi_type->alignment;
1833     stgdict->length = 0;
1834     stgdict->size = fmt->pffi_type->size;
1835     stgdict->setfunc = fmt->setfunc_swapped;
1836     stgdict->getfunc = fmt->getfunc_swapped;
1837 
1838     Py_INCREF(proto);
1839     stgdict->proto = proto;
1840 
1841     /* replace the class dict by our updated spam dict */
1842     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1843         Py_DECREF(result);
1844         Py_DECREF((PyObject *)stgdict);
1845         return NULL;
1846     }
1847     Py_DECREF(result->tp_dict);
1848     result->tp_dict = (PyObject *)stgdict;
1849 
1850     return (PyObject *)result;
1851 }
1852 
1853 static PyCArgObject *
1854 PyCSimpleType_paramfunc(CDataObject *self)
1855 {
1856     StgDictObject *dict;
1857     char *fmt;
1858     PyCArgObject *parg;
1859     struct fielddesc *fd;
1860 
1861     dict = PyObject_stgdict((PyObject *)self);
1862     assert(dict); /* Cannot be NULL for CDataObject instances */
1863     fmt = PyString_AsString(dict->proto);
1864     assert(fmt);
1865 
1866     fd = _ctypes_get_fielddesc(fmt);
1867     assert(fd);
1868 
1869     parg = PyCArgObject_new();
1870     if (parg == NULL)
1871         return NULL;
1872 
1873     parg->tag = fmt[0];
1874     parg->pffi_type = fd->pffi_type;
1875     Py_INCREF(self);
1876     parg->obj = (PyObject *)self;
1877     memcpy(&parg->value, self->b_ptr, self->b_size);
1878     return parg;
1879 }
1880 
1881 static PyObject *
1882 PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1883 {
1884     PyTypeObject *result;
1885     StgDictObject *stgdict;
1886     PyObject *proto;
1887     const char *proto_str;
1888     Py_ssize_t proto_len;
1889     PyMethodDef *ml;
1890     struct fielddesc *fmt;
1891 
1892     /* create the new instance (which is a class,
1893        since we are a metatype!) */
1894     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1895     if (result == NULL)
1896         return NULL;
1897 
1898     proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
1899     if (!proto) {
1900         PyErr_SetString(PyExc_AttributeError,
1901                         "class must define a '_type_' attribute");
1902   error:
1903         Py_XDECREF(proto);
1904         Py_XDECREF(result);
1905         return NULL;
1906     }
1907     if (PyString_Check(proto)) {
1908         proto_str = PyString_AS_STRING(proto);
1909         proto_len = PyString_GET_SIZE(proto);
1910     } else {
1911         PyErr_SetString(PyExc_TypeError,
1912             "class must define a '_type_' string attribute");
1913         goto error;
1914     }
1915     if (proto_len != 1) {
1916         PyErr_SetString(PyExc_ValueError,
1917                         "class must define a '_type_' attribute "
1918                         "which must be a string of length 1");
1919         goto error;
1920     }
1921     if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
1922         PyErr_Format(PyExc_AttributeError,
1923                      "class must define a '_type_' attribute which must be\n"
1924                      "a single character string containing one of '%s'.",
1925                      SIMPLE_TYPE_CHARS);
1926         goto error;
1927     }
1928     fmt = _ctypes_get_fielddesc(PyString_AS_STRING(proto));
1929     if (fmt == NULL) {
1930         PyErr_Format(PyExc_ValueError,
1931                      "_type_ '%s' not supported",
1932                      PyString_AS_STRING(proto));
1933         goto error;
1934     }
1935 
1936     stgdict = (StgDictObject *)PyObject_CallObject(
1937         (PyObject *)&PyCStgDict_Type, NULL);
1938     if (!stgdict)
1939         goto error;
1940 
1941     stgdict->ffi_type_pointer = *fmt->pffi_type;
1942     stgdict->align = fmt->pffi_type->alignment;
1943     stgdict->length = 0;
1944     stgdict->size = fmt->pffi_type->size;
1945     stgdict->setfunc = fmt->setfunc;
1946     stgdict->getfunc = fmt->getfunc;
1947 #ifdef WORDS_BIGENDIAN
1948     stgdict->format = _ctypes_alloc_format_string(">", proto_str);
1949 #else
1950     stgdict->format = _ctypes_alloc_format_string("<", proto_str);
1951 #endif
1952     if (stgdict->format == NULL) {
1953         Py_DECREF(result);
1954         Py_DECREF(proto);
1955         Py_DECREF((PyObject *)stgdict);
1956         return NULL;
1957     }
1958 
1959     stgdict->paramfunc = PyCSimpleType_paramfunc;
1960 /*
1961     if (result->tp_base != &Simple_Type) {
1962         stgdict->setfunc = NULL;
1963         stgdict->getfunc = NULL;
1964     }
1965 */
1966 
1967     /* This consumes the refcount on proto which we have */
1968     stgdict->proto = proto;
1969 
1970     /* replace the class dict by our updated spam dict */
1971     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1972         Py_DECREF(result);
1973         Py_DECREF((PyObject *)stgdict);
1974         return NULL;
1975     }
1976     Py_DECREF(result->tp_dict);
1977     result->tp_dict = (PyObject *)stgdict;
1978 
1979     /* Install from_param class methods in ctypes base classes.
1980        Overrides the PyCSimpleType_from_param generic method.
1981      */
1982     if (result->tp_base == &Simple_Type) {
1983         switch (PyString_AS_STRING(proto)[0]) {
1984         case 'z': /* c_char_p */
1985             ml = &c_char_p_method;
1986             stgdict->flags |= TYPEFLAG_ISPOINTER;
1987             break;
1988         case 'Z': /* c_wchar_p */
1989             ml = &c_wchar_p_method;
1990             stgdict->flags |= TYPEFLAG_ISPOINTER;
1991             break;
1992         case 'P': /* c_void_p */
1993             ml = &c_void_p_method;
1994             stgdict->flags |= TYPEFLAG_ISPOINTER;
1995             break;
1996         case 's':
1997         case 'X':
1998         case 'O':
1999             ml = NULL;
2000             stgdict->flags |= TYPEFLAG_ISPOINTER;
2001             break;
2002         default:
2003             ml = NULL;
2004             break;
2005         }
2006 
2007         if (ml) {
2008 #if (PYTHON_API_VERSION >= 1012)
2009             PyObject *meth;
2010             int x;
2011             meth = PyDescr_NewClassMethod(result, ml);
2012             if (!meth)
2013                 return NULL;
2014 #else
2015 #error
2016             PyObject *meth, *func;
2017             int x;
2018             func = PyCFunction_New(ml, NULL);
2019             if (!func)
2020                 return NULL;
2021             meth = PyObject_CallFunctionObjArgs(
2022                 (PyObject *)&PyClassMethod_Type,
2023                 func, NULL);
2024             Py_DECREF(func);
2025             if (!meth) {
2026                 return NULL;
2027             }
2028 #endif
2029             x = PyDict_SetItemString(result->tp_dict,
2030                                      ml->ml_name,
2031                                      meth);
2032             Py_DECREF(meth);
2033             if (x == -1) {
2034                 Py_DECREF(result);
2035                 return NULL;
2036             }
2037         }
2038     }
2039 
2040     if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
2041         PyObject *swapped = CreateSwappedType(type, args, kwds,
2042                                               proto, fmt);
2043         StgDictObject *sw_dict;
2044         if (swapped == NULL) {
2045             Py_DECREF(result);
2046             return NULL;
2047         }
2048         sw_dict = PyType_stgdict(swapped);
2049 #ifdef WORDS_BIGENDIAN
2050         PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
2051         PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
2052         PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
2053         PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
2054         /* We are creating the type for the OTHER endian */
2055         sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1);
2056 #else
2057         PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
2058         PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
2059         PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
2060         PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
2061         /* We are creating the type for the OTHER endian */
2062         sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1);
2063 #endif
2064         Py_DECREF(swapped);
2065         if (PyErr_Occurred()) {
2066             Py_DECREF(result);
2067             return NULL;
2068         }
2069     };
2070 
2071     return (PyObject *)result;
2072 }
2073 
2074 /*
2075  * This is a *class method*.
2076  * Convert a parameter into something that ConvParam can handle.
2077  */
2078 static PyObject *
2079 PyCSimpleType_from_param(PyObject *type, PyObject *value)
2080 {
2081     StgDictObject *dict;
2082     char *fmt;
2083     PyCArgObject *parg;
2084     struct fielddesc *fd;
2085     PyObject *as_parameter;
2086     int res;
2087 
2088     /* If the value is already an instance of the requested type,
2089        we can use it as is */
2090     res = PyObject_IsInstance(value, type);
2091     if (res == -1)
2092         return NULL;
2093     if (res) {
2094         Py_INCREF(value);
2095         return value;
2096     }
2097 
2098     dict = PyType_stgdict(type);
2099     assert(dict);
2100 
2101     /* I think we can rely on this being a one-character string */
2102     fmt = PyString_AsString(dict->proto);
2103     assert(fmt);
2104 
2105     fd = _ctypes_get_fielddesc(fmt);
2106     assert(fd);
2107 
2108     parg = PyCArgObject_new();
2109     if (parg == NULL)
2110         return NULL;
2111 
2112     parg->tag = fmt[0];
2113     parg->pffi_type = fd->pffi_type;
2114     parg->obj = fd->setfunc(&parg->value, value, 0);
2115     if (parg->obj)
2116         return (PyObject *)parg;
2117     PyErr_Clear();
2118     Py_DECREF(parg);
2119 
2120     as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
2121     if (as_parameter) {
2122         if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
2123             Py_DECREF(as_parameter);
2124             return NULL;
2125         }
2126         value = PyCSimpleType_from_param(type, as_parameter);
2127         Py_LeaveRecursiveCall();
2128         Py_DECREF(as_parameter);
2129         return value;
2130     }
2131     PyErr_SetString(PyExc_TypeError,
2132                     "wrong type");
2133     return NULL;
2134 }
2135 
2136 static PyMethodDef PyCSimpleType_methods[] = {
2137     { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc },
2138     { "from_address", CDataType_from_address, METH_O, from_address_doc },
2139     { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
2140     { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
2141     { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
2142     { NULL, NULL },
2143 };
2144 
2145 PyTypeObject PyCSimpleType_Type = {
2146     PyVarObject_HEAD_INIT(NULL, 0)
2147     "_ctypes.PyCSimpleType",                                    /* tp_name */
2148     0,                                          /* tp_basicsize */
2149     0,                                          /* tp_itemsize */
2150     0,                                          /* tp_dealloc */
2151     0,                                          /* tp_print */
2152     0,                                          /* tp_getattr */
2153     0,                                          /* tp_setattr */
2154     0,                                          /* tp_compare */
2155     0,                                          /* tp_repr */
2156     0,                                          /* tp_as_number */
2157     &CDataType_as_sequence,             /* tp_as_sequence */
2158     0,                                          /* tp_as_mapping */
2159     0,                                          /* tp_hash */
2160     0,                                          /* tp_call */
2161     0,                                          /* tp_str */
2162     0,                                          /* tp_getattro */
2163     0,                                          /* tp_setattro */
2164     0,                                          /* tp_as_buffer */
2165     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2166     "metatype for the PyCSimpleType Objects",           /* tp_doc */
2167     0,                                          /* tp_traverse */
2168     0,                                          /* tp_clear */
2169     0,                                          /* tp_richcompare */
2170     0,                                          /* tp_weaklistoffset */
2171     0,                                          /* tp_iter */
2172     0,                                          /* tp_iternext */
2173     PyCSimpleType_methods,                      /* tp_methods */
2174     0,                                          /* tp_members */
2175     0,                                          /* tp_getset */
2176     0,                                          /* tp_base */
2177     0,                                          /* tp_dict */
2178     0,                                          /* tp_descr_get */
2179     0,                                          /* tp_descr_set */
2180     0,                                          /* tp_dictoffset */
2181     0,                                          /* tp_init */
2182     0,                                          /* tp_alloc */
2183     PyCSimpleType_new,                                  /* tp_new */
2184     0,                                          /* tp_free */
2185 };
2186 
2187 /******************************************************************/
2188 /*
2189   PyCFuncPtrType_Type
2190  */
2191 
2192 static PyObject *
2193 converters_from_argtypes(PyObject *ob)
2194 {
2195     PyObject *converters;
2196     Py_ssize_t i;
2197     Py_ssize_t nArgs;
2198 
2199     ob = PySequence_Tuple(ob); /* new reference */
2200     if (!ob) {
2201         PyErr_SetString(PyExc_TypeError,
2202                         "_argtypes_ must be a sequence of types");
2203         return NULL;
2204     }
2205 
2206     nArgs = PyTuple_GET_SIZE(ob);
2207     converters = PyTuple_New(nArgs);
2208     if (!converters)
2209         return NULL;
2210 
2211     /* I have to check if this is correct. Using c_char, which has a size
2212        of 1, will be assumed to be pushed as only one byte!
2213        Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
2214     */
2215 
2216     for (i = 0; i < nArgs; ++i) {
2217         PyObject *tp = PyTuple_GET_ITEM(ob, i);
2218         PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
2219         if (!cnv)
2220             goto argtypes_error_1;
2221         PyTuple_SET_ITEM(converters, i, cnv);
2222     }
2223     Py_DECREF(ob);
2224     return converters;
2225 
2226   argtypes_error_1:
2227     Py_XDECREF(converters);
2228     Py_DECREF(ob);
2229     PyErr_Format(PyExc_TypeError,
2230 #if (PY_VERSION_HEX < 0x02050000)
2231                  "item %d in _argtypes_ has no from_param method",
2232 #else
2233                  "item %zd in _argtypes_ has no from_param method",
2234 #endif
2235                  i+1);
2236     return NULL;
2237 }
2238 
2239 static int
2240 make_funcptrtype_dict(StgDictObject *stgdict)
2241 {
2242     PyObject *ob;
2243     PyObject *converters = NULL;
2244 
2245     stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
2246     stgdict->length = 1;
2247     stgdict->size = sizeof(void *);
2248     stgdict->setfunc = NULL;
2249     stgdict->getfunc = NULL;
2250     stgdict->ffi_type_pointer = ffi_type_pointer;
2251 
2252     ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
2253     if (!ob || !PyInt_Check(ob)) {
2254         PyErr_SetString(PyExc_TypeError,
2255             "class must define _flags_ which must be an integer");
2256         return -1;
2257     }
2258     stgdict->flags = PyInt_AS_LONG(ob) | TYPEFLAG_ISPOINTER;
2259 
2260     /* _argtypes_ is optional... */
2261     ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
2262     if (ob) {
2263         converters = converters_from_argtypes(ob);
2264         if (!converters)
2265             goto error;
2266         Py_INCREF(ob);
2267         stgdict->argtypes = ob;
2268         stgdict->converters = converters;
2269     }
2270 
2271     ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
2272     if (ob) {
2273         if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2274             PyErr_SetString(PyExc_TypeError,
2275                 "_restype_ must be a type, a callable, or None");
2276             return -1;
2277         }
2278         Py_INCREF(ob);
2279         stgdict->restype = ob;
2280         stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
2281         if (stgdict->checker == NULL)
2282             PyErr_Clear();
2283     }
2284 /* XXX later, maybe.
2285     ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
2286     if (ob) {
2287         if (!PyCallable_Check(ob)) {
2288             PyErr_SetString(PyExc_TypeError,
2289                 "_errcheck_ must be callable");
2290             return -1;
2291         }
2292         Py_INCREF(ob);
2293         stgdict->errcheck = ob;
2294     }
2295 */
2296     return 0;
2297 
2298   error:
2299     Py_XDECREF(converters);
2300     return -1;
2301 
2302 }
2303 
2304 static PyCArgObject *
2305 PyCFuncPtrType_paramfunc(CDataObject *self)
2306 {
2307     PyCArgObject *parg;
2308 
2309     parg = PyCArgObject_new();
2310     if (parg == NULL)
2311         return NULL;
2312 
2313     parg->tag = 'P';
2314     parg->pffi_type = &ffi_type_pointer;
2315     Py_INCREF(self);
2316     parg->obj = (PyObject *)self;
2317     parg->value.p = *(void **)self->b_ptr;
2318     return parg;
2319 }
2320 
2321 static PyObject *
2322 PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2323 {
2324     PyTypeObject *result;
2325     StgDictObject *stgdict;
2326 
2327     stgdict = (StgDictObject *)PyObject_CallObject(
2328         (PyObject *)&PyCStgDict_Type, NULL);
2329     if (!stgdict)
2330         return NULL;
2331 
2332     stgdict->paramfunc = PyCFuncPtrType_paramfunc;
2333     /* We do NOT expose the function signature in the format string.  It
2334        is impossible, generally, because the only requirement for the
2335        argtypes items is that they have a .from_param method - we do not
2336        know the types of the arguments (although, in practice, most
2337        argtypes would be a ctypes type).
2338     */
2339     stgdict->format = _ctypes_alloc_format_string(NULL, "X{}");
2340     stgdict->flags |= TYPEFLAG_ISPOINTER;
2341 
2342     /* create the new instance (which is a class,
2343        since we are a metatype!) */
2344     result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
2345     if (result == NULL) {
2346         Py_DECREF((PyObject *)stgdict);
2347         return NULL;
2348     }
2349 
2350     /* replace the class dict by our updated storage dict */
2351     if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
2352         Py_DECREF(result);
2353         Py_DECREF((PyObject *)stgdict);
2354         return NULL;
2355     }
2356     Py_DECREF(result->tp_dict);
2357     result->tp_dict = (PyObject *)stgdict;
2358 
2359     if (-1 == make_funcptrtype_dict(stgdict)) {
2360         Py_DECREF(result);
2361         return NULL;
2362     }
2363 
2364     return (PyObject *)result;
2365 }
2366 
2367 PyTypeObject PyCFuncPtrType_Type = {
2368     PyVarObject_HEAD_INIT(NULL, 0)
2369     "_ctypes.PyCFuncPtrType",                           /* tp_name */
2370     0,                                          /* tp_basicsize */
2371     0,                                          /* tp_itemsize */
2372     0,                                          /* tp_dealloc */
2373     0,                                          /* tp_print */
2374     0,                                          /* tp_getattr */
2375     0,                                          /* tp_setattr */
2376     0,                                          /* tp_compare */
2377     0,                                          /* tp_repr */
2378     0,                                          /* tp_as_number */
2379     &CDataType_as_sequence,                     /* tp_as_sequence */
2380     0,                                          /* tp_as_mapping */
2381     0,                                          /* tp_hash */
2382     0,                                          /* tp_call */
2383     0,                                          /* tp_str */
2384     0,                                          /* tp_getattro */
2385     0,                                          /* tp_setattro */
2386     0,                                          /* tp_as_buffer */
2387     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2388     "metatype for C function pointers",         /* tp_doc */
2389     (traverseproc)CDataType_traverse,           /* tp_traverse */
2390     (inquiry)CDataType_clear,                   /* tp_clear */
2391     0,                                          /* tp_richcompare */
2392     0,                                          /* tp_weaklistoffset */
2393     0,                                          /* tp_iter */
2394     0,                                          /* tp_iternext */
2395     CDataType_methods,                          /* tp_methods */
2396     0,                                          /* tp_members */
2397     0,                                          /* tp_getset */
2398     0,                                          /* tp_base */
2399     0,                                          /* tp_dict */
2400     0,                                          /* tp_descr_get */
2401     0,                                          /* tp_descr_set */
2402     0,                                          /* tp_dictoffset */
2403     0,                                          /* tp_init */
2404     0,                                          /* tp_alloc */
2405     PyCFuncPtrType_new,                         /* tp_new */
2406     0,                                          /* tp_free */
2407 };
2408 
2409 
2410 /*****************************************************************
2411  * Code to keep needed objects alive
2412  */
2413 
2414 static CDataObject *
2415 PyCData_GetContainer(CDataObject *self)
2416 {
2417     while (self->b_base)
2418         self = self->b_base;
2419     if (self->b_objects == NULL) {
2420         if (self->b_length) {
2421             self->b_objects = PyDict_New();
2422         } else {
2423             Py_INCREF(Py_None);
2424             self->b_objects = Py_None;
2425         }
2426     }
2427     return self;
2428 }
2429 
2430 static PyObject *
2431 GetKeepedObjects(CDataObject *target)
2432 {
2433     return PyCData_GetContainer(target)->b_objects;
2434 }
2435 
2436 static PyObject *
2437 unique_key(CDataObject *target, Py_ssize_t index)
2438 {
2439     char string[256];
2440     char *cp = string;
2441     size_t bytes_left;
2442 
2443     assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
2444 #if (PY_VERSION_HEX < 0x02050000)
2445     cp += sprintf(cp, "%x", index);
2446 #else
2447     cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2448 #endif
2449     while (target->b_base) {
2450         bytes_left = sizeof(string) - (cp - string) - 1;
2451         /* Hex format needs 2 characters per byte */
2452         if (bytes_left < sizeof(Py_ssize_t) * 2) {
2453             PyErr_SetString(PyExc_ValueError,
2454                             "ctypes object structure too deep");
2455             return NULL;
2456         }
2457 #if (PY_VERSION_HEX < 0x02050000)
2458         cp += sprintf(cp, ":%x", (int)target->b_index);
2459 #else
2460         cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
2461 #endif
2462         target = target->b_base;
2463     }
2464     return PyString_FromStringAndSize(string, cp-string);
2465 }
2466 
2467 /*
2468  * Keep a reference to 'keep' in the 'target', at index 'index'.
2469  *
2470  * If 'keep' is None, do nothing.
2471  *
2472  * Otherwise create a dictionary (if it does not yet exist) id the root
2473  * objects 'b_objects' item, which will store the 'keep' object under a unique
2474  * key.
2475  *
2476  * The unique_key helper travels the target's b_base pointer down to the root,
2477  * building a string containing hex-formatted indexes found during traversal,
2478  * separated by colons.
2479  *
2480  * The index tuple is used as a key into the root object's b_objects dict.
2481  *
2482  * Note: This function steals a refcount of the third argument, even if it
2483  * fails!
2484  */
2485 static int
2486 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
2487 {
2488     int result;
2489     CDataObject *ob;
2490     PyObject *key;
2491 
2492 /* Optimization: no need to store None */
2493     if (keep == Py_None) {
2494         Py_DECREF(Py_None);
2495         return 0;
2496     }
2497     ob = PyCData_GetContainer(target);
2498     if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
2499         Py_XDECREF(ob->b_objects);
2500         ob->b_objects = keep; /* refcount consumed */
2501         return 0;
2502     }
2503     key = unique_key(target, index);
2504     if (key == NULL) {
2505         Py_DECREF(keep);
2506         return -1;
2507     }
2508     result = PyDict_SetItem(ob->b_objects, key, keep);
2509     Py_DECREF(key);
2510     Py_DECREF(keep);
2511     return result;
2512 }
2513 
2514 /******************************************************************/
2515 /*
2516   PyCData_Type
2517  */
2518 static int
2519 PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
2520 {
2521     Py_VISIT(self->b_objects);
2522     Py_VISIT((PyObject *)self->b_base);
2523     return 0;
2524 }
2525 
2526 static int
2527 PyCData_clear(CDataObject *self)
2528 {
2529     StgDictObject *dict = PyObject_stgdict((PyObject *)self);
2530     assert(dict); /* Cannot be NULL for CDataObject instances */
2531     Py_CLEAR(self->b_objects);
2532     if ((self->b_needsfree)
2533         && ((size_t)dict->size > sizeof(self->b_value)))
2534         PyMem_Free(self->b_ptr);
2535     self->b_ptr = NULL;
2536     Py_CLEAR(self->b_base);
2537     return 0;
2538 }
2539 
2540 static void
2541 PyCData_dealloc(PyObject *self)
2542 {
2543     PyCData_clear((CDataObject *)self);
2544     Py_TYPE(self)->tp_free(self);
2545 }
2546 
2547 static PyMemberDef PyCData_members[] = {
2548     { "_b_base_", T_OBJECT,
2549       offsetof(CDataObject, b_base), READONLY,
2550       "the base object" },
2551     { "_b_needsfree_", T_INT,
2552       offsetof(CDataObject, b_needsfree), READONLY,
2553       "whether the object owns the memory or not" },
2554     { "_objects", T_OBJECT,
2555       offsetof(CDataObject, b_objects), READONLY,
2556       "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2557     { NULL },
2558 };
2559 
2560 #if (PY_VERSION_HEX >= 0x02060000)
2561 static int PyCData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags)
2562 {
2563     CDataObject *self = (CDataObject *)_self;
2564     StgDictObject *dict = PyObject_stgdict(_self);
2565     Py_ssize_t i;
2566 
2567     if (view == NULL) return 0;
2568 
2569     view->buf = self->b_ptr;
2570     view->obj = _self;
2571     Py_INCREF(_self);
2572     view->len = self->b_size;
2573     view->readonly = 0;
2574     /* use default format character if not set */
2575     view->format = dict->format ? dict->format : "B";
2576     view->ndim = dict->ndim;
2577     view->shape = dict->shape;
2578     view->itemsize = self->b_size;
2579     if (view->itemsize) {
2580         for (i = 0; i < view->ndim; ++i) {
2581             view->itemsize /= dict->shape[i];
2582         }
2583     }
2584     view->strides = NULL;
2585     view->suboffsets = NULL;
2586     view->internal = NULL;
2587     return 0;
2588 }
2589 #endif
2590 
2591 static Py_ssize_t PyCData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
2592 {
2593     if (lenp)
2594         *lenp = 1;
2595     return 1;
2596 }
2597 
2598 static Py_ssize_t PyCData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr)
2599 {
2600     CDataObject *self = (CDataObject *)_self;
2601     if (seg != 0) {
2602         /* Hm. Must this set an exception? */
2603         return -1;
2604     }
2605     *pptr = self->b_ptr;
2606     return self->b_size;
2607 }
2608 
2609 static PyBufferProcs PyCData_as_buffer = {
2610     (readbufferproc)PyCData_GetBuffer,
2611     (writebufferproc)PyCData_GetBuffer,
2612     (segcountproc)PyCData_GetSegcount,
2613     (charbufferproc)NULL,
2614 #if (PY_VERSION_HEX >= 0x02060000)
2615     (getbufferproc)PyCData_NewGetBuffer,
2616     (releasebufferproc)NULL,
2617 #endif
2618 };
2619 
2620 /*
2621  * CData objects are mutable, so they cannot be hashable!
2622  */
2623 static long
2624 PyCData_nohash(PyObject *self)
2625 {
2626     PyErr_SetString(PyExc_TypeError, "unhashable type");
2627     return -1;
2628 }
2629 
2630 static PyObject *
2631 PyCData_reduce(PyObject *_self, PyObject *args)
2632 {
2633     CDataObject *self = (CDataObject *)_self;
2634 
2635     if (PyObject_stgdict(_self)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
2636         PyErr_SetString(PyExc_ValueError,
2637                         "ctypes objects containing pointers cannot be pickled");
2638         return NULL;
2639     }
2640     return Py_BuildValue("O(O(NN))",
2641                          _unpickle,
2642                          Py_TYPE(_self),
2643                          PyObject_GetAttrString(_self, "__dict__"),
2644                          PyString_FromStringAndSize(self->b_ptr, self->b_size));
2645 }
2646 
2647 static PyObject *
2648 PyCData_setstate(PyObject *_self, PyObject *args)
2649 {
2650     void *data;
2651     Py_ssize_t len;
2652     int res;
2653     PyObject *dict, *mydict;
2654     CDataObject *self = (CDataObject *)_self;
2655     if (!PyArg_ParseTuple(args, "Os#", &dict, &data, &len))
2656         return NULL;
2657     if (len > self->b_size)
2658         len = self->b_size;
2659     memmove(self->b_ptr, data, len);
2660     mydict = PyObject_GetAttrString(_self, "__dict__");
2661     res = PyDict_Update(mydict, dict);
2662     Py_DECREF(mydict);
2663     if (res == -1)
2664         return NULL;
2665     Py_INCREF(Py_None);
2666     return Py_None;
2667 }
2668 
2669 /*
2670  * default __ctypes_from_outparam__ method returns self.
2671  */
2672 static PyObject *
2673 PyCData_from_outparam(PyObject *self, PyObject *args)
2674 {
2675     Py_INCREF(self);
2676     return self;
2677 }
2678 
2679 static PyMethodDef PyCData_methods[] = {
2680     { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
2681     { "__reduce__", PyCData_reduce, METH_NOARGS, },
2682     { "__setstate__", PyCData_setstate, METH_VARARGS, },
2683     { NULL, NULL },
2684 };
2685 
2686 PyTypeObject PyCData_Type = {
2687     PyVarObject_HEAD_INIT(NULL, 0)
2688     "_ctypes._CData",
2689     sizeof(CDataObject),                        /* tp_basicsize */
2690     0,                                          /* tp_itemsize */
2691     PyCData_dealloc,                                    /* tp_dealloc */
2692     0,                                          /* tp_print */
2693     0,                                          /* tp_getattr */
2694     0,                                          /* tp_setattr */
2695     0,                                          /* tp_compare */
2696     0,                                          /* tp_repr */
2697     0,                                          /* tp_as_number */
2698     0,                                          /* tp_as_sequence */
2699     0,                                          /* tp_as_mapping */
2700     PyCData_nohash,                             /* tp_hash */
2701     0,                                          /* tp_call */
2702     0,                                          /* tp_str */
2703     0,                                          /* tp_getattro */
2704     0,                                          /* tp_setattro */
2705     &PyCData_as_buffer,                         /* tp_as_buffer */
2706     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
2707     "XXX to be provided",                       /* tp_doc */
2708     (traverseproc)PyCData_traverse,             /* tp_traverse */
2709     (inquiry)PyCData_clear,                     /* tp_clear */
2710     0,                                          /* tp_richcompare */
2711     0,                                          /* tp_weaklistoffset */
2712     0,                                          /* tp_iter */
2713     0,                                          /* tp_iternext */
2714     PyCData_methods,                                    /* tp_methods */
2715     PyCData_members,                                    /* tp_members */
2716     0,                                          /* tp_getset */
2717     0,                                          /* tp_base */
2718     0,                                          /* tp_dict */
2719     0,                                          /* tp_descr_get */
2720     0,                                          /* tp_descr_set */
2721     0,                                          /* tp_dictoffset */
2722     0,                                          /* tp_init */
2723     0,                                          /* tp_alloc */
2724     0,                                          /* tp_new */
2725     0,                                          /* tp_free */
2726 };
2727 
2728 static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
2729 {
2730     if ((size_t)dict->size <= sizeof(obj->b_value)) {
2731         /* No need to call malloc, can use the default buffer */
2732         obj->b_ptr = (char *)&obj->b_value;
2733         /* The b_needsfree flag does not mean that we actually did
2734            call PyMem_Malloc to allocate the memory block; instead it
2735            means we are the *owner* of the memory and are responsible
2736            for freeing resources associated with the memory.  This is
2737            also the reason that b_needsfree is exposed to Python.
2738          */
2739         obj->b_needsfree = 1;
2740     } else {
2741         /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2742            33% of the creation time for c_int().
2743         */
2744         obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2745         if (obj->b_ptr == NULL) {
2746             PyErr_NoMemory();
2747             return -1;
2748         }
2749         obj->b_needsfree = 1;
2750         memset(obj->b_ptr, 0, dict->size);
2751     }
2752     obj->b_size = dict->size;
2753     return 0;
2754 }
2755 
2756 PyObject *
2757 PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
2758 {
2759     CDataObject *cmem;
2760     StgDictObject *dict;
2761 
2762     assert(PyType_Check(type));
2763     dict = PyType_stgdict(type);
2764     if (!dict) {
2765         PyErr_SetString(PyExc_TypeError,
2766                         "abstract class");
2767         return NULL;
2768     }
2769     dict->flags |= DICTFLAG_FINAL;
2770     cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2771     if (cmem == NULL)
2772         return NULL;
2773     assert(CDataObject_Check(cmem));
2774 
2775     cmem->b_length = dict->length;
2776     cmem->b_size = dict->size;
2777     if (base) { /* use base's buffer */
2778         assert(CDataObject_Check(base));
2779         cmem->b_ptr = adr;
2780         cmem->b_needsfree = 0;
2781         Py_INCREF(base);
2782         cmem->b_base = (CDataObject *)base;
2783         cmem->b_index = index;
2784     } else { /* copy contents of adr */
2785         if (-1 == PyCData_MallocBuffer(cmem, dict)) {
2786             return NULL;
2787             Py_DECREF(cmem);
2788         }
2789         memcpy(cmem->b_ptr, adr, dict->size);
2790         cmem->b_index = index;
2791     }
2792     return (PyObject *)cmem;
2793 }
2794 
2795 /*
2796  Box a memory block into a CData instance.
2797 */
2798 PyObject *
2799 PyCData_AtAddress(PyObject *type, void *buf)
2800 {
2801     CDataObject *pd;
2802     StgDictObject *dict;
2803 
2804     assert(PyType_Check(type));
2805     dict = PyType_stgdict(type);
2806     if (!dict) {
2807         PyErr_SetString(PyExc_TypeError,
2808                         "abstract class");
2809         return NULL;
2810     }
2811     dict->flags |= DICTFLAG_FINAL;
2812 
2813     pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2814     if (!pd)
2815         return NULL;
2816     assert(CDataObject_Check(pd));
2817     pd->b_ptr = (char *)buf;
2818     pd->b_length = dict->length;
2819     pd->b_size = dict->size;
2820     return (PyObject *)pd;
2821 }
2822 
2823 /*
2824   This function returns TRUE for c_int, c_void_p, and these kind of
2825   classes.  FALSE otherwise FALSE also for subclasses of c_int and
2826   such.
2827 */
2828 int _ctypes_simple_instance(PyObject *obj)
2829 {
2830     PyTypeObject *type = (PyTypeObject *)obj;
2831 
2832     if (PyCSimpleTypeObject_Check(type))
2833         return type->tp_base != &Simple_Type;
2834     return 0;
2835 }
2836 
2837 PyObject *
2838 PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
2839           Py_ssize_t index, Py_ssize_t size, char *adr)
2840 {
2841     StgDictObject *dict;
2842     if (getfunc)
2843         return getfunc(adr, size);
2844     assert(type);
2845     dict = PyType_stgdict(type);
2846     if (dict && dict->getfunc && !_ctypes_simple_instance(type))
2847         return dict->getfunc(adr, size);
2848     return PyCData_FromBaseObj(type, src, index, adr);
2849 }
2850 
2851 /*
2852   Helper function for PyCData_set below.
2853 */
2854 static PyObject *
2855 _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2856            Py_ssize_t size, char *ptr)
2857 {
2858     CDataObject *src;
2859     int err;
2860 
2861     if (setfunc)
2862         return setfunc(ptr, value, size);
2863 
2864     if (!CDataObject_Check(value)) {
2865         StgDictObject *dict = PyType_stgdict(type);
2866         if (dict && dict->setfunc)
2867             return dict->setfunc(ptr, value, size);
2868         /*
2869            If value is a tuple, we try to call the type with the tuple
2870            and use the result!
2871         */
2872         assert(PyType_Check(type));
2873         if (PyTuple_Check(value)) {
2874             PyObject *ob;
2875             PyObject *result;
2876             ob = PyObject_CallObject(type, value);
2877             if (ob == NULL) {
2878                 _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
2879                                   ((PyTypeObject *)type)->tp_name);
2880                 return NULL;
2881             }
2882             result = _PyCData_set(dst, type, setfunc, ob,
2883                                 size, ptr);
2884             Py_DECREF(ob);
2885             return result;
2886         } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
2887             *(void **)ptr = NULL;
2888             Py_INCREF(Py_None);
2889             return Py_None;
2890         } else {
2891             PyErr_Format(PyExc_TypeError,
2892                          "expected %s instance, got %s",
2893                          ((PyTypeObject *)type)->tp_name,
2894                          Py_TYPE(value)->tp_name);
2895             return NULL;
2896         }
2897     }
2898     src = (CDataObject *)value;
2899 
2900     err = PyObject_IsInstance(value, type);
2901     if (err == -1)
2902         return NULL;
2903     if (err) {
2904         memcpy(ptr,
2905                src->b_ptr,
2906                size);
2907 
2908         if (PyCPointerTypeObject_Check(type))
2909             /* XXX */;
2910 
2911         value = GetKeepedObjects(src);
2912         Py_INCREF(value);
2913         return value;
2914     }
2915 
2916     if (PyCPointerTypeObject_Check(type)
2917         && ArrayObject_Check(value)) {
2918         StgDictObject *p1, *p2;
2919         PyObject *keep;
2920         p1 = PyObject_stgdict(value);
2921         assert(p1); /* Cannot be NULL for array instances */
2922         p2 = PyType_stgdict(type);
2923         assert(p2); /* Cannot be NULL for pointer types */
2924 
2925         if (p1->proto != p2->proto) {
2926             PyErr_Format(PyExc_TypeError,
2927                          "incompatible types, %s instance instead of %s instance",
2928                          Py_TYPE(value)->tp_name,
2929                          ((PyTypeObject *)type)->tp_name);
2930             return NULL;
2931         }
2932         *(void **)ptr = src->b_ptr;
2933 
2934         keep = GetKeepedObjects(src);
2935         /*
2936           We are assigning an array object to a field which represents
2937           a pointer. This has the same effect as converting an array
2938           into a pointer. So, again, we have to keep the whole object
2939           pointed to (which is the array in this case) alive, and not
2940           only it's object list.  So we create a tuple, containing
2941           b_objects list PLUS the array itself, and return that!
2942         */
2943         return PyTuple_Pack(2, keep, value);
2944     }
2945     PyErr_Format(PyExc_TypeError,
2946                  "incompatible types, %s instance instead of %s instance",
2947                  Py_TYPE(value)->tp_name,
2948                  ((PyTypeObject *)type)->tp_name);
2949     return NULL;
2950 }
2951 
2952 /*
2953  * Set a slice in object 'dst', which has the type 'type',
2954  * to the value 'value'.
2955  */
2956 int
2957 PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2958           Py_ssize_t index, Py_ssize_t size, char *ptr)
2959 {
2960     CDataObject *mem = (CDataObject *)dst;
2961     PyObject *result;
2962 
2963     if (!CDataObject_Check(dst)) {
2964         PyErr_SetString(PyExc_TypeError,
2965                         "not a ctype instance");
2966         return -1;
2967     }
2968 
2969     result = _PyCData_set(mem, type, setfunc, value,
2970                         size, ptr);
2971     if (result == NULL)
2972         return -1;
2973 
2974     /* KeepRef steals a refcount from it's last argument */
2975     /* If KeepRef fails, we are stumped.  The dst memory block has already
2976        been changed */
2977     return KeepRef(mem, index, result);
2978 }
2979 
2980 
2981 /******************************************************************/
2982 static PyObject *
2983 GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2984 {
2985     CDataObject *obj;
2986     StgDictObject *dict;
2987 
2988     dict = PyType_stgdict((PyObject *)type);
2989     if (!dict) {
2990         PyErr_SetString(PyExc_TypeError,
2991                         "abstract class");
2992         return NULL;
2993     }
2994     dict->flags |= DICTFLAG_FINAL;
2995 
2996     obj = (CDataObject *)type->tp_alloc(type, 0);
2997     if (!obj)
2998         return NULL;
2999 
3000     obj->b_base = NULL;
3001     obj->b_index = 0;
3002     obj->b_objects = NULL;
3003     obj->b_length = dict->length;
3004 
3005     if (-1 == PyCData_MallocBuffer(obj, dict)) {
3006         Py_DECREF(obj);
3007         return NULL;
3008     }
3009     return (PyObject *)obj;
3010 }
3011 /*****************************************************************/
3012 /*
3013   PyCFuncPtr_Type
3014 */
3015 
3016 static int
3017 PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob)
3018 {
3019     if (ob && !PyCallable_Check(ob)) {
3020         PyErr_SetString(PyExc_TypeError,
3021                         "the errcheck attribute must be callable");
3022         return -1;
3023     }
3024     Py_XDECREF(self->errcheck);
3025     Py_XINCREF(ob);
3026     self->errcheck = ob;
3027     return 0;
3028 }
3029 
3030 static PyObject *
3031 PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self)
3032 {
3033     if (self->errcheck) {
3034         Py_INCREF(self->errcheck);
3035         return self->errcheck;
3036     }
3037     Py_INCREF(Py_None);
3038     return Py_None;
3039 }
3040 
3041 static int
3042 PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob)
3043 {
3044     if (ob == NULL) {
3045         Py_XDECREF(self->restype);
3046         self->restype = NULL;
3047         Py_XDECREF(self->checker);
3048         self->checker = NULL;
3049         return 0;
3050     }
3051     if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
3052         PyErr_SetString(PyExc_TypeError,
3053                         "restype must be a type, a callable, or None");
3054         return -1;
3055     }
3056     Py_XDECREF(self->checker);
3057     Py_XDECREF(self->restype);
3058     Py_INCREF(ob);
3059     self->restype = ob;
3060     self->checker = PyObject_GetAttrString(ob, "_check_retval_");
3061     if (self->checker == NULL)
3062         PyErr_Clear();
3063     return 0;
3064 }
3065 
3066 static PyObject *
3067 PyCFuncPtr_get_restype(PyCFuncPtrObject *self)
3068 {
3069     StgDictObject *dict;
3070     if (self->restype) {
3071         Py_INCREF(self->restype);
3072         return self->restype;
3073     }
3074     dict = PyObject_stgdict((PyObject *)self);
3075     assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3076     if (dict->restype) {
3077         Py_INCREF(dict->restype);
3078         return dict->restype;
3079     } else {
3080         Py_INCREF(Py_None);
3081         return Py_None;
3082     }
3083 }
3084 
3085 static int
3086 PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob)
3087 {
3088     PyObject *converters;
3089 
3090     if (ob == NULL || ob == Py_None) {
3091         Py_XDECREF(self->converters);
3092         self->converters = NULL;
3093         Py_XDECREF(self->argtypes);
3094         self->argtypes = NULL;
3095     } else {
3096         converters = converters_from_argtypes(ob);
3097         if (!converters)
3098             return -1;
3099         Py_XDECREF(self->converters);
3100         self->converters = converters;
3101         Py_XDECREF(self->argtypes);
3102         Py_INCREF(ob);
3103         self->argtypes = ob;
3104     }
3105     return 0;
3106 }
3107 
3108 static PyObject *
3109 PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self)
3110 {
3111     StgDictObject *dict;
3112     if (self->argtypes) {
3113         Py_INCREF(self->argtypes);
3114         return self->argtypes;
3115     }
3116     dict = PyObject_stgdict((PyObject *)self);
3117     assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3118     if (dict->argtypes) {
3119         Py_INCREF(dict->argtypes);
3120         return dict->argtypes;
3121     } else {
3122         Py_INCREF(Py_None);
3123         return Py_None;
3124     }
3125 }
3126 
3127 static PyGetSetDef PyCFuncPtr_getsets[] = {
3128     { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
3129       "a function to check for errors", NULL },
3130     { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
3131       "specify the result type", NULL },
3132     { "argtypes", (getter)PyCFuncPtr_get_argtypes,
3133       (setter)PyCFuncPtr_set_argtypes,
3134       "specify the argument types", NULL },
3135     { NULL, NULL }
3136 };
3137 
3138 #ifdef MS_WIN32
3139 static PPROC FindAddress(void *handle, char *name, PyObject *type)
3140 {
3141 #ifdef MS_WIN64
3142     /* win64 has no stdcall calling conv, so it should
3143        also not have the name mangling of it.
3144     */
3145     return (PPROC)GetProcAddress(handle, name);
3146 #else
3147     PPROC address;
3148     char *mangled_name;
3149     int i;
3150     StgDictObject *dict;
3151 
3152     address = (PPROC)GetProcAddress(handle, name);
3153     if (address)
3154         return address;
3155     if (((size_t)name & ~0xFFFF) == 0) {
3156         return NULL;
3157     }
3158 
3159     dict = PyType_stgdict((PyObject *)type);
3160     /* It should not happen that dict is NULL, but better be safe */
3161     if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
3162         return address;
3163 
3164     /* for stdcall, try mangled names:
3165        funcname -> _funcname@<n>
3166        where n is 0, 4, 8, 12, ..., 128
3167      */
3168     mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
3169     if (!mangled_name)
3170         return NULL;
3171     for (i = 0; i < 32; ++i) {
3172         sprintf(mangled_name, "_%s@%d", name, i*4);
3173         address = (PPROC)GetProcAddress(handle, mangled_name);
3174         if (address)
3175             return address;
3176     }
3177     return NULL;
3178 #endif
3179 }
3180 #endif
3181 
3182 /* Return 1 if usable, 0 else and exception set. */
3183 static int
3184 _check_outarg_type(PyObject *arg, Py_ssize_t index)
3185 {
3186     StgDictObject *dict;
3187 
3188     if (PyCPointerTypeObject_Check(arg))
3189         return 1;
3190 
3191     if (PyCArrayTypeObject_Check(arg))
3192         return 1;
3193 
3194     dict = PyType_stgdict(arg);
3195     if (dict
3196         /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
3197         && PyString_Check(dict->proto)
3198 /* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
3199         && (strchr("PzZ", PyString_AS_STRING(dict->proto)[0]))) {
3200         return 1;
3201     }
3202 
3203     PyErr_Format(PyExc_TypeError,
3204                  "'out' parameter %d must be a pointer type, not %s",
3205                  Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
3206                  PyType_Check(arg) ?
3207                  ((PyTypeObject *)arg)->tp_name :
3208              Py_TYPE(arg)->tp_name);
3209     return 0;
3210 }
3211 
3212 /* Returns 1 on success, 0 on error */
3213 static int
3214 _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
3215 {
3216     Py_ssize_t i, len;
3217     StgDictObject *dict;
3218     PyObject *argtypes;
3219 
3220     dict = PyType_stgdict((PyObject *)type);
3221     assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */
3222     argtypes = dict->argtypes;
3223 
3224     if (paramflags == NULL || dict->argtypes == NULL)
3225         return 1;
3226 
3227     if (!PyTuple_Check(paramflags)) {
3228         PyErr_SetString(PyExc_TypeError,
3229                         "paramflags must be a tuple or None");
3230         return 0;
3231     }
3232 
3233     len = PyTuple_GET_SIZE(paramflags);
3234     if (len != PyTuple_GET_SIZE(dict->argtypes)) {
3235         PyErr_SetString(PyExc_ValueError,
3236                         "paramflags must have the same length as argtypes");
3237         return 0;
3238     }
3239 
3240     for (i = 0; i < len; ++i) {
3241         PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3242         int flag;
3243         char *name;
3244         PyObject *defval;
3245         PyObject *typ;
3246         if (!PyArg_ParseTuple(item, "i|zO", &flag, &name, &defval)) {
3247             PyErr_SetString(PyExc_TypeError,
3248                    "paramflags must be a sequence of (int [,string [,value]]) tuples");
3249             return 0;
3250         }
3251         typ = PyTuple_GET_ITEM(argtypes, i);
3252         switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3253         case 0:
3254         case PARAMFLAG_FIN:
3255         case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3256         case PARAMFLAG_FIN | PARAMFLAG_FOUT:
3257             break;
3258         case PARAMFLAG_FOUT:
3259             if (!_check_outarg_type(typ, i+1))
3260                 return 0;
3261             break;
3262         default:
3263             PyErr_Format(PyExc_TypeError,
3264                          "paramflag value %d not supported",
3265                          flag);
3266             return 0;
3267         }
3268     }
3269     return 1;
3270 }
3271 
3272 static int
3273 _get_name(PyObject *obj, char **pname)
3274 {
3275 #ifdef MS_WIN32
3276     if (PyInt_Check(obj) || PyLong_Check(obj)) {
3277         /* We have to use MAKEINTRESOURCEA for Windows CE.
3278            Works on Windows as well, of course.
3279         */
3280         *pname = MAKEINTRESOURCEA(PyInt_AsUnsignedLongMask(obj) & 0xFFFF);
3281         return 1;
3282     }
3283 #endif
3284     if (PyString_Check(obj) || PyUnicode_Check(obj)) {
3285         *pname = PyString_AsString(obj);
3286         return *pname ? 1 : 0;
3287     }
3288     PyErr_SetString(PyExc_TypeError,
3289                     "function name must be string or integer");
3290     return 0;
3291 }
3292 
3293 
3294 static PyObject *
3295 PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
3296 {
3297     char *name;
3298     int (* address)(void);
3299     PyObject *dll;
3300     PyObject *obj;
3301     PyCFuncPtrObject *self;
3302     void *handle;
3303     PyObject *paramflags = NULL;
3304 
3305     if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
3306         return NULL;
3307     if (paramflags == Py_None)
3308         paramflags = NULL;
3309 
3310     obj = PyObject_GetAttrString(dll, "_handle");
3311     if (!obj)
3312         return NULL;
3313     if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
3314         PyErr_SetString(PyExc_TypeError,
3315                         "the _handle attribute of the second argument must be an integer");
3316         Py_DECREF(obj);
3317         return NULL;
3318     }
3319     handle = (void *)PyLong_AsVoidPtr(obj);
3320     Py_DECREF(obj);
3321     if (PyErr_Occurred()) {
3322         PyErr_SetString(PyExc_ValueError,
3323                         "could not convert the _handle attribute to a pointer");
3324         return NULL;
3325     }
3326 
3327 #ifdef MS_WIN32
3328     address = FindAddress(handle, name, (PyObject *)type);
3329     if (!address) {
3330         if (!IS_INTRESOURCE(name))
3331             PyErr_Format(PyExc_AttributeError,
3332                          "function '%s' not found",
3333                          name);
3334         else
3335             PyErr_Format(PyExc_AttributeError,
3336                          "function ordinal %d not found",
3337                          (WORD)(size_t)name);
3338         return NULL;
3339     }
3340 #else
3341     address = (PPROC)ctypes_dlsym(handle, name);
3342     if (!address) {
3343 #ifdef __CYGWIN__
3344 /* dlerror() isn't very helpful on cygwin */
3345         PyErr_Format(PyExc_AttributeError,
3346                      "function '%s' not found (%s) ",
3347                      name);
3348 #else
3349         PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
3350 #endif
3351         return NULL;
3352     }
3353 #endif
3354     if (!_validate_paramflags(type, paramflags))
3355         return NULL;
3356 
3357     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3358     if (!self)
3359         return NULL;
3360 
3361     Py_XINCREF(paramflags);
3362     self->paramflags = paramflags;
3363 
3364     *(void **)self->b_ptr = address;
3365 
3366     Py_INCREF((PyObject *)dll); /* for KeepRef */
3367     if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
3368         Py_DECREF((PyObject *)self);
3369         return NULL;
3370     }
3371 
3372     Py_INCREF(self);
3373     self->callable = (PyObject *)self;
3374     return (PyObject *)self;
3375 }
3376 
3377 #ifdef MS_WIN32
3378 static PyObject *
3379 PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
3380 {
3381     PyCFuncPtrObject *self;
3382     int index;
3383     char *name = NULL;
3384     PyObject *paramflags = NULL;
3385     GUID *iid = NULL;
3386     Py_ssize_t iid_len = 0;
3387 
3388     if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
3389         return NULL;
3390     if (paramflags == Py_None)
3391         paramflags = NULL;
3392 
3393     if (!_validate_paramflags(type, paramflags))
3394         return NULL;
3395 
3396     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3397     self->index = index + 0x1000;
3398     Py_XINCREF(paramflags);
3399     self->paramflags = paramflags;
3400     if (iid_len == sizeof(GUID))
3401         self->iid = iid;
3402     return (PyObject *)self;
3403 }
3404 #endif
3405 
3406 /*
3407   PyCFuncPtr_new accepts different argument lists in addition to the standard
3408   _basespec_ keyword arg:
3409 
3410   one argument form
3411   "i" - function address
3412   "O" - must be a callable, creates a C callable function
3413 
3414   two or more argument forms (the third argument is a paramflags tuple)
3415   "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
3416   "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
3417   "is|..." - vtable index, method name, creates callable calling COM vtbl
3418 */
3419 static PyObject *
3420 PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3421 {
3422     PyCFuncPtrObject *self;
3423     PyObject *callable;
3424     StgDictObject *dict;
3425     CThunkObject *thunk;
3426 
3427     if (PyTuple_GET_SIZE(args) == 0)
3428         return GenericPyCData_new(type, args, kwds);
3429 
3430     if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
3431         return PyCFuncPtr_FromDll(type, args, kwds);
3432 
3433 #ifdef MS_WIN32
3434     if (2 <= PyTuple_GET_SIZE(args) && PyInt_Check(PyTuple_GET_ITEM(args, 0)))
3435         return PyCFuncPtr_FromVtblIndex(type, args, kwds);
3436 #endif
3437 
3438     if (1 == PyTuple_GET_SIZE(args)
3439         && (PyInt_Check(PyTuple_GET_ITEM(args, 0))
3440         || PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
3441         CDataObject *ob;
3442         void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
3443         if (ptr == NULL && PyErr_Occurred())
3444             return NULL;
3445         ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
3446         if (ob == NULL)
3447             return NULL;
3448         *(void **)ob->b_ptr = ptr;
3449         return (PyObject *)ob;
3450     }
3451 
3452     if (!PyArg_ParseTuple(args, "O", &callable))
3453         return NULL;
3454     if (!PyCallable_Check(callable)) {
3455         PyErr_SetString(PyExc_TypeError,
3456                         "argument must be callable or integer function address");
3457         return NULL;
3458     }
3459 
3460     /* XXX XXX This would allow to pass additional options.  For COM
3461        method *implementations*, we would probably want different
3462        behaviour than in 'normal' callback functions: return a HRESULT if
3463        an exception occurs in the callback, and print the traceback not
3464        only on the console, but also to OutputDebugString() or something
3465        like that.
3466     */
3467 /*
3468     if (kwds && PyDict_GetItemString(kwds, "options")) {
3469         ...
3470     }
3471 */
3472 
3473     dict = PyType_stgdict((PyObject *)type);
3474     /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
3475     if (!dict || !dict->argtypes) {
3476         PyErr_SetString(PyExc_TypeError,
3477                "cannot construct instance of this class:"
3478             " no argtypes");
3479         return NULL;
3480     }
3481 
3482     thunk = _ctypes_alloc_callback(callable,
3483                                   dict->argtypes,
3484                                   dict->restype,
3485                                   dict->flags);
3486     if (!thunk)
3487         return NULL;
3488 
3489     self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
3490     if (self == NULL) {
3491         Py_DECREF(thunk);
3492         return NULL;
3493     }
3494 
3495     Py_INCREF(callable);
3496     self->callable = callable;
3497 
3498     self->thunk = thunk;
3499     *(void **)self->b_ptr = (void *)thunk->pcl_exec;
3500 
3501     Py_INCREF((PyObject *)thunk); /* for KeepRef */
3502     if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3503         Py_DECREF((PyObject *)self);
3504         return NULL;
3505     }
3506     return (PyObject *)self;
3507 }
3508 
3509 
3510 /*
3511   _byref consumes a refcount to its argument
3512 */
3513 static PyObject *
3514 _byref(PyObject *obj)
3515 {
3516     PyCArgObject *parg;
3517     if (!CDataObject_Check(obj)) {
3518         PyErr_SetString(PyExc_TypeError,
3519                         "expected CData instance");
3520         return NULL;
3521     }
3522 
3523     parg = PyCArgObject_new();
3524     if (parg == NULL) {
3525         Py_DECREF(obj);
3526         return NULL;
3527     }
3528 
3529     parg->tag = 'P';
3530     parg->pffi_type = &ffi_type_pointer;
3531     parg->obj = obj;
3532     parg->value.p = ((CDataObject *)obj)->b_ptr;
3533     return (PyObject *)parg;
3534 }
3535 
3536 static PyObject *
3537 _get_arg(int *pindex, char *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
3538 {
3539     PyObject *v;
3540 
3541     if (*pindex < PyTuple_GET_SIZE(inargs)) {
3542         v = PyTuple_GET_ITEM(inargs, *pindex);
3543         ++*pindex;
3544         Py_INCREF(v);
3545         return v;
3546     }
3547     if (kwds && (v = PyDict_GetItemString(kwds, name))) {
3548         ++*pindex;
3549         Py_INCREF(v);
3550         return v;
3551     }
3552     if (defval) {
3553         Py_INCREF(defval);
3554         return defval;
3555     }
3556     /* we can't currently emit a better error message */
3557     if (name)
3558         PyErr_Format(PyExc_TypeError,
3559                      "required argument '%s' missing", name);
3560     else
3561         PyErr_Format(PyExc_TypeError,
3562                      "not enough arguments");
3563     return NULL;
3564 }
3565 
3566 /*
3567  This function implements higher level functionality plus the ability to call
3568  functions with keyword arguments by looking at parameter flags.  parameter
3569  flags is a tuple of 1, 2 or 3-tuples.  The first entry in each is an integer
3570  specifying the direction of the data transfer for this parameter - 'in',
3571  'out' or 'inout' (zero means the same as 'in').  The second entry is the
3572  parameter name, and the third is the default value if the parameter is
3573  missing in the function call.
3574 
3575  This function builds and returns a new tuple 'callargs' which contains the
3576  parameters to use in the call.  Items on this tuple are copied from the
3577  'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
3578  'argtypes' tuple for 'out' parameters.  It also calculates numretvals which
3579  is the number of return values for the function, outmask/inoutmask are
3580  bitmasks containing indexes into the callargs tuple specifying which
3581  parameters have to be returned.  _build_result builds the return value of the
3582  function.
3583 */
3584 static PyObject *
3585 _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
3586                 PyObject *inargs, PyObject *kwds,
3587                 int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
3588 {
3589     PyObject *paramflags = self->paramflags;
3590     PyObject *callargs;
3591     StgDictObject *dict;
3592     Py_ssize_t i, len;
3593     int inargs_index = 0;
3594     /* It's a little bit difficult to determine how many arguments the
3595     function call requires/accepts.  For simplicity, we count the consumed
3596     args and compare this to the number of supplied args. */
3597     Py_ssize_t actual_args;
3598 
3599     *poutmask = 0;
3600     *pinoutmask = 0;
3601     *pnumretvals = 0;
3602 
3603     /* Trivial cases, where we either return inargs itself, or a slice of it. */
3604     if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
3605 #ifdef MS_WIN32
3606         if (self->index)
3607             return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
3608 #endif
3609         Py_INCREF(inargs);
3610         return inargs;
3611     }
3612 
3613     len = PyTuple_GET_SIZE(argtypes);
3614     callargs = PyTuple_New(len); /* the argument tuple we build */
3615     if (callargs == NULL)
3616         return NULL;
3617 
3618 #ifdef MS_WIN32
3619     /* For a COM method, skip the first arg */
3620     if (self->index) {
3621         inargs_index = 1;
3622     }
3623 #endif
3624     for (i = 0; i < len; ++i) {
3625         PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3626         PyObject *ob;
3627         int flag;
3628         char *name = NULL;
3629         PyObject *defval = NULL;
3630 
3631         /* This way seems to be ~2 us faster than the PyArg_ParseTuple
3632            calls below. */
3633         /* We HAVE already checked that the tuple can be parsed with "i|zO", so... */
3634         Py_ssize_t tsize = PyTuple_GET_SIZE(item);
3635         flag = PyInt_AS_LONG(PyTuple_GET_ITEM(item, 0));
3636         name = tsize > 1 ? PyString_AS_STRING(PyTuple_GET_ITEM(item, 1)) : NULL;
3637         defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
3638 
3639         switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3640         case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3641             /* ['in', 'lcid'] parameter.  Always taken from defval,
3642              if given, else the integer 0. */
3643             if (defval == NULL) {
3644                 defval = PyInt_FromLong(0);
3645                 if (defval == NULL)
3646                     goto error;
3647             } else
3648                 Py_INCREF(defval);
3649             PyTuple_SET_ITEM(callargs, i, defval);
3650             break;
3651         case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
3652             *pinoutmask |= (1 << i); /* mark as inout arg */
3653             (*pnumretvals)++;
3654             /* fall through to PARAMFLAG_FIN... */
3655         case 0:
3656         case PARAMFLAG_FIN:
3657             /* 'in' parameter.  Copy it from inargs. */
3658             ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
3659             if (ob == NULL)
3660                 goto error;
3661             PyTuple_SET_ITEM(callargs, i, ob);
3662             break;
3663         case PARAMFLAG_FOUT:
3664             /* XXX Refactor this code into a separate function. */
3665             /* 'out' parameter.
3666                argtypes[i] must be a POINTER to a c type.
3667 
3668                Cannot by supplied in inargs, but a defval will be used
3669                if available.  XXX Should we support getting it from kwds?
3670             */
3671             if (defval) {
3672                 /* XXX Using mutable objects as defval will
3673                    make the function non-threadsafe, unless we
3674                    copy the object in each invocation */
3675                 Py_INCREF(defval);
3676                 PyTuple_SET_ITEM(callargs, i, defval);
3677                 *poutmask |= (1 << i); /* mark as out arg */
3678                 (*pnumretvals)++;
3679                 break;
3680             }
3681             ob = PyTuple_GET_ITEM(argtypes, i);
3682             dict = PyType_stgdict(ob);
3683             if (dict == NULL) {
3684                 /* Cannot happen: _validate_paramflags()
3685                   would not accept such an object */
3686                 PyErr_Format(PyExc_RuntimeError,
3687                              "NULL stgdict unexpected");
3688                 goto error;
3689             }
3690             if (PyString_Check(dict->proto)) {
3691                 PyErr_Format(
3692                     PyExc_TypeError,
3693                     "%s 'out' parameter must be passed as default value",
3694                     ((PyTypeObject *)ob)->tp_name);
3695                 goto error;
3696             }
3697             if (PyCArrayTypeObject_Check(ob))
3698                 ob = PyObject_CallObject(ob, NULL);
3699             else
3700                 /* Create an instance of the pointed-to type */
3701                 ob = PyObject_CallObject(dict->proto, NULL);
3702             /*
3703                XXX Is the following correct any longer?
3704                We must not pass a byref() to the array then but
3705                the array instance itself. Then, we cannot retrive
3706                the result from the PyCArgObject.
3707             */
3708             if (ob == NULL)
3709                 goto error;
3710             /* The .from_param call that will ocurr later will pass this
3711                as a byref parameter. */
3712             PyTuple_SET_ITEM(callargs, i, ob);
3713             *poutmask |= (1 << i); /* mark as out arg */
3714             (*pnumretvals)++;
3715             break;
3716         default:
3717             PyErr_Format(PyExc_ValueError,
3718                          "paramflag %d not yet implemented", flag);
3719             goto error;
3720             break;
3721         }
3722     }
3723 
3724     /* We have counted the arguments we have consumed in 'inargs_index'.  This
3725        must be the same as len(inargs) + len(kwds), otherwise we have
3726        either too much or not enough arguments. */
3727 
3728     actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
3729     if (actual_args != inargs_index) {
3730         /* When we have default values or named parameters, this error
3731            message is misleading.  See unittests/test_paramflags.py
3732          */
3733         PyErr_Format(PyExc_TypeError,
3734 #if (PY_VERSION_HEX < 0x02050000)
3735                      "call takes exactly %d arguments (%d given)",
3736 #else
3737                      "call takes exactly %d arguments (%zd given)",
3738 #endif
3739                      inargs_index, actual_args);
3740         goto error;
3741     }
3742 
3743     /* outmask is a bitmask containing indexes into callargs.  Items at
3744        these indexes contain values to return.
3745      */
3746     return callargs;
3747   error:
3748     Py_DECREF(callargs);
3749     return NULL;
3750 }
3751 
3752 /* See also:
3753    http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
3754 */
3755 /*
3756   Build return value of a function.
3757 
3758   Consumes the refcount on result and callargs.
3759 */
3760 static PyObject *
3761 _build_result(PyObject *result, PyObject *callargs,
3762               int outmask, int inoutmask, unsigned int numretvals)
3763 {
3764     unsigned int i, index;
3765     int bit;
3766     PyObject *tup = NULL;
3767 
3768     if (callargs == NULL)
3769         return result;
3770     if (result == NULL || numretvals == 0) {
3771         Py_DECREF(callargs);
3772         return result;
3773     }
3774     Py_DECREF(result);
3775 
3776     /* tup will not be allocated if numretvals == 1 */
3777     /* allocate tuple to hold the result */
3778     if (numretvals > 1) {
3779         tup = PyTuple_New(numretvals);
3780         if (tup == NULL) {
3781             Py_DECREF(callargs);
3782             return NULL;
3783         }
3784     }
3785 
3786     index = 0;
3787     for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
3788         PyObject *v;
3789         if (bit & inoutmask) {
3790             v = PyTuple_GET_ITEM(callargs, i);
3791             Py_INCREF(v);
3792             if (numretvals == 1) {
3793                 Py_DECREF(callargs);
3794                 return v;
3795             }
3796             PyTuple_SET_ITEM(tup, index, v);
3797             index++;
3798         } else if (bit & outmask) {
3799             v = PyTuple_GET_ITEM(callargs, i);
3800             v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
3801             if (v == NULL || numretvals == 1) {
3802                 Py_DECREF(callargs);
3803                 return v;
3804             }
3805             PyTuple_SET_ITEM(tup, index, v);
3806             index++;
3807         }
3808         if (index == numretvals)
3809             break;
3810     }
3811 
3812     Py_DECREF(callargs);
3813     return tup;
3814 }
3815 
3816 static PyObject *
3817 PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
3818 {
3819     PyObject *restype;
3820     PyObject *converters;
3821     PyObject *checker;
3822     PyObject *argtypes;
3823     StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3824     PyObject *result;
3825     PyObject *callargs;
3826     PyObject *errcheck;
3827 #ifdef MS_WIN32
3828     IUnknown *piunk = NULL;
3829 #endif
3830     void *pProc = NULL;
3831 
3832     int inoutmask;
3833     int outmask;
3834     unsigned int numretvals;
3835 
3836     assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
3837     restype = self->restype ? self->restype : dict->restype;
3838     converters = self->converters ? self->converters : dict->converters;
3839     checker = self->checker ? self->checker : dict->checker;
3840     argtypes = self->argtypes ? self->argtypes : dict->argtypes;
3841 /* later, we probably want to have an errcheck field in stgdict */
3842     errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
3843 
3844 
3845     pProc = *(void **)self->b_ptr;
3846 #ifdef MS_WIN32
3847     if (self->index) {
3848         /* It's a COM method */
3849         CDataObject *this;
3850         this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
3851         if (!this) {
3852             PyErr_SetString(PyExc_ValueError,
3853                             "native com method call without 'this' parameter");
3854             return NULL;
3855         }
3856         if (!CDataObject_Check(this)) {
3857             PyErr_SetString(PyExc_TypeError,
3858                             "Expected a COM this pointer as first argument");
3859             return NULL;
3860         }
3861         /* there should be more checks? No, in Python */
3862         /* First arg is an pointer to an interface instance */
3863         if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
3864             PyErr_SetString(PyExc_ValueError,
3865                             "NULL COM pointer access");
3866             return NULL;
3867         }
3868         piunk = *(IUnknown **)this->b_ptr;
3869         if (NULL == piunk->lpVtbl) {
3870             PyErr_SetString(PyExc_ValueError,
3871                             "COM method call without VTable");
3872             return NULL;
3873         }
3874         pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
3875     }
3876 #endif
3877     callargs = _build_callargs(self, argtypes,
3878                                inargs, kwds,
3879                                &outmask, &inoutmask, &numretvals);
3880     if (callargs == NULL)
3881         return NULL;
3882 
3883     if (converters) {
3884         int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
3885                                         Py_ssize_t, int);
3886         int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
3887                                       Py_ssize_t, int);
3888 
3889         if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
3890             /* For cdecl functions, we allow more actual arguments
3891                than the length of the argtypes tuple.
3892             */
3893             if (required > actual) {
3894                 Py_DECREF(callargs);
3895                 PyErr_Format(PyExc_TypeError,
3896               "this function takes at least %d argument%s (%d given)",
3897                                  required,
3898                                  required == 1 ? "" : "s",
3899                                  actual);
3900                 return NULL;
3901             }
3902         } else if (required != actual) {
3903             Py_DECREF(callargs);
3904             PyErr_Format(PyExc_TypeError,
3905                  "this function takes %d argument%s (%d given)",
3906                      required,
3907                      required == 1 ? "" : "s",
3908                      actual);
3909             return NULL;
3910         }
3911     }
3912 
3913     result = _ctypes_callproc(pProc,
3914                        callargs,
3915 #ifdef MS_WIN32
3916                        piunk,
3917                        self->iid,
3918 #endif
3919                        dict->flags,
3920                        converters,
3921                        restype,
3922                        checker);
3923 /* The 'errcheck' protocol */
3924     if (result != NULL && errcheck) {
3925         PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
3926                                                    result,
3927                                                    self,
3928                                                    callargs,
3929                                                    NULL);
3930         /* If the errcheck funtion failed, return NULL.
3931            If the errcheck function returned callargs unchanged,
3932            continue normal processing.
3933            If the errcheck function returned something else,
3934            use that as result.
3935         */
3936         if (v == NULL || v != callargs) {
3937             Py_DECREF(result);
3938             Py_DECREF(callargs);
3939             return v;
3940         }
3941         Py_DECREF(v);
3942     }
3943 
3944     return _build_result(result, callargs,
3945                          outmask, inoutmask, numretvals);
3946 }
3947 
3948 static int
3949 PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
3950 {
3951     Py_VISIT(self->callable);
3952     Py_VISIT(self->restype);
3953     Py_VISIT(self->checker);
3954     Py_VISIT(self->errcheck);
3955     Py_VISIT(self->argtypes);
3956     Py_VISIT(self->converters);
3957     Py_VISIT(self->paramflags);
3958     Py_VISIT(self->thunk);
3959     return PyCData_traverse((CDataObject *)self, visit, arg);
3960 }
3961 
3962 static int
3963 PyCFuncPtr_clear(PyCFuncPtrObject *self)
3964 {
3965     Py_CLEAR(self->callable);
3966     Py_CLEAR(self->restype);
3967     Py_CLEAR(self->checker);
3968     Py_CLEAR(self->errcheck);
3969     Py_CLEAR(self->argtypes);
3970     Py_CLEAR(self->converters);
3971     Py_CLEAR(self->paramflags);
3972     Py_CLEAR(self->thunk);
3973     return PyCData_clear((CDataObject *)self);
3974 }
3975 
3976 static void
3977 PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
3978 {
3979     PyCFuncPtr_clear(self);
3980     Py_TYPE(self)->tp_free((PyObject *)self);
3981 }
3982 
3983 static PyObject *
3984 PyCFuncPtr_repr(PyCFuncPtrObject *self)
3985 {
3986 #ifdef MS_WIN32
3987     if (self->index)
3988         return PyString_FromFormat("<COM method offset %d: %s at %p>",
3989                                    self->index - 0x1000,
3990                                    Py_TYPE(self)->tp_name,
3991                                    self);
3992 #endif
3993     return PyString_FromFormat("<%s object at %p>",
3994                                Py_TYPE(self)->tp_name,
3995                                self);
3996 }
3997 
3998 static int
3999 PyCFuncPtr_nonzero(PyCFuncPtrObject *self)
4000 {
4001     return ((*(void **)self->b_ptr != NULL)
4002 #ifdef MS_WIN32
4003         || (self->index != 0)
4004 #endif
4005         );
4006 }
4007 
4008 static PyNumberMethods PyCFuncPtr_as_number = {
4009     0, /* nb_add */
4010     0, /* nb_subtract */
4011     0, /* nb_multiply */
4012     0, /* nb_divide */
4013     0, /* nb_remainder */
4014     0, /* nb_divmod */
4015     0, /* nb_power */
4016     0, /* nb_negative */
4017     0, /* nb_positive */
4018     0, /* nb_absolute */
4019     (inquiry)PyCFuncPtr_nonzero, /* nb_nonzero */
4020 };
4021 
4022 PyTypeObject PyCFuncPtr_Type = {
4023     PyVarObject_HEAD_INIT(NULL, 0)
4024     "_ctypes.PyCFuncPtr",
4025     sizeof(PyCFuncPtrObject),                           /* tp_basicsize */
4026     0,                                          /* tp_itemsize */
4027     (destructor)PyCFuncPtr_dealloc,             /* tp_dealloc */
4028     0,                                          /* tp_print */
4029     0,                                          /* tp_getattr */
4030     0,                                          /* tp_setattr */
4031     0,                                          /* tp_compare */
4032     (reprfunc)PyCFuncPtr_repr,                  /* tp_repr */
4033     &PyCFuncPtr_as_number,                      /* tp_as_number */
4034     0,                                          /* tp_as_sequence */
4035     0,                                          /* tp_as_mapping */
4036     0,                                          /* tp_hash */
4037     (ternaryfunc)PyCFuncPtr_call,               /* tp_call */
4038     0,                                          /* tp_str */
4039     0,                                          /* tp_getattro */
4040     0,                                          /* tp_setattro */
4041     &PyCData_as_buffer,                         /* tp_as_buffer */
4042     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4043     "Function Pointer",                         /* tp_doc */
4044     (traverseproc)PyCFuncPtr_traverse,          /* tp_traverse */
4045     (inquiry)PyCFuncPtr_clear,                  /* tp_clear */
4046     0,                                          /* tp_richcompare */
4047     0,                                          /* tp_weaklistoffset */
4048     0,                                          /* tp_iter */
4049     0,                                          /* tp_iternext */
4050     0,                                          /* tp_methods */
4051     0,                                          /* tp_members */
4052     PyCFuncPtr_getsets,                         /* tp_getset */
4053     0,                                          /* tp_base */
4054     0,                                          /* tp_dict */
4055     0,                                          /* tp_descr_get */
4056     0,                                          /* tp_descr_set */
4057     0,                                          /* tp_dictoffset */
4058     0,                                          /* tp_init */
4059     0,                                          /* tp_alloc */
4060     PyCFuncPtr_new,                             /* tp_new */
4061     0,                                          /* tp_free */
4062 };
4063 
4064 /*****************************************************************/
4065 /*
4066   Struct_Type
4067 */
4068 /*
4069   This function is called to initialize a Structure or Union with positional
4070   arguments. It calls itself recursively for all Structure or Union base
4071   classes, then retrieves the _fields_ member to associate the argument
4072   position with the correct field name.
4073 
4074   Returns -1 on error, or the index of next argument on success.
4075  */
4076 static int
4077 _init_pos_args(PyObject *self, PyTypeObject *type,
4078                PyObject *args, PyObject *kwds,
4079                int index)
4080 {
4081     StgDictObject *dict;
4082     PyObject *fields;
4083     int i;
4084 
4085     if (PyType_stgdict((PyObject *)type->tp_base)) {
4086         index = _init_pos_args(self, type->tp_base,
4087                                args, kwds,
4088                                index);
4089         if (index == -1)
4090             return -1;
4091     }
4092 
4093     dict = PyType_stgdict((PyObject *)type);
4094     fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
4095     if (fields == NULL)
4096         return index;
4097 
4098     for (i = 0;
4099          i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
4100          ++i) {
4101         PyObject *pair = PySequence_GetItem(fields, i);
4102         PyObject *name, *val;
4103         int res;
4104         if (!pair)
4105             return -1;
4106         name = PySequence_GetItem(pair, 0);
4107         if (!name) {
4108             Py_DECREF(pair);
4109             return -1;
4110         }
4111         val = PyTuple_GET_ITEM(args, i + index);
4112         if (kwds && PyDict_GetItem(kwds, name)) {
4113             char *field = PyString_AsString(name);
4114             if (field == NULL) {
4115                 PyErr_Clear();
4116                 field = "???";
4117             }
4118             PyErr_Format(PyExc_TypeError,
4119                          "duplicate values for field '%s'",
4120                          field);
4121             Py_DECREF(pair);
4122             Py_DECREF(name);
4123             return -1;
4124         }
4125 
4126         res = PyObject_SetAttr(self, name, val);
4127         Py_DECREF(pair);
4128         Py_DECREF(name);
4129         if (res == -1)
4130             return -1;
4131     }
4132     return index + dict->length;
4133 }
4134 
4135 static int
4136 Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
4137 {
4138 /* Optimization possible: Store the attribute names _fields_[x][0]
4139  * in C accessible fields somewhere ?
4140  */
4141     if (!PyTuple_Check(args)) {
4142         PyErr_SetString(PyExc_TypeError,
4143                         "args not a tuple?");
4144         return -1;
4145     }
4146     if (PyTuple_GET_SIZE(args)) {
4147         int res = _init_pos_args(self, Py_TYPE(self),
4148                                  args, kwds, 0);
4149         if (res == -1)
4150             return -1;
4151         if (res < PyTuple_GET_SIZE(args)) {
4152             PyErr_SetString(PyExc_TypeError,
4153                             "too many initializers");
4154             return -1;
4155         }
4156     }
4157 
4158     if (kwds) {
4159         PyObject *key, *value;
4160         Py_ssize_t pos = 0;
4161         while(PyDict_Next(kwds, &pos, &key, &value)) {
4162             if (-1 == PyObject_SetAttr(self, key, value))
4163                 return -1;
4164         }
4165     }
4166     return 0;
4167 }
4168 
4169 static PyTypeObject Struct_Type = {
4170     PyVarObject_HEAD_INIT(NULL, 0)
4171     "_ctypes.Structure",
4172     sizeof(CDataObject),                        /* tp_basicsize */
4173     0,                                          /* tp_itemsize */
4174     0,                                          /* tp_dealloc */
4175     0,                                          /* tp_print */
4176     0,                                          /* tp_getattr */
4177     0,                                          /* tp_setattr */
4178     0,                                          /* tp_compare */
4179     0,                                          /* tp_repr */
4180     0,                                          /* tp_as_number */
4181     0,                                          /* tp_as_sequence */
4182     0,                                          /* tp_as_mapping */
4183     0,                                          /* tp_hash */
4184     0,                                          /* tp_call */
4185     0,                                          /* tp_str */
4186     0,                                          /* tp_getattro */
4187     0,                                          /* tp_setattro */
4188     &PyCData_as_buffer,                         /* tp_as_buffer */
4189     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4190     "Structure base class",                     /* tp_doc */
4191     (traverseproc)PyCData_traverse,             /* tp_traverse */
4192     (inquiry)PyCData_clear,                     /* tp_clear */
4193     0,                                          /* tp_richcompare */
4194     0,                                          /* tp_weaklistoffset */
4195     0,                                          /* tp_iter */
4196     0,                                          /* tp_iternext */
4197     0,                                          /* tp_methods */
4198     0,                                          /* tp_members */
4199     0,                                          /* tp_getset */
4200     0,                                          /* tp_base */
4201     0,                                          /* tp_dict */
4202     0,                                          /* tp_descr_get */
4203     0,                                          /* tp_descr_set */
4204     0,                                          /* tp_dictoffset */
4205     Struct_init,                                /* tp_init */
4206     0,                                          /* tp_alloc */
4207     GenericPyCData_new,                         /* tp_new */
4208     0,                                          /* tp_free */
4209 };
4210 
4211 static PyTypeObject Union_Type = {
4212     PyVarObject_HEAD_INIT(NULL, 0)
4213     "_ctypes.Union",
4214     sizeof(CDataObject),                        /* tp_basicsize */
4215     0,                                          /* tp_itemsize */
4216     0,                                          /* tp_dealloc */
4217     0,                                          /* tp_print */
4218     0,                                          /* tp_getattr */
4219     0,                                          /* tp_setattr */
4220     0,                                          /* tp_compare */
4221     0,                                          /* tp_repr */
4222     0,                                          /* tp_as_number */
4223     0,                                          /* tp_as_sequence */
4224     0,                                          /* tp_as_mapping */
4225     0,                                          /* tp_hash */
4226     0,                                          /* tp_call */
4227     0,                                          /* tp_str */
4228     0,                                          /* tp_getattro */
4229     0,                                          /* tp_setattro */
4230     &PyCData_as_buffer,                         /* tp_as_buffer */
4231     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4232     "Union base class",                         /* tp_doc */
4233     (traverseproc)PyCData_traverse,             /* tp_traverse */
4234     (inquiry)PyCData_clear,                     /* tp_clear */
4235     0,                                          /* tp_richcompare */
4236     0,                                          /* tp_weaklistoffset */
4237     0,                                          /* tp_iter */
4238     0,                                          /* tp_iternext */
4239     0,                                          /* tp_methods */
4240     0,                                          /* tp_members */
4241     0,                                          /* tp_getset */
4242     0,                                          /* tp_base */
4243     0,                                          /* tp_dict */
4244     0,                                          /* tp_descr_get */
4245     0,                                          /* tp_descr_set */
4246     0,                                          /* tp_dictoffset */
4247     Struct_init,                                /* tp_init */
4248     0,                                          /* tp_alloc */
4249     GenericPyCData_new,                         /* tp_new */
4250     0,                                          /* tp_free */
4251 };
4252 
4253 
4254 /******************************************************************/
4255 /*
4256   PyCArray_Type
4257 */
4258 static int
4259 Array_init(CDataObject *self, PyObject *args, PyObject *kw)
4260 {
4261     Py_ssize_t i;
4262     Py_ssize_t n;
4263 
4264     if (!PyTuple_Check(args)) {
4265         PyErr_SetString(PyExc_TypeError,
4266                         "args not a tuple?");
4267         return -1;
4268     }
4269     n = PyTuple_GET_SIZE(args);
4270     for (i = 0; i < n; ++i) {
4271         PyObject *v;
4272         v = PyTuple_GET_ITEM(args, i);
4273         if (-1 == PySequence_SetItem((PyObject *)self, i, v))
4274             return -1;
4275     }
4276     return 0;
4277 }
4278 
4279 static PyObject *
4280 Array_item(PyObject *_self, Py_ssize_t index)
4281 {
4282     CDataObject *self = (CDataObject *)_self;
4283     Py_ssize_t offset, size;
4284     StgDictObject *stgdict;
4285 
4286 
4287     if (index < 0 || index >= self->b_length) {
4288         PyErr_SetString(PyExc_IndexError,
4289                         "invalid index");
4290         return NULL;
4291     }
4292 
4293     stgdict = PyObject_stgdict((PyObject *)self);
4294     assert(stgdict); /* Cannot be NULL for array instances */
4295     /* Would it be clearer if we got the item size from
4296        stgdict->proto's stgdict?
4297     */
4298     size = stgdict->size / stgdict->length;
4299     offset = index * size;
4300 
4301     return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
4302                      index, size, self->b_ptr + offset);
4303 }
4304 
4305 static PyObject *
4306 Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
4307 {
4308     CDataObject *self = (CDataObject *)_self;
4309     StgDictObject *stgdict, *itemdict;
4310     PyObject *proto;
4311     PyListObject *np;
4312     Py_ssize_t i, len;
4313 
4314     if (ilow < 0)
4315         ilow = 0;
4316     else if (ilow > self->b_length)
4317         ilow = self->b_length;
4318     if (ihigh < ilow)
4319         ihigh = ilow;
4320     else if (ihigh > self->b_length)
4321         ihigh = self->b_length;
4322     len = ihigh - ilow;
4323 
4324     stgdict = PyObject_stgdict((PyObject *)self);
4325     assert(stgdict); /* Cannot be NULL for array object instances */
4326     proto = stgdict->proto;
4327     itemdict = PyType_stgdict(proto);
4328     assert(itemdict); /* proto is the item type of the array, a ctypes
4329                          type, so this cannot be NULL */
4330     if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4331         char *ptr = (char *)self->b_ptr;
4332         return PyString_FromStringAndSize(ptr + ilow, len);
4333 #ifdef CTYPES_UNICODE
4334     } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4335         wchar_t *ptr = (wchar_t *)self->b_ptr;
4336         return PyUnicode_FromWideChar(ptr + ilow, len);
4337 #endif
4338     }
4339 
4340     np = (PyListObject *) PyList_New(len);
4341     if (np == NULL)
4342         return NULL;
4343 
4344     for (i = 0; i < len; i++) {
4345         PyObject *v = Array_item(_self, i+ilow);
4346         PyList_SET_ITEM(np, i, v);
4347     }
4348     return (PyObject *)np;
4349 }
4350 
4351 static PyObject *
4352 Array_subscript(PyObject *_self, PyObject *item)
4353 {
4354     CDataObject *self = (CDataObject *)_self;
4355 
4356     if (PyIndex_Check(item)) {
4357         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4358 
4359         if (i == -1 && PyErr_Occurred())
4360             return NULL;
4361         if (i < 0)
4362             i += self->b_length;
4363         return Array_item(_self, i);
4364     }
4365     else if PySlice_Check(item) {
4366         StgDictObject *stgdict, *itemdict;
4367         PyObject *proto;
4368         PyObject *np;
4369         Py_ssize_t start, stop, step, slicelen, cur, i;
4370 
4371         if (PySlice_GetIndicesEx((PySliceObject *)item,
4372                                  self->b_length, &start, &stop,
4373                                  &step, &slicelen) < 0) {
4374             return NULL;
4375         }
4376 
4377         stgdict = PyObject_stgdict((PyObject *)self);
4378         assert(stgdict); /* Cannot be NULL for array object instances */
4379         proto = stgdict->proto;
4380         itemdict = PyType_stgdict(proto);
4381         assert(itemdict); /* proto is the item type of the array, a
4382                              ctypes type, so this cannot be NULL */
4383 
4384         if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4385             char *ptr = (char *)self->b_ptr;
4386             char *dest;
4387 
4388             if (slicelen <= 0)
4389                 return PyString_FromString("");
4390             if (step == 1) {
4391                 return PyString_FromStringAndSize(ptr + start,
4392                                                   slicelen);
4393             }
4394             dest = (char *)PyMem_Malloc(slicelen);
4395 
4396             if (dest == NULL)
4397                 return PyErr_NoMemory();
4398 
4399             for (cur = start, i = 0; i < slicelen;
4400                  cur += step, i++) {
4401                 dest[i] = ptr[cur];
4402             }
4403 
4404             np = PyString_FromStringAndSize(dest, slicelen);
4405             PyMem_Free(dest);
4406             return np;
4407         }
4408 #ifdef CTYPES_UNICODE
4409         if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4410             wchar_t *ptr = (wchar_t *)self->b_ptr;
4411             wchar_t *dest;
4412 
4413             if (slicelen <= 0)
4414                 return PyUnicode_FromUnicode(NULL, 0);
4415             if (step == 1) {
4416                 return PyUnicode_FromWideChar(ptr + start,
4417                                               slicelen);
4418             }
4419 
4420             dest = (wchar_t *)PyMem_Malloc(
4421                                     slicelen * sizeof(wchar_t));
4422 
4423             for (cur = start, i = 0; i < slicelen;
4424                  cur += step, i++) {
4425                 dest[i] = ptr[cur];
4426             }
4427 
4428             np = PyUnicode_FromWideChar(dest, slicelen);
4429             PyMem_Free(dest);
4430             return np;
4431         }
4432 #endif
4433 
4434         np = PyList_New(slicelen);
4435         if (np == NULL)
4436             return NULL;
4437 
4438         for (cur = start, i = 0; i < slicelen;
4439              cur += step, i++) {
4440             PyObject *v = Array_item(_self, cur);
4441             PyList_SET_ITEM(np, i, v);
4442         }
4443         return np;
4444     }
4445     else {
4446         PyErr_SetString(PyExc_TypeError,
4447                         "indices must be integers");
4448         return NULL;
4449     }
4450 
4451 }
4452 
4453 static int
4454 Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4455 {
4456     CDataObject *self = (CDataObject *)_self;
4457     Py_ssize_t size, offset;
4458     StgDictObject *stgdict;
4459     char *ptr;
4460 
4461     if (value == NULL) {
4462         PyErr_SetString(PyExc_TypeError,
4463                         "Array does not support item deletion");
4464         return -1;
4465     }
4466 
4467     stgdict = PyObject_stgdict((PyObject *)self);
4468     assert(stgdict); /* Cannot be NULL for array object instances */
4469     if (index < 0 || index >= stgdict->length) {
4470         PyErr_SetString(PyExc_IndexError,
4471                         "invalid index");
4472         return -1;
4473     }
4474     size = stgdict->size / stgdict->length;
4475     offset = index * size;
4476     ptr = self->b_ptr + offset;
4477 
4478     return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
4479                      index, size, ptr);
4480 }
4481 
4482 static int
4483 Array_ass_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *value)
4484 {
4485     CDataObject *self = (CDataObject *)_self;
4486     Py_ssize_t i, len;
4487 
4488     if (value == NULL) {
4489         PyErr_SetString(PyExc_TypeError,
4490                         "Array does not support item deletion");
4491         return -1;
4492     }
4493 
4494     if (ilow < 0)
4495         ilow = 0;
4496     else if (ilow > self->b_length)
4497         ilow = self->b_length;
4498     if (ihigh < 0)
4499         ihigh = 0;
4500     if (ihigh < ilow)
4501         ihigh = ilow;
4502     else if (ihigh > self->b_length)
4503         ihigh = self->b_length;
4504 
4505     len = PySequence_Length(value);
4506     if (len != ihigh - ilow) {
4507         PyErr_SetString(PyExc_ValueError,
4508                         "Can only assign sequence of same size");
4509         return -1;
4510     }
4511     for (i = 0; i < len; i++) {
4512         PyObject *item = PySequence_GetItem(value, i);
4513         int result;
4514         if (item == NULL)
4515             return -1;
4516         result = Array_ass_item(_self, i+ilow, item);
4517         Py_DECREF(item);
4518         if (result == -1)
4519             return -1;
4520     }
4521     return 0;
4522 }
4523 
4524 static int
4525 Array_ass_subscript(PyObject *_self, PyObject *item, PyObject *value)
4526 {
4527     CDataObject *self = (CDataObject *)_self;
4528 
4529     if (value == NULL) {
4530         PyErr_SetString(PyExc_TypeError,
4531                         "Array does not support item deletion");
4532         return -1;
4533     }
4534 
4535     if (PyIndex_Check(item)) {
4536         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4537 
4538         if (i == -1 && PyErr_Occurred())
4539             return -1;
4540         if (i < 0)
4541             i += self->b_length;
4542         return Array_ass_item(_self, i, value);
4543     }
4544     else if (PySlice_Check(item)) {
4545         Py_ssize_t start, stop, step, slicelen, otherlen, i, cur;
4546 
4547         if (PySlice_GetIndicesEx((PySliceObject *)item,
4548                                  self->b_length, &start, &stop,
4549                                  &step, &slicelen) < 0) {
4550             return -1;
4551         }
4552         if ((step < 0 && start < stop) ||
4553             (step > 0 && start > stop))
4554             stop = start;
4555 
4556         otherlen = PySequence_Length(value);
4557         if (otherlen != slicelen) {
4558             PyErr_SetString(PyExc_ValueError,
4559                 "Can only assign sequence of same size");
4560             return -1;
4561         }
4562         for (cur = start, i = 0; i < otherlen; cur += step, i++) {
4563             PyObject *item = PySequence_GetItem(value, i);
4564             int result;
4565             if (item == NULL)
4566                 return -1;
4567             result = Array_ass_item(_self, cur, item);
4568             Py_DECREF(item);
4569             if (result == -1)
4570                 return -1;
4571         }
4572         return 0;
4573     }
4574     else {
4575         PyErr_SetString(PyExc_TypeError,
4576                         "indices must be integer");
4577         return -1;
4578     }
4579 }
4580 
4581 static Py_ssize_t
4582 Array_length(PyObject *_self)
4583 {
4584     CDataObject *self = (CDataObject *)_self;
4585     return self->b_length;
4586 }
4587 
4588 static PySequenceMethods Array_as_sequence = {
4589     Array_length,                               /* sq_length; */
4590     0,                                          /* sq_concat; */
4591     0,                                          /* sq_repeat; */
4592     Array_item,                                 /* sq_item; */
4593     Array_slice,                                /* sq_slice; */
4594     Array_ass_item,                             /* sq_ass_item; */
4595     Array_ass_slice,                            /* sq_ass_slice; */
4596     0,                                          /* sq_contains; */
4597 
4598     0,                                          /* sq_inplace_concat; */
4599     0,                                          /* sq_inplace_repeat; */
4600 };
4601 
4602 static PyMappingMethods Array_as_mapping = {
4603     Array_length,
4604     Array_subscript,
4605     Array_ass_subscript,
4606 };
4607 
4608 PyTypeObject PyCArray_Type = {
4609     PyVarObject_HEAD_INIT(NULL, 0)
4610     "_ctypes.Array",
4611     sizeof(CDataObject),                        /* tp_basicsize */
4612     0,                                          /* tp_itemsize */
4613     0,                                          /* tp_dealloc */
4614     0,                                          /* tp_print */
4615     0,                                          /* tp_getattr */
4616     0,                                          /* tp_setattr */
4617     0,                                          /* tp_compare */
4618     0,                                          /* tp_repr */
4619     0,                                          /* tp_as_number */
4620     &Array_as_sequence,                         /* tp_as_sequence */
4621     &Array_as_mapping,                          /* tp_as_mapping */
4622     0,                                          /* tp_hash */
4623     0,                                          /* tp_call */
4624     0,                                          /* tp_str */
4625     0,                                          /* tp_getattro */
4626     0,                                          /* tp_setattro */
4627     &PyCData_as_buffer,                         /* tp_as_buffer */
4628     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4629     "XXX to be provided",                       /* tp_doc */
4630     (traverseproc)PyCData_traverse,             /* tp_traverse */
4631     (inquiry)PyCData_clear,                     /* tp_clear */
4632     0,                                          /* tp_richcompare */
4633     0,                                          /* tp_weaklistoffset */
4634     0,                                          /* tp_iter */
4635     0,                                          /* tp_iternext */
4636     0,                                          /* tp_methods */
4637     0,                                          /* tp_members */
4638     0,                                          /* tp_getset */
4639     0,                                          /* tp_base */
4640     0,                                          /* tp_dict */
4641     0,                                          /* tp_descr_get */
4642     0,                                          /* tp_descr_set */
4643     0,                                          /* tp_dictoffset */
4644     (initproc)Array_init,                       /* tp_init */
4645     0,                                          /* tp_alloc */
4646     GenericPyCData_new,                         /* tp_new */
4647     0,                                          /* tp_free */
4648 };
4649 
4650 PyObject *
4651 PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
4652 {
4653     static PyObject *cache;
4654     PyObject *key;
4655     PyObject *result;
4656     char name[256];
4657     PyObject *len;
4658 
4659     if (cache == NULL) {
4660         cache = PyDict_New();
4661         if (cache == NULL)
4662             return NULL;
4663     }
4664     len = PyInt_FromSsize_t(length);
4665     if (len == NULL)
4666         return NULL;
4667     key = PyTuple_Pack(2, itemtype, len);
4668     Py_DECREF(len);
4669     if (!key)
4670         return NULL;
4671     result = PyDict_GetItemProxy(cache, key);
4672     if (result) {
4673         Py_INCREF(result);
4674         Py_DECREF(key);
4675         return result;
4676     }
4677 
4678     if (!PyType_Check(itemtype)) {
4679         PyErr_SetString(PyExc_TypeError,
4680                         "Expected a type object");
4681         Py_DECREF(key);
4682         return NULL;
4683     }
4684 #ifdef MS_WIN64
4685     sprintf(name, "%.200s_Array_%Id",
4686         ((PyTypeObject *)itemtype)->tp_name, length);
4687 #else
4688     sprintf(name, "%.200s_Array_%ld",
4689         ((PyTypeObject *)itemtype)->tp_name, (long)length);
4690 #endif
4691 
4692     result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type,
4693 #if (PY_VERSION_HEX < 0x02050000)
4694                                    "s(O){s:i,s:O}",
4695 #else
4696                                    "s(O){s:n,s:O}",
4697 #endif
4698                                    name,
4699                                    &PyCArray_Type,
4700                                    "_length_",
4701                                    length,
4702                                    "_type_",
4703                                    itemtype
4704         );
4705     if (result == NULL) {
4706         Py_DECREF(key);
4707         return NULL;
4708     }
4709     if (-1 == PyDict_SetItemProxy(cache, key, result)) {
4710         Py_DECREF(key);
4711         Py_DECREF(result);
4712         return NULL;
4713     }
4714     Py_DECREF(key);
4715     return result;
4716 }
4717 
4718 
4719 /******************************************************************/
4720 /*
4721   Simple_Type
4722 */
4723 
4724 static int
4725 Simple_set_value(CDataObject *self, PyObject *value)
4726 {
4727     PyObject *result;
4728     StgDictObject *dict = PyObject_stgdict((PyObject *)self);
4729 
4730     if (value == NULL) {
4731         PyErr_SetString(PyExc_TypeError,
4732                         "can't delete attribute");
4733         return -1;
4734     }
4735     assert(dict); /* Cannot be NULL for CDataObject instances */
4736     assert(dict->setfunc);
4737     result = dict->setfunc(self->b_ptr, value, dict->size);
4738     if (!result)
4739         return -1;
4740 
4741     /* consumes the refcount the setfunc returns */
4742     return KeepRef(self, 0, result);
4743 }
4744 
4745 static int
4746 Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
4747 {
4748     PyObject *value = NULL;
4749     if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
4750         return -1;
4751     if (value)
4752         return Simple_set_value(self, value);
4753     return 0;
4754 }
4755 
4756 static PyObject *
4757 Simple_get_value(CDataObject *self)
4758 {
4759     StgDictObject *dict;
4760     dict = PyObject_stgdict((PyObject *)self);
4761     assert(dict); /* Cannot be NULL for CDataObject instances */
4762     assert(dict->getfunc);
4763     return dict->getfunc(self->b_ptr, self->b_size);
4764 }
4765 
4766 static PyGetSetDef Simple_getsets[] = {
4767     { "value", (getter)Simple_get_value, (setter)Simple_set_value,
4768       "current value", NULL },
4769     { NULL, NULL }
4770 };
4771 
4772 static PyObject *
4773 Simple_from_outparm(PyObject *self, PyObject *args)
4774 {
4775     if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) {
4776         Py_INCREF(self);
4777         return self;
4778     }
4779     /* call stgdict->getfunc */
4780     return Simple_get_value((CDataObject *)self);
4781 }
4782 
4783 static PyMethodDef Simple_methods[] = {
4784     { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
4785     { NULL, NULL },
4786 };
4787 
4788 static int Simple_nonzero(CDataObject *self)
4789 {
4790     return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
4791 }
4792 
4793 static PyNumberMethods Simple_as_number = {
4794     0, /* nb_add */
4795     0, /* nb_subtract */
4796     0, /* nb_multiply */
4797     0, /* nb_divide */
4798     0, /* nb_remainder */
4799     0, /* nb_divmod */
4800     0, /* nb_power */
4801     0, /* nb_negative */
4802     0, /* nb_positive */
4803     0, /* nb_absolute */
4804     (inquiry)Simple_nonzero, /* nb_nonzero */
4805 };
4806 
4807 /* "%s(%s)" % (self.__class__.__name__, self.value) */
4808 static PyObject *
4809 Simple_repr(CDataObject *self)
4810 {
4811     PyObject *val, *name, *args, *result;
4812     static PyObject *format;
4813 
4814     if (Py_TYPE(self)->tp_base != &Simple_Type) {
4815         return PyString_FromFormat("<%s object at %p>",
4816                                    Py_TYPE(self)->tp_name, self);
4817     }
4818 
4819     if (format == NULL) {
4820         format = PyString_InternFromString("%s(%r)");
4821         if (format == NULL)
4822             return NULL;
4823     }
4824 
4825     val = Simple_get_value(self);
4826     if (val == NULL)
4827         return NULL;
4828 
4829     name = PyString_FromString(Py_TYPE(self)->tp_name);
4830     if (name == NULL) {
4831         Py_DECREF(val);
4832         return NULL;
4833     }
4834 
4835     args = PyTuple_Pack(2, name, val);
4836     Py_DECREF(name);
4837     Py_DECREF(val);
4838     if (args == NULL)
4839         return NULL;
4840 
4841     result = PyString_Format(format, args);
4842     Py_DECREF(args);
4843     return result;
4844 }
4845 
4846 static PyTypeObject Simple_Type = {
4847     PyVarObject_HEAD_INIT(NULL, 0)
4848     "_ctypes._SimpleCData",
4849     sizeof(CDataObject),                        /* tp_basicsize */
4850     0,                                          /* tp_itemsize */
4851     0,                                          /* tp_dealloc */
4852     0,                                          /* tp_print */
4853     0,                                          /* tp_getattr */
4854     0,                                          /* tp_setattr */
4855     0,                                          /* tp_compare */
4856     (reprfunc)&Simple_repr,                     /* tp_repr */
4857     &Simple_as_number,                          /* tp_as_number */
4858     0,                                          /* tp_as_sequence */
4859     0,                                          /* tp_as_mapping */
4860     0,                                          /* tp_hash */
4861     0,                                          /* tp_call */
4862     0,                                          /* tp_str */
4863     0,                                          /* tp_getattro */
4864     0,                                          /* tp_setattro */
4865     &PyCData_as_buffer,                         /* tp_as_buffer */
4866     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4867     "XXX to be provided",                       /* tp_doc */
4868     (traverseproc)PyCData_traverse,             /* tp_traverse */
4869     (inquiry)PyCData_clear,                     /* tp_clear */
4870     0,                                          /* tp_richcompare */
4871     0,                                          /* tp_weaklistoffset */
4872     0,                                          /* tp_iter */
4873     0,                                          /* tp_iternext */
4874     Simple_methods,                             /* tp_methods */
4875     0,                                          /* tp_members */
4876     Simple_getsets,                             /* tp_getset */
4877     0,                                          /* tp_base */
4878     0,                                          /* tp_dict */
4879     0,                                          /* tp_descr_get */
4880     0,                                          /* tp_descr_set */
4881     0,                                          /* tp_dictoffset */
4882     (initproc)Simple_init,                      /* tp_init */
4883     0,                                          /* tp_alloc */
4884     GenericPyCData_new,                         /* tp_new */
4885     0,                                          /* tp_free */
4886 };
4887 
4888 /******************************************************************/
4889 /*
4890   PyCPointer_Type
4891 */
4892 static PyObject *
4893 Pointer_item(PyObject *_self, Py_ssize_t index)
4894 {
4895     CDataObject *self = (CDataObject *)_self;
4896     Py_ssize_t size;
4897     Py_ssize_t offset;
4898     StgDictObject *stgdict, *itemdict;
4899     PyObject *proto;
4900 
4901     if (*(void **)self->b_ptr == NULL) {
4902         PyErr_SetString(PyExc_ValueError,
4903                         "NULL pointer access");
4904         return NULL;
4905     }
4906 
4907     stgdict = PyObject_stgdict((PyObject *)self);
4908     assert(stgdict); /* Cannot be NULL for pointer object instances */
4909 
4910     proto = stgdict->proto;
4911     assert(proto);
4912     itemdict = PyType_stgdict(proto);
4913     assert(itemdict); /* proto is the item type of the pointer, a ctypes
4914                          type, so this cannot be NULL */
4915 
4916     size = itemdict->size;
4917     offset = index * itemdict->size;
4918 
4919     return PyCData_get(proto, stgdict->getfunc, (PyObject *)self,
4920                      index, size, (*(char **)self->b_ptr) + offset);
4921 }
4922 
4923 static int
4924 Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4925 {
4926     CDataObject *self = (CDataObject *)_self;
4927     Py_ssize_t size;
4928     Py_ssize_t offset;
4929     StgDictObject *stgdict, *itemdict;
4930     PyObject *proto;
4931 
4932     if (value == NULL) {
4933         PyErr_SetString(PyExc_TypeError,
4934                         "Pointer does not support item deletion");
4935         return -1;
4936     }
4937 
4938     if (*(void **)self->b_ptr == NULL) {
4939         PyErr_SetString(PyExc_ValueError,
4940                         "NULL pointer access");
4941         return -1;
4942     }
4943 
4944     stgdict = PyObject_stgdict((PyObject *)self);
4945     assert(stgdict); /* Cannot be NULL fr pointer instances */
4946 
4947     proto = stgdict->proto;
4948     assert(proto);
4949 
4950     itemdict = PyType_stgdict(proto);
4951     assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
4952                          is always a ctypes type */
4953 
4954     size = itemdict->size;
4955     offset = index * itemdict->size;
4956 
4957     return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value,
4958                      index, size, (*(char **)self->b_ptr) + offset);
4959 }
4960 
4961 static PyObject *
4962 Pointer_get_contents(CDataObject *self, void *closure)
4963 {
4964     StgDictObject *stgdict;
4965 
4966     if (*(void **)self->b_ptr == NULL) {
4967         PyErr_SetString(PyExc_ValueError,
4968                         "NULL pointer access");
4969         return NULL;
4970     }
4971 
4972     stgdict = PyObject_stgdict((PyObject *)self);
4973     assert(stgdict); /* Cannot be NULL fr pointer instances */
4974     return PyCData_FromBaseObj(stgdict->proto,
4975                              (PyObject *)self, 0,
4976                              *(void **)self->b_ptr);
4977 }
4978 
4979 static int
4980 Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
4981 {
4982     StgDictObject *stgdict;
4983     CDataObject *dst;
4984     PyObject *keep;
4985 
4986     if (value == NULL) {
4987         PyErr_SetString(PyExc_TypeError,
4988                         "Pointer does not support item deletion");
4989         return -1;
4990     }
4991     stgdict = PyObject_stgdict((PyObject *)self);
4992     assert(stgdict); /* Cannot be NULL fr pointer instances */
4993     assert(stgdict->proto);
4994     if (!CDataObject_Check(value)) {
4995         int res = PyObject_IsInstance(value, stgdict->proto);
4996         if (res == -1)
4997             return -1;
4998         if (!res) {
4999             PyErr_Format(PyExc_TypeError,
5000                          "expected %s instead of %s",
5001                          ((PyTypeObject *)(stgdict->proto))->tp_name,
5002                          Py_TYPE(value)->tp_name);
5003             return -1;
5004         }
5005     }
5006 
5007     dst = (CDataObject *)value;
5008     *(void **)self->b_ptr = dst->b_ptr;
5009 
5010     /*
5011        A Pointer instance must keep a the value it points to alive.  So, a
5012        pointer instance has b_length set to 2 instead of 1, and we set
5013        'value' itself as the second item of the b_objects list, additionally.
5014     */
5015     Py_INCREF(value);
5016     if (-1 == KeepRef(self, 1, value))
5017         return -1;
5018 
5019     keep = GetKeepedObjects(dst);
5020     Py_INCREF(keep);
5021     return KeepRef(self, 0, keep);
5022 }
5023 
5024 static PyGetSetDef Pointer_getsets[] = {
5025     { "contents", (getter)Pointer_get_contents,
5026       (setter)Pointer_set_contents,
5027       "the object this pointer points to (read-write)", NULL },
5028     { NULL, NULL }
5029 };
5030 
5031 static int
5032 Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
5033 {
5034     PyObject *value = NULL;
5035 
5036     if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
5037         return -1;
5038     if (value == NULL)
5039         return 0;
5040     return Pointer_set_contents(self, value, NULL);
5041 }
5042 
5043 static PyObject *
5044 Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
5045 {
5046     StgDictObject *dict = PyType_stgdict((PyObject *)type);
5047     if (!dict || !dict->proto) {
5048         PyErr_SetString(PyExc_TypeError,
5049                         "Cannot create instance: has no _type_");
5050         return NULL;
5051     }
5052     return GenericPyCData_new(type, args, kw);
5053 }
5054 
5055 static PyObject *
5056 Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
5057 {
5058     CDataObject *self = (CDataObject *)_self;
5059     PyListObject *np;
5060     StgDictObject *stgdict, *itemdict;
5061     PyObject *proto;
5062     Py_ssize_t i, len;
5063 
5064     if (ilow < 0)
5065         ilow = 0;
5066     if (ihigh < ilow)
5067         ihigh = ilow;
5068     len = ihigh - ilow;
5069 
5070     stgdict = PyObject_stgdict((PyObject *)self);
5071     assert(stgdict); /* Cannot be NULL fr pointer instances */
5072     proto = stgdict->proto;
5073     assert(proto);
5074     itemdict = PyType_stgdict(proto);
5075     assert(itemdict);
5076     if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
5077         char *ptr = *(char **)self->b_ptr;
5078         return PyString_FromStringAndSize(ptr + ilow, len);
5079 #ifdef CTYPES_UNICODE
5080     } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
5081         wchar_t *ptr = *(wchar_t **)self->b_ptr;
5082         return PyUnicode_FromWideChar(ptr + ilow, len);
5083 #endif
5084     }
5085 
5086     np = (PyListObject *) PyList_New(len);
5087     if (np == NULL)
5088         return NULL;
5089 
5090     for (i = 0; i < len; i++) {
5091         PyObject *v = Pointer_item(_self, i+ilow);
5092         PyList_SET_ITEM(np, i, v);
5093     }
5094     return (PyObject *)np;
5095 }
5096 
5097 static PyObject *
5098 Pointer_subscript(PyObject *_self, PyObject *item)
5099 {
5100     CDataObject *self = (CDataObject *)_self;
5101     if (PyIndex_Check(item)) {
5102         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
5103         if (i == -1 && PyErr_Occurred())
5104             return NULL;
5105         return Pointer_item(_self, i);
5106     }
5107     else if (PySlice_Check(item)) {
5108         PySliceObject *slice = (PySliceObject *)item;
5109         Py_ssize_t start, stop, step;
5110         PyObject *np;
5111         StgDictObject *stgdict, *itemdict;
5112         PyObject *proto;
5113         Py_ssize_t i, len, cur;
5114 
5115         /* Since pointers have no length, and we want to apply
5116            different semantics to negative indices than normal
5117            slicing, we have to dissect the slice object ourselves.*/
5118         if (slice->step == Py_None) {
5119             step = 1;
5120         }
5121         else {
5122             step = PyNumber_AsSsize_t(slice->step,
5123                                       PyExc_ValueError);
5124             if (step == -1 && PyErr_Occurred())
5125                 return NULL;
5126             if (step == 0) {
5127                 PyErr_SetString(PyExc_ValueError,
5128                                 "slice step cannot be zero");
5129                 return NULL;
5130             }
5131         }
5132         if (slice->start == Py_None) {
5133             if (step < 0) {
5134                 PyErr_SetString(PyExc_ValueError,
5135                                 "slice start is required "
5136                                 "for step < 0");
5137                 return NULL;
5138             }
5139             start = 0;
5140         }
5141         else {
5142             start = PyNumber_AsSsize_t(slice->start,
5143                                        PyExc_ValueError);
5144             if (start == -1 && PyErr_Occurred())
5145                 return NULL;
5146         }
5147         if (slice->stop == Py_None) {
5148             PyErr_SetString(PyExc_ValueError,
5149                             "slice stop is required");
5150             return NULL;
5151         }
5152         stop = PyNumber_AsSsize_t(slice->stop,
5153                                   PyExc_ValueError);
5154         if (stop == -1 && PyErr_Occurred())
5155             return NULL;
5156         if ((step > 0 && start > stop) ||
5157             (step < 0 && start < stop))
5158             len = 0;
5159         else if (step > 0)
5160             len = (stop - start - 1) / step + 1;
5161         else
5162             len = (stop - start + 1) / step + 1;
5163 
5164         stgdict = PyObject_stgdict((PyObject *)self);
5165         assert(stgdict); /* Cannot be NULL for pointer instances */
5166         proto = stgdict->proto;
5167         assert(proto);
5168         itemdict = PyType_stgdict(proto);
5169         assert(itemdict);
5170         if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
5171             char *ptr = *(char **)self->b_ptr;
5172             char *dest;
5173 
5174             if (len <= 0)
5175                 return PyString_FromString("");
5176             if (step == 1) {
5177                 return PyString_FromStringAndSize(ptr + start,
5178                                                   len);
5179             }
5180             dest = (char *)PyMem_Malloc(len);
5181             if (dest == NULL)
5182                 return PyErr_NoMemory();
5183             for (cur = start, i = 0; i < len; cur += step, i++) {
5184                 dest[i] = ptr[cur];
5185             }
5186             np = PyString_FromStringAndSize(dest, len);
5187             PyMem_Free(dest);
5188             return np;
5189         }
5190 #ifdef CTYPES_UNICODE
5191         if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
5192             wchar_t *ptr = *(wchar_t **)self->b_ptr;
5193             wchar_t *dest;
5194 
5195             if (len <= 0)
5196                 return PyUnicode_FromUnicode(NULL, 0);
5197             if (step == 1) {
5198                 return PyUnicode_FromWideChar(ptr + start,
5199                                               len);
5200             }
5201             dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t));
5202             if (dest == NULL)
5203                 return PyErr_NoMemory();
5204             for (cur = start, i = 0; i < len; cur += step, i++) {
5205                 dest[i] = ptr[cur];
5206             }
5207             np = PyUnicode_FromWideChar(dest, len);
5208             PyMem_Free(dest);
5209             return np;
5210         }
5211 #endif
5212 
5213         np = PyList_New(len);
5214         if (np == NULL)
5215             return NULL;
5216 
5217         for (cur = start, i = 0; i < len; cur += step, i++) {
5218             PyObject *v = Pointer_item(_self, cur);
5219             PyList_SET_ITEM(np, i, v);
5220         }
5221         return np;
5222     }
5223     else {
5224         PyErr_SetString(PyExc_TypeError,
5225                         "Pointer indices must be integer");
5226         return NULL;
5227     }
5228 }
5229 
5230 static PySequenceMethods Pointer_as_sequence = {
5231     0,                                          /* inquiry sq_length; */
5232     0,                                          /* binaryfunc sq_concat; */
5233     0,                                          /* intargfunc sq_repeat; */
5234     Pointer_item,                               /* intargfunc sq_item; */
5235     Pointer_slice,                              /* intintargfunc sq_slice; */
5236     Pointer_ass_item,                           /* intobjargproc sq_ass_item; */
5237     0,                                          /* intintobjargproc sq_ass_slice; */
5238     0,                                          /* objobjproc sq_contains; */
5239     /* Added in release 2.0 */
5240     0,                                          /* binaryfunc sq_inplace_concat; */
5241     0,                                          /* intargfunc sq_inplace_repeat; */
5242 };
5243 
5244 static PyMappingMethods Pointer_as_mapping = {
5245     0,
5246     Pointer_subscript,
5247 };
5248 
5249 static int
5250 Pointer_nonzero(CDataObject *self)
5251 {
5252     return (*(void **)self->b_ptr != NULL);
5253 }
5254 
5255 static PyNumberMethods Pointer_as_number = {
5256     0, /* nb_add */
5257     0, /* nb_subtract */
5258     0, /* nb_multiply */
5259     0, /* nb_divide */
5260     0, /* nb_remainder */
5261     0, /* nb_divmod */
5262     0, /* nb_power */
5263     0, /* nb_negative */
5264     0, /* nb_positive */
5265     0, /* nb_absolute */
5266     (inquiry)Pointer_nonzero, /* nb_nonzero */
5267 };
5268 
5269 PyTypeObject PyCPointer_Type = {
5270     PyVarObject_HEAD_INIT(NULL, 0)
5271     "_ctypes._Pointer",
5272     sizeof(CDataObject),                        /* tp_basicsize */
5273     0,                                          /* tp_itemsize */
5274     0,                                          /* tp_dealloc */
5275     0,                                          /* tp_print */
5276     0,                                          /* tp_getattr */
5277     0,                                          /* tp_setattr */
5278     0,                                          /* tp_compare */
5279     0,                                          /* tp_repr */
5280     &Pointer_as_number,                         /* tp_as_number */
5281     &Pointer_as_sequence,                       /* tp_as_sequence */
5282     &Pointer_as_mapping,                        /* tp_as_mapping */
5283     0,                                          /* tp_hash */
5284     0,                                          /* tp_call */
5285     0,                                          /* tp_str */
5286     0,                                          /* tp_getattro */
5287     0,                                          /* tp_setattro */
5288     &PyCData_as_buffer,                         /* tp_as_buffer */
5289     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
5290     "XXX to be provided",                       /* tp_doc */
5291     (traverseproc)PyCData_traverse,             /* tp_traverse */
5292     (inquiry)PyCData_clear,                     /* tp_clear */
5293     0,                                          /* tp_richcompare */
5294     0,                                          /* tp_weaklistoffset */
5295     0,                                          /* tp_iter */
5296     0,                                          /* tp_iternext */
5297     0,                                          /* tp_methods */
5298     0,                                          /* tp_members */
5299     Pointer_getsets,                            /* tp_getset */
5300     0,                                          /* tp_base */
5301     0,                                          /* tp_dict */
5302     0,                                          /* tp_descr_get */
5303     0,                                          /* tp_descr_set */
5304     0,                                          /* tp_dictoffset */
5305     (initproc)Pointer_init,                     /* tp_init */
5306     0,                                          /* tp_alloc */
5307     Pointer_new,                                /* tp_new */
5308     0,                                          /* tp_free */
5309 };
5310 
5311 
5312 /******************************************************************/
5313 /*
5314  *  Module initialization.
5315  */
5316 
5317 static char *module_docs =
5318 "Create and manipulate C compatible data types in Python.";
5319 
5320 #ifdef MS_WIN32
5321 
5322 static char comerror_doc[] = "Raised when a COM method call failed.";
5323 
5324 static PyObject *
5325 comerror_init(PyObject *self, PyObject *args)
5326 {
5327     PyObject *hresult, *text, *details;
5328     PyObject *a;
5329     int status;
5330 
5331     if (!PyArg_ParseTuple(args, "OOOO:COMError", &self, &hresult, &text, &details))
5332         return NULL;
5333 
5334     a = PySequence_GetSlice(args, 1, PySequence_Size(args));
5335     if (!a)
5336     return NULL;
5337     status = PyObject_SetAttrString(self, "args", a);
5338     Py_DECREF(a);
5339     if (status < 0)
5340     return NULL;
5341 
5342     if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
5343         return NULL;
5344 
5345     if (PyObject_SetAttrString(self, "text", text) < 0)
5346         return NULL;
5347 
5348     if (PyObject_SetAttrString(self, "details", details) < 0)
5349         return NULL;
5350 
5351     Py_INCREF(Py_None);
5352     return Py_None;
5353 }
5354 
5355 static PyMethodDef comerror_methods[] = {
5356     { "__init__", comerror_init, METH_VARARGS },
5357     { NULL, NULL },
5358 };
5359 
5360 static int
5361 create_comerror(void)
5362 {
5363     PyObject *dict = PyDict_New();
5364     PyMethodDef *methods = comerror_methods;
5365     PyObject *s;
5366     int status;
5367 
5368     if (dict == NULL)
5369         return -1;
5370 
5371     while (methods->ml_name) {
5372         /* get a wrapper for the built-in function */
5373         PyObject *func = PyCFunction_New(methods, NULL);
5374         PyObject *meth;
5375         if (func == NULL)
5376             goto error;
5377         meth = PyMethod_New(func, NULL, ComError);
5378         Py_DECREF(func);
5379         if (meth == NULL)
5380             goto error;
5381         PyDict_SetItemString(dict, methods->ml_name, meth);
5382         Py_DECREF(meth);
5383         ++methods;
5384     }
5385 
5386     s = PyString_FromString(comerror_doc);
5387     if (s == NULL)
5388         goto error;
5389     status = PyDict_SetItemString(dict, "__doc__", s);
5390     Py_DECREF(s);
5391     if (status == -1)
5392         goto error;
5393 
5394     ComError = PyErr_NewException("_ctypes.COMError",
5395                                   NULL,
5396                                   dict);
5397     if (ComError == NULL)
5398         goto error;
5399 
5400     return 0;
5401   error:
5402     Py_DECREF(dict);
5403     return -1;
5404 }
5405 
5406 #endif
5407 
5408 static PyObject *
5409 string_at(const char *ptr, int size)
5410 {
5411     if (size == -1)
5412         return PyString_FromString(ptr);
5413     return PyString_FromStringAndSize(ptr, size);
5414 }
5415 
5416 static int
5417 cast_check_pointertype(PyObject *arg)
5418 {
5419     StgDictObject *dict;
5420 
5421     if (PyCPointerTypeObject_Check(arg))
5422         return 1;
5423     if (PyCFuncPtrTypeObject_Check(arg))
5424         return 1;
5425     dict = PyType_stgdict(arg);
5426     if (dict) {
5427         if (PyString_Check(dict->proto)
5428             && (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) {
5429             /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
5430             return 1;
5431         }
5432     }
5433     PyErr_Format(PyExc_TypeError,
5434                  "cast() argument 2 must be a pointer type, not %s",
5435                  PyType_Check(arg)
5436                  ? ((PyTypeObject *)arg)->tp_name
5437                  : Py_TYPE(arg)->tp_name);
5438     return 0;
5439 }
5440 
5441 static PyObject *
5442 cast(void *ptr, PyObject *src, PyObject *ctype)
5443 {
5444     CDataObject *result;
5445     if (0 == cast_check_pointertype(ctype))
5446         return NULL;
5447     result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
5448     if (result == NULL)
5449         return NULL;
5450 
5451     /*
5452       The casted objects '_objects' member:
5453 
5454       It must certainly contain the source objects one.
5455       It must contain the source object itself.
5456      */
5457     if (CDataObject_Check(src)) {
5458         CDataObject *obj = (CDataObject *)src;
5459         /* PyCData_GetContainer will initialize src.b_objects, we need
5460            this so it can be shared */
5461         PyCData_GetContainer(obj);
5462         /* But we need a dictionary! */
5463         if (obj->b_objects == Py_None) {
5464             Py_DECREF(Py_None);
5465             obj->b_objects = PyDict_New();
5466             if (obj->b_objects == NULL)
5467                 goto failed;
5468         }
5469         Py_XINCREF(obj->b_objects);
5470         result->b_objects = obj->b_objects;
5471         if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
5472             PyObject *index;
5473             int rc;
5474             index = PyLong_FromVoidPtr((void *)src);
5475             if (index == NULL)
5476                 goto failed;
5477             rc = PyDict_SetItem(result->b_objects, index, src);
5478             Py_DECREF(index);
5479             if (rc == -1)
5480                 goto failed;
5481         }
5482     }
5483     /* Should we assert that result is a pointer type? */
5484     memcpy(result->b_ptr, &ptr, sizeof(void *));
5485     return (PyObject *)result;
5486 
5487   failed:
5488     Py_DECREF(result);
5489     return NULL;
5490 }
5491 
5492 #ifdef CTYPES_UNICODE
5493 static PyObject *
5494 wstring_at(const wchar_t *ptr, int size)
5495 {
5496     Py_ssize_t ssize = size;
5497     if (ssize == -1)
5498         ssize = wcslen(ptr);
5499     return PyUnicode_FromWideChar(ptr, ssize);
5500 }
5501 #endif
5502 
5503 PyMODINIT_FUNC
5504 init_ctypes(void)
5505 {
5506     PyObject *m;
5507 
5508 /* Note:
5509    ob_type is the metatype (the 'type'), defaults to PyType_Type,
5510    tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
5511 */
5512 #ifdef WITH_THREAD
5513     PyEval_InitThreads();
5514 #endif
5515     m = Py_InitModule3("_ctypes", _ctypes_module_methods, module_docs);
5516     if (!m)
5517         return;
5518 
5519     _ctypes_ptrtype_cache = PyDict_New();
5520     if (_ctypes_ptrtype_cache == NULL)
5521         return;
5522 
5523     PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache);
5524 
5525     _unpickle = PyObject_GetAttrString(m, "_unpickle");
5526     if (_unpickle == NULL)
5527         return;
5528 
5529     if (PyType_Ready(&PyCArg_Type) < 0)
5530         return;
5531 
5532     if (PyType_Ready(&PyCThunk_Type) < 0)
5533         return;
5534 
5535     /* StgDict is derived from PyDict_Type */
5536     PyCStgDict_Type.tp_base = &PyDict_Type;
5537     if (PyType_Ready(&PyCStgDict_Type) < 0)
5538         return;
5539 
5540     /*************************************************
5541      *
5542      * Metaclasses
5543      */
5544 
5545     PyCStructType_Type.tp_base = &PyType_Type;
5546     if (PyType_Ready(&PyCStructType_Type) < 0)
5547         return;
5548 
5549     UnionType_Type.tp_base = &PyType_Type;
5550     if (PyType_Ready(&UnionType_Type) < 0)
5551         return;
5552 
5553     PyCPointerType_Type.tp_base = &PyType_Type;
5554     if (PyType_Ready(&PyCPointerType_Type) < 0)
5555         return;
5556 
5557     PyCArrayType_Type.tp_base = &PyType_Type;
5558     if (PyType_Ready(&PyCArrayType_Type) < 0)
5559         return;
5560 
5561     PyCSimpleType_Type.tp_base = &PyType_Type;
5562     if (PyType_Ready(&PyCSimpleType_Type) < 0)
5563         return;
5564 
5565     PyCFuncPtrType_Type.tp_base = &PyType_Type;
5566     if (PyType_Ready(&PyCFuncPtrType_Type) < 0)
5567         return;
5568 
5569     /*************************************************
5570      *
5571      * Classes using a custom metaclass
5572      */
5573 
5574     if (PyType_Ready(&PyCData_Type) < 0)
5575         return;
5576 
5577     Py_TYPE(&Struct_Type) = &PyCStructType_Type;
5578     Struct_Type.tp_base = &PyCData_Type;
5579     if (PyType_Ready(&Struct_Type) < 0)
5580         return;
5581     Py_INCREF(&Struct_Type);
5582     PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
5583 
5584     Py_TYPE(&Union_Type) = &UnionType_Type;
5585     Union_Type.tp_base = &PyCData_Type;
5586     if (PyType_Ready(&Union_Type) < 0)
5587         return;
5588     Py_INCREF(&Union_Type);
5589     PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
5590 
5591     Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type;
5592     PyCPointer_Type.tp_base = &PyCData_Type;
5593     if (PyType_Ready(&PyCPointer_Type) < 0)
5594         return;
5595     Py_INCREF(&PyCPointer_Type);
5596     PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);
5597 
5598     Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type;
5599     PyCArray_Type.tp_base = &PyCData_Type;
5600     if (PyType_Ready(&PyCArray_Type) < 0)
5601         return;
5602     Py_INCREF(&PyCArray_Type);
5603     PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);
5604 
5605     Py_TYPE(&Simple_Type) = &PyCSimpleType_Type;
5606     Simple_Type.tp_base = &PyCData_Type;
5607     if (PyType_Ready(&Simple_Type) < 0)
5608         return;
5609     Py_INCREF(&Simple_Type);
5610     PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
5611 
5612     Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type;
5613     PyCFuncPtr_Type.tp_base = &PyCData_Type;
5614     if (PyType_Ready(&PyCFuncPtr_Type) < 0)
5615         return;
5616     Py_INCREF(&PyCFuncPtr_Type);
5617     PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);
5618 
5619     /*************************************************
5620      *
5621      * Simple classes
5622      */
5623 
5624     /* PyCField_Type is derived from PyBaseObject_Type */
5625     if (PyType_Ready(&PyCField_Type) < 0)
5626         return;
5627 
5628     /*************************************************
5629      *
5630      * Other stuff
5631      */
5632 
5633     DictRemover_Type.tp_new = PyType_GenericNew;
5634     if (PyType_Ready(&DictRemover_Type) < 0)
5635         return;
5636 
5637 #ifdef MS_WIN32
5638     if (create_comerror() < 0)
5639         return;
5640     PyModule_AddObject(m, "COMError", ComError);
5641 
5642     PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyInt_FromLong(FUNCFLAG_HRESULT));
5643     PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyInt_FromLong(FUNCFLAG_STDCALL));
5644 #endif
5645     PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
5646     PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyInt_FromLong(FUNCFLAG_USE_ERRNO));
5647     PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyInt_FromLong(FUNCFLAG_USE_LASTERROR));
5648     PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
5649     PyModule_AddStringConstant(m, "__version__", "1.1.0");
5650 
5651     PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
5652     PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
5653     PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
5654     PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
5655 #ifdef CTYPES_UNICODE
5656     PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
5657 #endif
5658 
5659 /* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
5660 #ifndef RTLD_LOCAL
5661 #define RTLD_LOCAL 0
5662 #endif
5663 
5664 /* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
5665    RTLD_LOCAL.
5666 */
5667 #ifndef RTLD_GLOBAL
5668 #define RTLD_GLOBAL RTLD_LOCAL
5669 #endif
5670 
5671     PyModule_AddObject(m, "RTLD_LOCAL", PyInt_FromLong(RTLD_LOCAL));
5672     PyModule_AddObject(m, "RTLD_GLOBAL", PyInt_FromLong(RTLD_GLOBAL));
5673 
5674     PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5675     if (PyExc_ArgError) {
5676         Py_INCREF(PyExc_ArgError);
5677         PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
5678     }
5679 }
5680 
5681 /*****************************************************************
5682  * replacements for broken Python api functions (in Python 2.3).
5683  * See #1047269 Buffer overwrite in PyUnicode_AsWideChar
5684  */
5685 
5686 #if (PY_VERSION_HEX < 0x02040000)
5687 #ifdef HAVE_WCHAR_H
5688 
5689 PyObject *My_PyUnicode_FromWideChar(register const wchar_t *w,
5690                                     Py_ssize_t size)
5691 {
5692     PyUnicodeObject *unicode;
5693 
5694     if (w == NULL) {
5695     PyErr_BadInternalCall();
5696     return NULL;
5697     }
5698 
5699     unicode = (PyUnicodeObject *)PyUnicode_FromUnicode(NULL, size);
5700     if (!unicode)
5701     return NULL;
5702 
5703     /* Copy the wchar_t data into the new object */
5704 #ifdef HAVE_USABLE_WCHAR_T
5705     memcpy(unicode->str, w, size * sizeof(wchar_t));
5706 #else
5707     {
5708     register Py_UNICODE *u;
5709     register int i;
5710     u = PyUnicode_AS_UNICODE(unicode);
5711     /* In Python, the following line has a one-off error */
5712     for (i = size; i > 0; i--)
5713         *u++ = *w++;
5714     }
5715 #endif
5716 
5717     return (PyObject *)unicode;
5718 }
5719 
5720 Py_ssize_t My_PyUnicode_AsWideChar(PyUnicodeObject *unicode,
5721                             register wchar_t *w,
5722                             Py_ssize_t size)
5723 {
5724     if (unicode == NULL) {
5725     PyErr_BadInternalCall();
5726     return -1;
5727     }
5728     if (size > PyUnicode_GET_SIZE(unicode))
5729     size = PyUnicode_GET_SIZE(unicode);
5730 #ifdef HAVE_USABLE_WCHAR_T
5731     memcpy(w, unicode->str, size * sizeof(wchar_t));
5732 #else
5733     {
5734     register Py_UNICODE *u;
5735     register int i;
5736     u = PyUnicode_AS_UNICODE(unicode);
5737     /* In Python, the following line has a one-off error */
5738     for (i = size; i > 0; i--)
5739         *w++ = *u++;
5740     }
5741 #endif
5742 
5743     return size;
5744 }
5745 #endif
5746 #endif
5747 
5748 /*
5749  Local Variables:
5750  compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
5751  End:
5752 */