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