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