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