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