Branch data Line data Source code
1 : : #ifndef Py_BUILD_CORE_BUILTIN
2 : : # define Py_BUILD_CORE_MODULE 1
3 : : #endif
4 : :
5 : : #include "Python.h"
6 : : // windows.h must be included before pycore internal headers
7 : : #ifdef MS_WIN32
8 : : # include <windows.h>
9 : : #endif
10 : :
11 : : #include "pycore_bitutils.h" // _Py_bswap32()
12 : : #include "pycore_call.h" // _PyObject_CallNoArgs()
13 : :
14 : : #include <ffi.h>
15 : : #include "ctypes.h"
16 : :
17 : :
18 : : #define CTYPES_CFIELD_CAPSULE_NAME_PYMEM "_ctypes/cfield.c pymem"
19 : :
20 : 0 : static void pymem_destructor(PyObject *ptr)
21 : : {
22 : 0 : void *p = PyCapsule_GetPointer(ptr, CTYPES_CFIELD_CAPSULE_NAME_PYMEM);
23 [ # # ]: 0 : if (p) {
24 : 0 : PyMem_Free(p);
25 : : }
26 : 0 : }
27 : :
28 : :
29 : : /******************************************************************/
30 : : /*
31 : : PyCField_Type
32 : : */
33 : :
34 : : /*
35 : : * Expects the size, index and offset for the current field in *psize and
36 : : * *poffset, stores the total size so far in *psize, the offset for the next
37 : : * field in *poffset, the alignment requirements for the current field in
38 : : * *palign, and returns a field descriptor for this field.
39 : : */
40 : : /*
41 : : * bitfields extension:
42 : : * bitsize != 0: this is a bit field.
43 : : * pbitofs points to the current bit offset, this will be updated.
44 : : * prev_desc points to the type of the previous bitfield, if any.
45 : : */
46 : : PyObject *
47 : 0 : PyCField_FromDesc(PyObject *desc, Py_ssize_t index,
48 : : Py_ssize_t *pfield_size, int bitsize, int *pbitofs,
49 : : Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign,
50 : : int pack, int big_endian)
51 : : {
52 : : CFieldObject *self;
53 : : PyObject *proto;
54 : : Py_ssize_t size, align;
55 : 0 : SETFUNC setfunc = NULL;
56 : 0 : GETFUNC getfunc = NULL;
57 : : StgDictObject *dict;
58 : : int fieldtype;
59 : : #define NO_BITFIELD 0
60 : : #define NEW_BITFIELD 1
61 : : #define CONT_BITFIELD 2
62 : : #define EXPAND_BITFIELD 3
63 : :
64 : 0 : self = (CFieldObject *)PyCField_Type.tp_alloc((PyTypeObject *)&PyCField_Type, 0);
65 [ # # ]: 0 : if (self == NULL)
66 : 0 : return NULL;
67 : 0 : dict = PyType_stgdict(desc);
68 [ # # ]: 0 : if (!dict) {
69 : 0 : PyErr_SetString(PyExc_TypeError,
70 : : "has no _stginfo_");
71 : 0 : Py_DECREF(self);
72 : 0 : return NULL;
73 : : }
74 [ # # ]: 0 : if (bitsize /* this is a bitfield request */
75 [ # # ]: 0 : && *pfield_size /* we have a bitfield open */
76 : : #ifdef MS_WIN32
77 : : /* MSVC, GCC with -mms-bitfields */
78 : : && dict->size * 8 == *pfield_size
79 : : #else
80 : : /* GCC */
81 [ # # ]: 0 : && dict->size * 8 <= *pfield_size
82 : : #endif
83 [ # # ]: 0 : && (*pbitofs + bitsize) <= *pfield_size) {
84 : : /* continue bit field */
85 : 0 : fieldtype = CONT_BITFIELD;
86 : : #ifndef MS_WIN32
87 [ # # ]: 0 : } else if (bitsize /* this is a bitfield request */
88 [ # # ]: 0 : && *pfield_size /* we have a bitfield open */
89 [ # # ]: 0 : && dict->size * 8 >= *pfield_size
90 [ # # ]: 0 : && (*pbitofs + bitsize) <= dict->size * 8) {
91 : : /* expand bit field */
92 : 0 : fieldtype = EXPAND_BITFIELD;
93 : : #endif
94 [ # # ]: 0 : } else if (bitsize) {
95 : : /* start new bitfield */
96 : 0 : fieldtype = NEW_BITFIELD;
97 : 0 : *pbitofs = 0;
98 : 0 : *pfield_size = dict->size * 8;
99 : : } else {
100 : : /* not a bit field */
101 : 0 : fieldtype = NO_BITFIELD;
102 : 0 : *pbitofs = 0;
103 : 0 : *pfield_size = 0;
104 : : }
105 : :
106 : 0 : size = dict->size;
107 : 0 : proto = desc;
108 : :
109 : : /* Field descriptors for 'c_char * n' are be scpecial cased to
110 : : return a Python string instead of an Array object instance...
111 : : */
112 [ # # ]: 0 : if (PyCArrayTypeObject_Check(proto)) {
113 : 0 : StgDictObject *adict = PyType_stgdict(proto);
114 : : StgDictObject *idict;
115 [ # # # # ]: 0 : if (adict && adict->proto) {
116 : 0 : idict = PyType_stgdict(adict->proto);
117 [ # # ]: 0 : if (!idict) {
118 : 0 : PyErr_SetString(PyExc_TypeError,
119 : : "has no _stginfo_");
120 : 0 : Py_DECREF(self);
121 : 0 : return NULL;
122 : : }
123 [ # # ]: 0 : if (idict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
124 : 0 : struct fielddesc *fd = _ctypes_get_fielddesc("s");
125 : 0 : getfunc = fd->getfunc;
126 : 0 : setfunc = fd->setfunc;
127 : : }
128 [ # # ]: 0 : if (idict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
129 : 0 : struct fielddesc *fd = _ctypes_get_fielddesc("U");
130 : 0 : getfunc = fd->getfunc;
131 : 0 : setfunc = fd->setfunc;
132 : : }
133 : : }
134 : : }
135 : :
136 : 0 : self->setfunc = setfunc;
137 : 0 : self->getfunc = getfunc;
138 : 0 : self->index = index;
139 : :
140 : 0 : self->proto = Py_NewRef(proto);
141 : :
142 [ # # # # : 0 : switch (fieldtype) {
# ]
143 : 0 : case NEW_BITFIELD:
144 [ # # ]: 0 : if (big_endian)
145 : 0 : self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
146 : : else
147 : 0 : self->size = (bitsize << 16) + *pbitofs;
148 : 0 : *pbitofs = bitsize;
149 : : /* fall through */
150 : 0 : case NO_BITFIELD:
151 [ # # ]: 0 : if (pack)
152 : 0 : align = min(pack, dict->align);
153 : : else
154 : 0 : align = dict->align;
155 [ # # # # ]: 0 : if (align && *poffset % align) {
156 : 0 : Py_ssize_t delta = align - (*poffset % align);
157 : 0 : *psize += delta;
158 : 0 : *poffset += delta;
159 : : }
160 : :
161 [ # # ]: 0 : if (bitsize == 0)
162 : 0 : self->size = size;
163 : 0 : *psize += size;
164 : :
165 : 0 : self->offset = *poffset;
166 : 0 : *poffset += size;
167 : :
168 : 0 : *palign = align;
169 : 0 : break;
170 : :
171 : 0 : case EXPAND_BITFIELD:
172 : 0 : *poffset += dict->size - *pfield_size/8;
173 : 0 : *psize += dict->size - *pfield_size/8;
174 : :
175 : 0 : *pfield_size = dict->size * 8;
176 : :
177 [ # # ]: 0 : if (big_endian)
178 : 0 : self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
179 : : else
180 : 0 : self->size = (bitsize << 16) + *pbitofs;
181 : :
182 : 0 : self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
183 : 0 : *pbitofs += bitsize;
184 : 0 : break;
185 : :
186 : 0 : case CONT_BITFIELD:
187 [ # # ]: 0 : if (big_endian)
188 : 0 : self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize;
189 : : else
190 : 0 : self->size = (bitsize << 16) + *pbitofs;
191 : :
192 : 0 : self->offset = *poffset - size; /* poffset is already updated for the NEXT field */
193 : 0 : *pbitofs += bitsize;
194 : 0 : break;
195 : : }
196 : :
197 : 0 : return (PyObject *)self;
198 : : }
199 : :
200 : : static int
201 : 0 : PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
202 : : {
203 : : CDataObject *dst;
204 : : char *ptr;
205 [ # # ]: 0 : if (!CDataObject_Check(inst)) {
206 : 0 : PyErr_SetString(PyExc_TypeError,
207 : : "not a ctype instance");
208 : 0 : return -1;
209 : : }
210 : 0 : dst = (CDataObject *)inst;
211 : 0 : ptr = dst->b_ptr + self->offset;
212 [ # # ]: 0 : if (value == NULL) {
213 : 0 : PyErr_SetString(PyExc_TypeError,
214 : : "can't delete attribute");
215 : 0 : return -1;
216 : : }
217 : 0 : return PyCData_set(inst, self->proto, self->setfunc, value,
218 : : self->index, self->size, ptr);
219 : : }
220 : :
221 : : static PyObject *
222 : 0 : PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
223 : : {
224 : : CDataObject *src;
225 [ # # ]: 0 : if (inst == NULL) {
226 : 0 : return Py_NewRef(self);
227 : : }
228 [ # # ]: 0 : if (!CDataObject_Check(inst)) {
229 : 0 : PyErr_SetString(PyExc_TypeError,
230 : : "not a ctype instance");
231 : 0 : return NULL;
232 : : }
233 : 0 : src = (CDataObject *)inst;
234 : 0 : return PyCData_get(self->proto, self->getfunc, inst,
235 : 0 : self->index, self->size, src->b_ptr + self->offset);
236 : : }
237 : :
238 : : static PyObject *
239 : 0 : PyCField_get_offset(PyObject *self, void *data)
240 : : {
241 : 0 : return PyLong_FromSsize_t(((CFieldObject *)self)->offset);
242 : : }
243 : :
244 : : static PyObject *
245 : 0 : PyCField_get_size(PyObject *self, void *data)
246 : : {
247 : 0 : return PyLong_FromSsize_t(((CFieldObject *)self)->size);
248 : : }
249 : :
250 : : static PyGetSetDef PyCField_getset[] = {
251 : : { "offset", PyCField_get_offset, NULL, "offset in bytes of this field" },
252 : : { "size", PyCField_get_size, NULL, "size in bytes of this field" },
253 : : { NULL, NULL, NULL, NULL },
254 : : };
255 : :
256 : : static int
257 : 0 : PyCField_traverse(CFieldObject *self, visitproc visit, void *arg)
258 : : {
259 [ # # # # ]: 0 : Py_VISIT(self->proto);
260 : 0 : return 0;
261 : : }
262 : :
263 : : static int
264 : 0 : PyCField_clear(CFieldObject *self)
265 : : {
266 [ # # ]: 0 : Py_CLEAR(self->proto);
267 : 0 : return 0;
268 : : }
269 : :
270 : : static void
271 : 0 : PyCField_dealloc(PyObject *self)
272 : : {
273 : 0 : PyObject_GC_UnTrack(self);
274 : 0 : PyCField_clear((CFieldObject *)self);
275 : 0 : Py_TYPE(self)->tp_free((PyObject *)self);
276 : 0 : }
277 : :
278 : : static PyObject *
279 : 0 : PyCField_repr(CFieldObject *self)
280 : : {
281 : : PyObject *result;
282 : 0 : Py_ssize_t bits = self->size >> 16;
283 : 0 : Py_ssize_t size = self->size & 0xFFFF;
284 : : const char *name;
285 : :
286 : 0 : name = ((PyTypeObject *)self->proto)->tp_name;
287 : :
288 [ # # ]: 0 : if (bits)
289 : 0 : result = PyUnicode_FromFormat(
290 : : "<Field type=%s, ofs=%zd:%zd, bits=%zd>",
291 : : name, self->offset, size, bits);
292 : : else
293 : 0 : result = PyUnicode_FromFormat(
294 : : "<Field type=%s, ofs=%zd, size=%zd>",
295 : : name, self->offset, size);
296 : 0 : return result;
297 : : }
298 : :
299 : : PyTypeObject PyCField_Type = {
300 : : PyVarObject_HEAD_INIT(NULL, 0)
301 : : "_ctypes.CField", /* tp_name */
302 : : sizeof(CFieldObject), /* tp_basicsize */
303 : : 0, /* tp_itemsize */
304 : : PyCField_dealloc, /* tp_dealloc */
305 : : 0, /* tp_vectorcall_offset */
306 : : 0, /* tp_getattr */
307 : : 0, /* tp_setattr */
308 : : 0, /* tp_as_async */
309 : : (reprfunc)PyCField_repr, /* tp_repr */
310 : : 0, /* tp_as_number */
311 : : 0, /* tp_as_sequence */
312 : : 0, /* tp_as_mapping */
313 : : 0, /* tp_hash */
314 : : 0, /* tp_call */
315 : : 0, /* tp_str */
316 : : 0, /* tp_getattro */
317 : : 0, /* tp_setattro */
318 : : 0, /* tp_as_buffer */
319 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
320 : : PyDoc_STR("Structure/Union member"), /* tp_doc */
321 : : (traverseproc)PyCField_traverse, /* tp_traverse */
322 : : (inquiry)PyCField_clear, /* tp_clear */
323 : : 0, /* tp_richcompare */
324 : : 0, /* tp_weaklistoffset */
325 : : 0, /* tp_iter */
326 : : 0, /* tp_iternext */
327 : : 0, /* tp_methods */
328 : : 0, /* tp_members */
329 : : PyCField_getset, /* tp_getset */
330 : : 0, /* tp_base */
331 : : 0, /* tp_dict */
332 : : (descrgetfunc)PyCField_get, /* tp_descr_get */
333 : : (descrsetfunc)PyCField_set, /* tp_descr_set */
334 : : 0, /* tp_dictoffset */
335 : : 0, /* tp_init */
336 : : 0, /* tp_alloc */
337 : : 0, /* tp_new */
338 : : 0, /* tp_free */
339 : : };
340 : :
341 : :
342 : : /******************************************************************/
343 : : /*
344 : : Accessor functions
345 : : */
346 : :
347 : : /* Derived from Modules/structmodule.c:
348 : : Helper routine to get a Python integer and raise the appropriate error
349 : : if it isn't one */
350 : :
351 : : static int
352 : 0 : get_long(PyObject *v, long *p)
353 : : {
354 : 0 : long x = PyLong_AsUnsignedLongMask(v);
355 [ # # # # ]: 0 : if (x == -1 && PyErr_Occurred())
356 : 0 : return -1;
357 : 0 : *p = x;
358 : 0 : return 0;
359 : : }
360 : :
361 : : /* Same, but handling unsigned long */
362 : :
363 : : static int
364 : 0 : get_ulong(PyObject *v, unsigned long *p)
365 : : {
366 : 0 : unsigned long x = PyLong_AsUnsignedLongMask(v);
367 [ # # # # ]: 0 : if (x == (unsigned long)-1 && PyErr_Occurred())
368 : 0 : return -1;
369 : 0 : *p = x;
370 : 0 : return 0;
371 : : }
372 : :
373 : : /* Same, but handling native long long. */
374 : :
375 : : static int
376 : 0 : get_longlong(PyObject *v, long long *p)
377 : : {
378 : 0 : long long x = PyLong_AsUnsignedLongLongMask(v);
379 [ # # # # ]: 0 : if (x == -1 && PyErr_Occurred())
380 : 0 : return -1;
381 : 0 : *p = x;
382 : 0 : return 0;
383 : : }
384 : :
385 : : /* Same, but handling native unsigned long long. */
386 : :
387 : : static int
388 : 0 : get_ulonglong(PyObject *v, unsigned long long *p)
389 : : {
390 : 0 : unsigned long long x = PyLong_AsUnsignedLongLongMask(v);
391 [ # # # # ]: 0 : if (x == (unsigned long long)-1 && PyErr_Occurred())
392 : 0 : return -1;
393 : 0 : *p = x;
394 : 0 : return 0;
395 : : }
396 : :
397 : : /*****************************************************************
398 : : * Integer fields, with bitfield support
399 : : */
400 : :
401 : : /* how to decode the size field, for integer get/set functions */
402 : : #define LOW_BIT(x) ((x) & 0xFFFF)
403 : : #define NUM_BITS(x) ((x) >> 16)
404 : :
405 : : /* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */
406 : : #define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1)
407 : :
408 : : /* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
409 : : we must first shift left, then right.
410 : : */
411 : : #define GET_BITFIELD(v, size) \
412 : : if (NUM_BITS(size)) { \
413 : : v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \
414 : : v >>= (sizeof(v)*8 - NUM_BITS(size)); \
415 : : }
416 : :
417 : : /* This macro RETURNS the first parameter with the bit field CHANGED. */
418 : : #define SET(type, x, v, size) \
419 : : (NUM_BITS(size) ? \
420 : : ( ( (type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type, size)) << LOW_BIT(size) ) ) \
421 : : : (type)v)
422 : :
423 : : #if SIZEOF_SHORT == 2
424 : : # define SWAP_SHORT _Py_bswap16
425 : : #else
426 : : # error "unsupported short size"
427 : : #endif
428 : :
429 : : #if SIZEOF_INT == 4
430 : : # define SWAP_INT _Py_bswap32
431 : : #else
432 : : # error "unsupported int size"
433 : : #endif
434 : :
435 : : #if SIZEOF_LONG == 4
436 : : # define SWAP_LONG _Py_bswap32
437 : : #elif SIZEOF_LONG == 8
438 : : # define SWAP_LONG _Py_bswap64
439 : : #else
440 : : # error "unsupported long size"
441 : : #endif
442 : :
443 : : #if SIZEOF_LONG_LONG == 8
444 : : # define SWAP_LONG_LONG _Py_bswap64
445 : : #else
446 : : # error "unsupported long long size"
447 : : #endif
448 : :
449 : : /*****************************************************************
450 : : * The setter methods return an object which must be kept alive, to keep the
451 : : * data valid which has been stored in the memory block. The ctypes object
452 : : * instance inserts this object into its 'b_objects' list.
453 : : *
454 : : * For simple Python types like integers or characters, there is nothing that
455 : : * has to been kept alive, so Py_None is returned in these cases. But this
456 : : * makes inspecting the 'b_objects' list, which is accessible from Python for
457 : : * debugging, less useful.
458 : : *
459 : : * So, defining the _CTYPES_DEBUG_KEEP symbol returns the original value
460 : : * instead of Py_None.
461 : : */
462 : :
463 : : #ifdef _CTYPES_DEBUG_KEEP
464 : : #define _RET(x) Py_INCREF(x); return x
465 : : #else
466 : : #define _RET(X) Py_RETURN_NONE
467 : : #endif
468 : :
469 : : /*****************************************************************
470 : : * integer accessor methods, supporting bit fields
471 : : */
472 : :
473 : : static PyObject *
474 : 0 : b_set(void *ptr, PyObject *value, Py_ssize_t size)
475 : : {
476 : : long val;
477 [ # # ]: 0 : if (get_long(value, &val) < 0)
478 : 0 : return NULL;
479 [ # # ]: 0 : *(signed char *)ptr = SET(signed char, *(signed char *)ptr, val, size);
480 : 0 : _RET(value);
481 : : }
482 : :
483 : :
484 : : static PyObject *
485 : 0 : b_get(void *ptr, Py_ssize_t size)
486 : : {
487 : 0 : signed char val = *(signed char *)ptr;
488 [ # # ]: 0 : GET_BITFIELD(val, size);
489 : 0 : return PyLong_FromLong(val);
490 : : }
491 : :
492 : : static PyObject *
493 : 0 : B_set(void *ptr, PyObject *value, Py_ssize_t size)
494 : : {
495 : : unsigned long val;
496 [ # # ]: 0 : if (get_ulong(value, &val) < 0)
497 : 0 : return NULL;
498 [ # # ]: 0 : *(unsigned char *)ptr = SET(unsigned char, *(unsigned char*)ptr, val, size);
499 : 0 : _RET(value);
500 : : }
501 : :
502 : :
503 : : static PyObject *
504 : 0 : B_get(void *ptr, Py_ssize_t size)
505 : : {
506 : 0 : unsigned char val = *(unsigned char *)ptr;
507 [ # # ]: 0 : GET_BITFIELD(val, size);
508 : 0 : return PyLong_FromLong(val);
509 : : }
510 : :
511 : : static PyObject *
512 : 0 : h_set(void *ptr, PyObject *value, Py_ssize_t size)
513 : : {
514 : : long val;
515 : : short x;
516 [ # # ]: 0 : if (get_long(value, &val) < 0)
517 : 0 : return NULL;
518 : 0 : memcpy(&x, ptr, sizeof(x));
519 [ # # ]: 0 : x = SET(short, x, val, size);
520 : 0 : memcpy(ptr, &x, sizeof(x));
521 : 0 : _RET(value);
522 : : }
523 : :
524 : :
525 : : static PyObject *
526 : 0 : h_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
527 : : {
528 : : long val;
529 : : short field;
530 [ # # ]: 0 : if (get_long(value, &val) < 0) {
531 : 0 : return NULL;
532 : : }
533 : 0 : memcpy(&field, ptr, sizeof(field));
534 : 0 : field = SWAP_SHORT(field);
535 [ # # ]: 0 : field = SET(short, field, val, size);
536 : 0 : field = SWAP_SHORT(field);
537 : 0 : memcpy(ptr, &field, sizeof(field));
538 : 0 : _RET(value);
539 : : }
540 : :
541 : : static PyObject *
542 : 0 : h_get(void *ptr, Py_ssize_t size)
543 : : {
544 : : short val;
545 : 0 : memcpy(&val, ptr, sizeof(val));
546 [ # # ]: 0 : GET_BITFIELD(val, size);
547 : 0 : return PyLong_FromLong((long)val);
548 : : }
549 : :
550 : : static PyObject *
551 : 0 : h_get_sw(void *ptr, Py_ssize_t size)
552 : : {
553 : : short val;
554 : 0 : memcpy(&val, ptr, sizeof(val));
555 : 0 : val = SWAP_SHORT(val);
556 [ # # ]: 0 : GET_BITFIELD(val, size);
557 : 0 : return PyLong_FromLong(val);
558 : : }
559 : :
560 : : static PyObject *
561 : 0 : H_set(void *ptr, PyObject *value, Py_ssize_t size)
562 : : {
563 : : unsigned long val;
564 : : unsigned short x;
565 [ # # ]: 0 : if (get_ulong(value, &val) < 0)
566 : 0 : return NULL;
567 : 0 : memcpy(&x, ptr, sizeof(x));
568 [ # # ]: 0 : x = SET(unsigned short, x, val, size);
569 : 0 : memcpy(ptr, &x, sizeof(x));
570 : 0 : _RET(value);
571 : : }
572 : :
573 : : static PyObject *
574 : 0 : H_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
575 : : {
576 : : unsigned long val;
577 : : unsigned short field;
578 [ # # ]: 0 : if (get_ulong(value, &val) < 0) {
579 : 0 : return NULL;
580 : : }
581 : 0 : memcpy(&field, ptr, sizeof(field));
582 : 0 : field = SWAP_SHORT(field);
583 [ # # ]: 0 : field = SET(unsigned short, field, val, size);
584 : 0 : field = SWAP_SHORT(field);
585 : 0 : memcpy(ptr, &field, sizeof(field));
586 : 0 : _RET(value);
587 : : }
588 : :
589 : :
590 : : static PyObject *
591 : 0 : H_get(void *ptr, Py_ssize_t size)
592 : : {
593 : : unsigned short val;
594 : 0 : memcpy(&val, ptr, sizeof(val));
595 [ # # ]: 0 : GET_BITFIELD(val, size);
596 : 0 : return PyLong_FromLong(val);
597 : : }
598 : :
599 : : static PyObject *
600 : 0 : H_get_sw(void *ptr, Py_ssize_t size)
601 : : {
602 : : unsigned short val;
603 : 0 : memcpy(&val, ptr, sizeof(val));
604 : 0 : val = SWAP_SHORT(val);
605 [ # # ]: 0 : GET_BITFIELD(val, size);
606 : 0 : return PyLong_FromLong(val);
607 : : }
608 : :
609 : : static PyObject *
610 : 0 : i_set(void *ptr, PyObject *value, Py_ssize_t size)
611 : : {
612 : : long val;
613 : : int x;
614 [ # # ]: 0 : if (get_long(value, &val) < 0)
615 : 0 : return NULL;
616 : 0 : memcpy(&x, ptr, sizeof(x));
617 [ # # ]: 0 : x = SET(int, x, val, size);
618 : 0 : memcpy(ptr, &x, sizeof(x));
619 : 0 : _RET(value);
620 : : }
621 : :
622 : : static PyObject *
623 : 0 : i_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
624 : : {
625 : : long val;
626 : : int field;
627 [ # # ]: 0 : if (get_long(value, &val) < 0) {
628 : 0 : return NULL;
629 : : }
630 : 0 : memcpy(&field, ptr, sizeof(field));
631 : 0 : field = SWAP_INT(field);
632 [ # # ]: 0 : field = SET(int, field, val, size);
633 : 0 : field = SWAP_INT(field);
634 : 0 : memcpy(ptr, &field, sizeof(field));
635 : 0 : _RET(value);
636 : : }
637 : :
638 : :
639 : : static PyObject *
640 : 0 : i_get(void *ptr, Py_ssize_t size)
641 : : {
642 : : int val;
643 : 0 : memcpy(&val, ptr, sizeof(val));
644 [ # # ]: 0 : GET_BITFIELD(val, size);
645 : 0 : return PyLong_FromLong(val);
646 : : }
647 : :
648 : : static PyObject *
649 : 0 : i_get_sw(void *ptr, Py_ssize_t size)
650 : : {
651 : : int val;
652 : 0 : memcpy(&val, ptr, sizeof(val));
653 : 0 : val = SWAP_INT(val);
654 [ # # ]: 0 : GET_BITFIELD(val, size);
655 : 0 : return PyLong_FromLong(val);
656 : : }
657 : :
658 : : #ifndef MS_WIN32
659 : : /* http://msdn.microsoft.com/en-us/library/cc237864.aspx */
660 : : #define VARIANT_FALSE 0x0000
661 : : #define VARIANT_TRUE 0xFFFF
662 : : #endif
663 : : /* short BOOL - VARIANT_BOOL */
664 : : static PyObject *
665 : 0 : vBOOL_set(void *ptr, PyObject *value, Py_ssize_t size)
666 : : {
667 [ # # # ]: 0 : switch (PyObject_IsTrue(value)) {
668 : 0 : case -1:
669 : 0 : return NULL;
670 : 0 : case 0:
671 : 0 : *(short int *)ptr = VARIANT_FALSE;
672 : 0 : _RET(value);
673 : 0 : default:
674 : 0 : *(short int *)ptr = VARIANT_TRUE;
675 : 0 : _RET(value);
676 : : }
677 : : }
678 : :
679 : : static PyObject *
680 : 0 : vBOOL_get(void *ptr, Py_ssize_t size)
681 : : {
682 : 0 : return PyBool_FromLong((long)*(short int *)ptr);
683 : : }
684 : :
685 : : static PyObject *
686 : 0 : bool_set(void *ptr, PyObject *value, Py_ssize_t size)
687 : : {
688 [ # # # ]: 0 : switch (PyObject_IsTrue(value)) {
689 : 0 : case -1:
690 : 0 : return NULL;
691 : 0 : case 0:
692 : 0 : *(_Bool *)ptr = 0;
693 : 0 : _RET(value);
694 : 0 : default:
695 : 0 : *(_Bool *)ptr = 1;
696 : 0 : _RET(value);
697 : : }
698 : : }
699 : :
700 : : static PyObject *
701 : 0 : bool_get(void *ptr, Py_ssize_t size)
702 : : {
703 : 0 : return PyBool_FromLong((long)*(_Bool *)ptr);
704 : : }
705 : :
706 : : static PyObject *
707 : 0 : I_set(void *ptr, PyObject *value, Py_ssize_t size)
708 : : {
709 : : unsigned long val;
710 : : unsigned int x;
711 [ # # ]: 0 : if (get_ulong(value, &val) < 0)
712 : 0 : return NULL;
713 : 0 : memcpy(&x, ptr, sizeof(x));
714 [ # # ]: 0 : x = SET(unsigned int, x, val, size);
715 : 0 : memcpy(ptr, &x, sizeof(x));
716 : 0 : _RET(value);
717 : : }
718 : :
719 : : static PyObject *
720 : 0 : I_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
721 : : {
722 : : unsigned long val;
723 : : unsigned int field;
724 [ # # ]: 0 : if (get_ulong(value, &val) < 0) {
725 : 0 : return NULL;
726 : : }
727 : 0 : memcpy(&field, ptr, sizeof(field));
728 : 0 : field = SWAP_INT(field);
729 [ # # ]: 0 : field = SET(unsigned int, field, (unsigned int)val, size);
730 : 0 : field = SWAP_INT(field);
731 : 0 : memcpy(ptr, &field, sizeof(field));
732 : 0 : _RET(value);
733 : : }
734 : :
735 : :
736 : : static PyObject *
737 : 0 : I_get(void *ptr, Py_ssize_t size)
738 : : {
739 : : unsigned int val;
740 : 0 : memcpy(&val, ptr, sizeof(val));
741 [ # # ]: 0 : GET_BITFIELD(val, size);
742 : 0 : return PyLong_FromUnsignedLong(val);
743 : : }
744 : :
745 : : static PyObject *
746 : 0 : I_get_sw(void *ptr, Py_ssize_t size)
747 : : {
748 : : unsigned int val;
749 : 0 : memcpy(&val, ptr, sizeof(val));
750 : 0 : val = SWAP_INT(val);
751 [ # # ]: 0 : GET_BITFIELD(val, size);
752 : 0 : return PyLong_FromUnsignedLong(val);
753 : : }
754 : :
755 : : static PyObject *
756 : 0 : l_set(void *ptr, PyObject *value, Py_ssize_t size)
757 : : {
758 : : long val;
759 : : long x;
760 [ # # ]: 0 : if (get_long(value, &val) < 0)
761 : 0 : return NULL;
762 : 0 : memcpy(&x, ptr, sizeof(x));
763 [ # # ]: 0 : x = SET(long, x, val, size);
764 : 0 : memcpy(ptr, &x, sizeof(x));
765 : 0 : _RET(value);
766 : : }
767 : :
768 : : static PyObject *
769 : 0 : l_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
770 : : {
771 : : long val;
772 : : long field;
773 [ # # ]: 0 : if (get_long(value, &val) < 0) {
774 : 0 : return NULL;
775 : : }
776 : 0 : memcpy(&field, ptr, sizeof(field));
777 : 0 : field = SWAP_LONG(field);
778 [ # # ]: 0 : field = SET(long, field, val, size);
779 : 0 : field = SWAP_LONG(field);
780 : 0 : memcpy(ptr, &field, sizeof(field));
781 : 0 : _RET(value);
782 : : }
783 : :
784 : :
785 : : static PyObject *
786 : 0 : l_get(void *ptr, Py_ssize_t size)
787 : : {
788 : : long val;
789 : 0 : memcpy(&val, ptr, sizeof(val));
790 [ # # ]: 0 : GET_BITFIELD(val, size);
791 : 0 : return PyLong_FromLong(val);
792 : : }
793 : :
794 : : static PyObject *
795 : 0 : l_get_sw(void *ptr, Py_ssize_t size)
796 : : {
797 : : long val;
798 : 0 : memcpy(&val, ptr, sizeof(val));
799 : 0 : val = SWAP_LONG(val);
800 [ # # ]: 0 : GET_BITFIELD(val, size);
801 : 0 : return PyLong_FromLong(val);
802 : : }
803 : :
804 : : static PyObject *
805 : 0 : L_set(void *ptr, PyObject *value, Py_ssize_t size)
806 : : {
807 : : unsigned long val;
808 : : unsigned long x;
809 [ # # ]: 0 : if (get_ulong(value, &val) < 0)
810 : 0 : return NULL;
811 : 0 : memcpy(&x, ptr, sizeof(x));
812 [ # # ]: 0 : x = SET(unsigned long, x, val, size);
813 : 0 : memcpy(ptr, &x, sizeof(x));
814 : 0 : _RET(value);
815 : : }
816 : :
817 : : static PyObject *
818 : 0 : L_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
819 : : {
820 : : unsigned long val;
821 : : unsigned long field;
822 [ # # ]: 0 : if (get_ulong(value, &val) < 0) {
823 : 0 : return NULL;
824 : : }
825 : 0 : memcpy(&field, ptr, sizeof(field));
826 : 0 : field = SWAP_LONG(field);
827 [ # # ]: 0 : field = SET(unsigned long, field, val, size);
828 : 0 : field = SWAP_LONG(field);
829 : 0 : memcpy(ptr, &field, sizeof(field));
830 : 0 : _RET(value);
831 : : }
832 : :
833 : :
834 : : static PyObject *
835 : 0 : L_get(void *ptr, Py_ssize_t size)
836 : : {
837 : : unsigned long val;
838 : 0 : memcpy(&val, ptr, sizeof(val));
839 [ # # ]: 0 : GET_BITFIELD(val, size);
840 : 0 : return PyLong_FromUnsignedLong(val);
841 : : }
842 : :
843 : : static PyObject *
844 : 0 : L_get_sw(void *ptr, Py_ssize_t size)
845 : : {
846 : : unsigned long val;
847 : 0 : memcpy(&val, ptr, sizeof(val));
848 : 0 : val = SWAP_LONG(val);
849 [ # # ]: 0 : GET_BITFIELD(val, size);
850 : 0 : return PyLong_FromUnsignedLong(val);
851 : : }
852 : :
853 : : static PyObject *
854 : 0 : q_set(void *ptr, PyObject *value, Py_ssize_t size)
855 : : {
856 : : long long val;
857 : : long long x;
858 [ # # ]: 0 : if (get_longlong(value, &val) < 0)
859 : 0 : return NULL;
860 : 0 : memcpy(&x, ptr, sizeof(x));
861 [ # # ]: 0 : x = SET(long long, x, val, size);
862 : 0 : memcpy(ptr, &x, sizeof(x));
863 : 0 : _RET(value);
864 : : }
865 : :
866 : : static PyObject *
867 : 0 : q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
868 : : {
869 : : long long val;
870 : : long long field;
871 [ # # ]: 0 : if (get_longlong(value, &val) < 0) {
872 : 0 : return NULL;
873 : : }
874 : 0 : memcpy(&field, ptr, sizeof(field));
875 : 0 : field = SWAP_LONG_LONG(field);
876 [ # # ]: 0 : field = SET(long long, field, val, size);
877 : 0 : field = SWAP_LONG_LONG(field);
878 : 0 : memcpy(ptr, &field, sizeof(field));
879 : 0 : _RET(value);
880 : : }
881 : :
882 : : static PyObject *
883 : 0 : q_get(void *ptr, Py_ssize_t size)
884 : : {
885 : : long long val;
886 : 0 : memcpy(&val, ptr, sizeof(val));
887 [ # # ]: 0 : GET_BITFIELD(val, size);
888 : 0 : return PyLong_FromLongLong(val);
889 : : }
890 : :
891 : : static PyObject *
892 : 0 : q_get_sw(void *ptr, Py_ssize_t size)
893 : : {
894 : : long long val;
895 : 0 : memcpy(&val, ptr, sizeof(val));
896 : 0 : val = SWAP_LONG_LONG(val);
897 [ # # ]: 0 : GET_BITFIELD(val, size);
898 : 0 : return PyLong_FromLongLong(val);
899 : : }
900 : :
901 : : static PyObject *
902 : 0 : Q_set(void *ptr, PyObject *value, Py_ssize_t size)
903 : : {
904 : : unsigned long long val;
905 : : unsigned long long x;
906 [ # # ]: 0 : if (get_ulonglong(value, &val) < 0)
907 : 0 : return NULL;
908 : 0 : memcpy(&x, ptr, sizeof(x));
909 [ # # ]: 0 : x = SET(long long, x, val, size);
910 : 0 : memcpy(ptr, &x, sizeof(x));
911 : 0 : _RET(value);
912 : : }
913 : :
914 : : static PyObject *
915 : 0 : Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
916 : : {
917 : : unsigned long long val;
918 : : unsigned long long field;
919 [ # # ]: 0 : if (get_ulonglong(value, &val) < 0) {
920 : 0 : return NULL;
921 : : }
922 : 0 : memcpy(&field, ptr, sizeof(field));
923 : 0 : field = SWAP_LONG_LONG(field);
924 [ # # ]: 0 : field = SET(unsigned long long, field, val, size);
925 : 0 : field = SWAP_LONG_LONG(field);
926 : 0 : memcpy(ptr, &field, sizeof(field));
927 : 0 : _RET(value);
928 : : }
929 : :
930 : : static PyObject *
931 : 0 : Q_get(void *ptr, Py_ssize_t size)
932 : : {
933 : : unsigned long long val;
934 : 0 : memcpy(&val, ptr, sizeof(val));
935 [ # # ]: 0 : GET_BITFIELD(val, size);
936 : 0 : return PyLong_FromUnsignedLongLong(val);
937 : : }
938 : :
939 : : static PyObject *
940 : 0 : Q_get_sw(void *ptr, Py_ssize_t size)
941 : : {
942 : : unsigned long long val;
943 : 0 : memcpy(&val, ptr, sizeof(val));
944 : 0 : val = SWAP_LONG_LONG(val);
945 [ # # ]: 0 : GET_BITFIELD(val, size);
946 : 0 : return PyLong_FromUnsignedLongLong(val);
947 : : }
948 : :
949 : : /*****************************************************************
950 : : * non-integer accessor methods, not supporting bit fields
951 : : */
952 : :
953 : :
954 : : static PyObject *
955 : 0 : g_set(void *ptr, PyObject *value, Py_ssize_t size)
956 : : {
957 : : long double x;
958 : :
959 : 0 : x = PyFloat_AsDouble(value);
960 [ # # # # ]: 0 : if (x == -1 && PyErr_Occurred())
961 : 0 : return NULL;
962 : 0 : memcpy(ptr, &x, sizeof(long double));
963 : 0 : _RET(value);
964 : : }
965 : :
966 : : static PyObject *
967 : 0 : g_get(void *ptr, Py_ssize_t size)
968 : : {
969 : : long double val;
970 : 0 : memcpy(&val, ptr, sizeof(long double));
971 : 0 : return PyFloat_FromDouble(val);
972 : : }
973 : :
974 : : static PyObject *
975 : 0 : d_set(void *ptr, PyObject *value, Py_ssize_t size)
976 : : {
977 : : double x;
978 : :
979 : 0 : x = PyFloat_AsDouble(value);
980 [ # # # # ]: 0 : if (x == -1 && PyErr_Occurred())
981 : 0 : return NULL;
982 : 0 : memcpy(ptr, &x, sizeof(double));
983 : 0 : _RET(value);
984 : : }
985 : :
986 : : static PyObject *
987 : 0 : d_get(void *ptr, Py_ssize_t size)
988 : : {
989 : : double val;
990 : 0 : memcpy(&val, ptr, sizeof(val));
991 : 0 : return PyFloat_FromDouble(val);
992 : : }
993 : :
994 : : static PyObject *
995 : 0 : d_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
996 : : {
997 : : double x;
998 : :
999 : 0 : x = PyFloat_AsDouble(value);
1000 [ # # # # ]: 0 : if (x == -1 && PyErr_Occurred())
1001 : 0 : return NULL;
1002 : : #ifdef WORDS_BIGENDIAN
1003 : : if (PyFloat_Pack8(x, ptr, 1))
1004 : : return NULL;
1005 : : #else
1006 [ # # ]: 0 : if (PyFloat_Pack8(x, ptr, 0))
1007 : 0 : return NULL;
1008 : : #endif
1009 : 0 : _RET(value);
1010 : : }
1011 : :
1012 : : static PyObject *
1013 : 0 : d_get_sw(void *ptr, Py_ssize_t size)
1014 : : {
1015 : : #ifdef WORDS_BIGENDIAN
1016 : : return PyFloat_FromDouble(PyFloat_Unpack8(ptr, 1));
1017 : : #else
1018 : 0 : return PyFloat_FromDouble(PyFloat_Unpack8(ptr, 0));
1019 : : #endif
1020 : : }
1021 : :
1022 : : static PyObject *
1023 : 0 : f_set(void *ptr, PyObject *value, Py_ssize_t size)
1024 : : {
1025 : : float x;
1026 : :
1027 : 0 : x = (float)PyFloat_AsDouble(value);
1028 [ # # # # ]: 0 : if (x == -1 && PyErr_Occurred())
1029 : 0 : return NULL;
1030 : 0 : memcpy(ptr, &x, sizeof(x));
1031 : 0 : _RET(value);
1032 : : }
1033 : :
1034 : : static PyObject *
1035 : 0 : f_get(void *ptr, Py_ssize_t size)
1036 : : {
1037 : : float val;
1038 : 0 : memcpy(&val, ptr, sizeof(val));
1039 : 0 : return PyFloat_FromDouble(val);
1040 : : }
1041 : :
1042 : : static PyObject *
1043 : 0 : f_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
1044 : : {
1045 : : float x;
1046 : :
1047 : 0 : x = (float)PyFloat_AsDouble(value);
1048 [ # # # # ]: 0 : if (x == -1 && PyErr_Occurred())
1049 : 0 : return NULL;
1050 : : #ifdef WORDS_BIGENDIAN
1051 : : if (PyFloat_Pack4(x, ptr, 1))
1052 : : return NULL;
1053 : : #else
1054 [ # # ]: 0 : if (PyFloat_Pack4(x, ptr, 0))
1055 : 0 : return NULL;
1056 : : #endif
1057 : 0 : _RET(value);
1058 : : }
1059 : :
1060 : : static PyObject *
1061 : 0 : f_get_sw(void *ptr, Py_ssize_t size)
1062 : : {
1063 : : #ifdef WORDS_BIGENDIAN
1064 : : return PyFloat_FromDouble(PyFloat_Unpack4(ptr, 1));
1065 : : #else
1066 : 0 : return PyFloat_FromDouble(PyFloat_Unpack4(ptr, 0));
1067 : : #endif
1068 : : }
1069 : :
1070 : : /*
1071 : : py_object refcounts:
1072 : :
1073 : : 1. If we have a py_object instance, O_get must Py_INCREF the returned
1074 : : object, of course. If O_get is called from a function result, no py_object
1075 : : instance is created - so callproc.c::GetResult has to call Py_DECREF.
1076 : :
1077 : : 2. The memory block in py_object owns a refcount. So, py_object must call
1078 : : Py_DECREF on destruction. Maybe only when b_needsfree is non-zero.
1079 : : */
1080 : : static PyObject *
1081 : 0 : O_get(void *ptr, Py_ssize_t size)
1082 : : {
1083 : 0 : PyObject *ob = *(PyObject **)ptr;
1084 [ # # ]: 0 : if (ob == NULL) {
1085 [ # # ]: 0 : if (!PyErr_Occurred())
1086 : : /* Set an error if not yet set */
1087 : 0 : PyErr_SetString(PyExc_ValueError,
1088 : : "PyObject is NULL");
1089 : 0 : return NULL;
1090 : : }
1091 : 0 : return Py_NewRef(ob);
1092 : : }
1093 : :
1094 : : static PyObject *
1095 : 0 : O_set(void *ptr, PyObject *value, Py_ssize_t size)
1096 : : {
1097 : : /* Hm, does the memory block need it's own refcount or not? */
1098 : 0 : *(PyObject **)ptr = value;
1099 : 0 : return Py_NewRef(value);
1100 : : }
1101 : :
1102 : :
1103 : : static PyObject *
1104 : 0 : c_set(void *ptr, PyObject *value, Py_ssize_t size)
1105 : : {
1106 [ # # # # ]: 0 : if (PyBytes_Check(value) && PyBytes_GET_SIZE(value) == 1) {
1107 : 0 : *(char *)ptr = PyBytes_AS_STRING(value)[0];
1108 : 0 : _RET(value);
1109 : : }
1110 [ # # # # ]: 0 : if (PyByteArray_Check(value) && PyByteArray_GET_SIZE(value) == 1) {
1111 : 0 : *(char *)ptr = PyByteArray_AS_STRING(value)[0];
1112 : 0 : _RET(value);
1113 : : }
1114 [ # # ]: 0 : if (PyLong_Check(value))
1115 : : {
1116 : 0 : long longval = PyLong_AsLong(value);
1117 [ # # # # ]: 0 : if (longval < 0 || longval >= 256)
1118 : 0 : goto error;
1119 : 0 : *(char *)ptr = (char)longval;
1120 : 0 : _RET(value);
1121 : : }
1122 : 0 : error:
1123 : 0 : PyErr_Format(PyExc_TypeError,
1124 : : "one character bytes, bytearray or integer expected");
1125 : 0 : return NULL;
1126 : : }
1127 : :
1128 : :
1129 : : static PyObject *
1130 : 0 : c_get(void *ptr, Py_ssize_t size)
1131 : : {
1132 : 0 : return PyBytes_FromStringAndSize((char *)ptr, 1);
1133 : : }
1134 : :
1135 : : /* u - a single wchar_t character */
1136 : : static PyObject *
1137 : 0 : u_set(void *ptr, PyObject *value, Py_ssize_t size)
1138 : : {
1139 : : Py_ssize_t len;
1140 : : wchar_t chars[2];
1141 [ # # ]: 0 : if (!PyUnicode_Check(value)) {
1142 : 0 : PyErr_Format(PyExc_TypeError,
1143 : : "unicode string expected instead of %s instance",
1144 : 0 : Py_TYPE(value)->tp_name);
1145 : 0 : return NULL;
1146 : : } else
1147 : 0 : Py_INCREF(value);
1148 : :
1149 : 0 : len = PyUnicode_AsWideChar(value, chars, 2);
1150 [ # # ]: 0 : if (len != 1) {
1151 : 0 : Py_DECREF(value);
1152 : 0 : PyErr_SetString(PyExc_TypeError,
1153 : : "one character unicode string expected");
1154 : 0 : return NULL;
1155 : : }
1156 : :
1157 : 0 : *(wchar_t *)ptr = chars[0];
1158 : 0 : Py_DECREF(value);
1159 : :
1160 : 0 : _RET(value);
1161 : : }
1162 : :
1163 : :
1164 : : static PyObject *
1165 : 0 : u_get(void *ptr, Py_ssize_t size)
1166 : : {
1167 : 0 : return PyUnicode_FromWideChar((wchar_t *)ptr, 1);
1168 : : }
1169 : :
1170 : : /* U - a unicode string */
1171 : : static PyObject *
1172 : 0 : U_get(void *ptr, Py_ssize_t size)
1173 : : {
1174 : : Py_ssize_t len;
1175 : : wchar_t *p;
1176 : :
1177 : 0 : size /= sizeof(wchar_t); /* we count character units here, not bytes */
1178 : :
1179 : : /* We need 'result' to be able to count the characters with wcslen,
1180 : : since ptr may not be NUL terminated. If the length is smaller (if
1181 : : it was actually NUL terminated, we construct a new one and throw
1182 : : away the result.
1183 : : */
1184 : : /* chop off at the first NUL character, if any. */
1185 : 0 : p = (wchar_t*)ptr;
1186 [ # # ]: 0 : for (len = 0; len < size; ++len) {
1187 [ # # ]: 0 : if (!p[len])
1188 : 0 : break;
1189 : : }
1190 : :
1191 : 0 : return PyUnicode_FromWideChar((wchar_t *)ptr, len);
1192 : : }
1193 : :
1194 : : static PyObject *
1195 : 0 : U_set(void *ptr, PyObject *value, Py_ssize_t length)
1196 : : {
1197 : : /* It's easier to calculate in characters than in bytes */
1198 : 0 : length /= sizeof(wchar_t);
1199 : :
1200 [ # # ]: 0 : if (!PyUnicode_Check(value)) {
1201 : 0 : PyErr_Format(PyExc_TypeError,
1202 : : "unicode string expected instead of %s instance",
1203 : 0 : Py_TYPE(value)->tp_name);
1204 : 0 : return NULL;
1205 : : }
1206 : :
1207 : 0 : Py_ssize_t size = PyUnicode_AsWideChar(value, NULL, 0);
1208 [ # # ]: 0 : if (size < 0) {
1209 : 0 : return NULL;
1210 : : }
1211 : : // PyUnicode_AsWideChar() returns number of wchars including trailing null byte,
1212 : : // when it is called with NULL.
1213 : 0 : size--;
1214 : : assert(size >= 0);
1215 [ # # ]: 0 : if (size > length) {
1216 : 0 : PyErr_Format(PyExc_ValueError,
1217 : : "string too long (%zd, maximum length %zd)",
1218 : : size, length);
1219 : 0 : return NULL;
1220 : : }
1221 [ # # ]: 0 : if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, length) == -1) {
1222 : 0 : return NULL;
1223 : : }
1224 : :
1225 : 0 : return Py_NewRef(value);
1226 : : }
1227 : :
1228 : :
1229 : : static PyObject *
1230 : 0 : s_get(void *ptr, Py_ssize_t size)
1231 : : {
1232 : : Py_ssize_t i;
1233 : : char *p;
1234 : :
1235 : 0 : p = (char *)ptr;
1236 [ # # ]: 0 : for (i = 0; i < size; ++i) {
1237 [ # # ]: 0 : if (*p++ == '\0')
1238 : 0 : break;
1239 : : }
1240 : :
1241 : 0 : return PyBytes_FromStringAndSize((char *)ptr, (Py_ssize_t)i);
1242 : : }
1243 : :
1244 : : static PyObject *
1245 : 0 : s_set(void *ptr, PyObject *value, Py_ssize_t length)
1246 : : {
1247 : : const char *data;
1248 : : Py_ssize_t size;
1249 : :
1250 [ # # ]: 0 : if(!PyBytes_Check(value)) {
1251 : 0 : PyErr_Format(PyExc_TypeError,
1252 : : "expected bytes, %s found",
1253 : 0 : Py_TYPE(value)->tp_name);
1254 : 0 : return NULL;
1255 : : }
1256 : :
1257 : 0 : data = PyBytes_AS_STRING(value);
1258 : : // bpo-39593: Use strlen() to truncate the string at the first null character.
1259 : 0 : size = strlen(data);
1260 : :
1261 [ # # ]: 0 : if (size < length) {
1262 : : /* This will copy the terminating NUL character
1263 : : * if there is space for it.
1264 : : */
1265 : 0 : ++size;
1266 [ # # ]: 0 : } else if (size > length) {
1267 : 0 : PyErr_Format(PyExc_ValueError,
1268 : : "bytes too long (%zd, maximum length %zd)",
1269 : : size, length);
1270 : 0 : return NULL;
1271 : : }
1272 : : /* Also copy the terminating NUL character if there is space */
1273 : 0 : memcpy((char *)ptr, data, size);
1274 : :
1275 : 0 : _RET(value);
1276 : : }
1277 : :
1278 : : static PyObject *
1279 : 0 : z_set(void *ptr, PyObject *value, Py_ssize_t size)
1280 : : {
1281 [ # # ]: 0 : if (value == Py_None) {
1282 : 0 : *(char **)ptr = NULL;
1283 : 0 : return Py_NewRef(value);
1284 : : }
1285 [ # # ]: 0 : if (PyBytes_Check(value)) {
1286 : 0 : *(const char **)ptr = PyBytes_AsString(value);
1287 : 0 : return Py_NewRef(value);
1288 [ # # ]: 0 : } else if (PyLong_Check(value)) {
1289 : : #if SIZEOF_VOID_P == SIZEOF_LONG_LONG
1290 : 0 : *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value);
1291 : : #else
1292 : : *(char **)ptr = (char *)PyLong_AsUnsignedLongMask(value);
1293 : : #endif
1294 : 0 : _RET(value);
1295 : : }
1296 : 0 : PyErr_Format(PyExc_TypeError,
1297 : : "bytes or integer address expected instead of %s instance",
1298 : 0 : Py_TYPE(value)->tp_name);
1299 : 0 : return NULL;
1300 : : }
1301 : :
1302 : : static PyObject *
1303 : 0 : z_get(void *ptr, Py_ssize_t size)
1304 : : {
1305 : : /* XXX What about invalid pointers ??? */
1306 [ # # ]: 0 : if (*(void **)ptr) {
1307 : 0 : return PyBytes_FromStringAndSize(*(char **)ptr,
1308 : 0 : strlen(*(char **)ptr));
1309 : : } else {
1310 : 0 : Py_RETURN_NONE;
1311 : : }
1312 : : }
1313 : :
1314 : : static PyObject *
1315 : 0 : Z_set(void *ptr, PyObject *value, Py_ssize_t size)
1316 : : {
1317 : : PyObject *keep;
1318 : : wchar_t *buffer;
1319 : : Py_ssize_t bsize;
1320 : :
1321 [ # # ]: 0 : if (value == Py_None) {
1322 : 0 : *(wchar_t **)ptr = NULL;
1323 : 0 : return Py_NewRef(value);
1324 : : }
1325 [ # # ]: 0 : if (PyLong_Check(value)) {
1326 : : #if SIZEOF_VOID_P == SIZEOF_LONG_LONG
1327 : 0 : *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongLongMask(value);
1328 : : #else
1329 : : *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongMask(value);
1330 : : #endif
1331 : 0 : Py_RETURN_NONE;
1332 : : }
1333 [ # # ]: 0 : if (!PyUnicode_Check(value)) {
1334 : 0 : PyErr_Format(PyExc_TypeError,
1335 : : "unicode string or integer address expected instead of %s instance",
1336 : 0 : Py_TYPE(value)->tp_name);
1337 : 0 : return NULL;
1338 : : }
1339 : :
1340 : : /* We must create a wchar_t* buffer from the unicode object,
1341 : : and keep it alive */
1342 : 0 : buffer = PyUnicode_AsWideCharString(value, &bsize);
1343 [ # # ]: 0 : if (!buffer)
1344 : 0 : return NULL;
1345 : 0 : keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);
1346 [ # # ]: 0 : if (!keep) {
1347 : 0 : PyMem_Free(buffer);
1348 : 0 : return NULL;
1349 : : }
1350 : 0 : *(wchar_t **)ptr = buffer;
1351 : 0 : return keep;
1352 : : }
1353 : :
1354 : : static PyObject *
1355 : 0 : Z_get(void *ptr, Py_ssize_t size)
1356 : : {
1357 : : wchar_t *p;
1358 : 0 : p = *(wchar_t **)ptr;
1359 [ # # ]: 0 : if (p) {
1360 : 0 : return PyUnicode_FromWideChar(p, wcslen(p));
1361 : : } else {
1362 : 0 : Py_RETURN_NONE;
1363 : : }
1364 : : }
1365 : :
1366 : :
1367 : : #ifdef MS_WIN32
1368 : : static PyObject *
1369 : : BSTR_set(void *ptr, PyObject *value, Py_ssize_t size)
1370 : : {
1371 : : BSTR bstr;
1372 : :
1373 : : /* convert value into a PyUnicodeObject or NULL */
1374 : : if (Py_None == value) {
1375 : : value = NULL;
1376 : : } else if (!PyUnicode_Check(value)) {
1377 : : PyErr_Format(PyExc_TypeError,
1378 : : "unicode string expected instead of %s instance",
1379 : : Py_TYPE(value)->tp_name);
1380 : : return NULL;
1381 : : }
1382 : :
1383 : : /* create a BSTR from value */
1384 : : if (value) {
1385 : : Py_ssize_t wsize;
1386 : : wchar_t *wvalue = PyUnicode_AsWideCharString(value, &wsize);
1387 : : if (wvalue == NULL) {
1388 : : return NULL;
1389 : : }
1390 : : if ((unsigned) wsize != wsize) {
1391 : : PyErr_SetString(PyExc_ValueError, "String too long for BSTR");
1392 : : PyMem_Free(wvalue);
1393 : : return NULL;
1394 : : }
1395 : : bstr = SysAllocStringLen(wvalue, (unsigned)wsize);
1396 : : PyMem_Free(wvalue);
1397 : : } else
1398 : : bstr = NULL;
1399 : :
1400 : : /* free the previous contents, if any */
1401 : : if (*(BSTR *)ptr)
1402 : : SysFreeString(*(BSTR *)ptr);
1403 : :
1404 : : /* and store it */
1405 : : *(BSTR *)ptr = bstr;
1406 : :
1407 : : /* We don't need to keep any other object */
1408 : : _RET(value);
1409 : : }
1410 : :
1411 : :
1412 : : static PyObject *
1413 : : BSTR_get(void *ptr, Py_ssize_t size)
1414 : : {
1415 : : BSTR p;
1416 : : p = *(BSTR *)ptr;
1417 : : if (p)
1418 : : return PyUnicode_FromWideChar(p, SysStringLen(p));
1419 : : else {
1420 : : /* Hm, it seems NULL pointer and zero length string are the
1421 : : same in BSTR, see Don Box, p 81
1422 : : */
1423 : : Py_RETURN_NONE;
1424 : : }
1425 : : }
1426 : : #endif
1427 : :
1428 : : static PyObject *
1429 : 0 : P_set(void *ptr, PyObject *value, Py_ssize_t size)
1430 : : {
1431 : : void *v;
1432 [ # # ]: 0 : if (value == Py_None) {
1433 : 0 : *(void **)ptr = NULL;
1434 : 0 : _RET(value);
1435 : : }
1436 : :
1437 [ # # ]: 0 : if (!PyLong_Check(value)) {
1438 : 0 : PyErr_SetString(PyExc_TypeError,
1439 : : "cannot be converted to pointer");
1440 : 0 : return NULL;
1441 : : }
1442 : :
1443 : : #if SIZEOF_VOID_P <= SIZEOF_LONG
1444 : 0 : v = (void *)PyLong_AsUnsignedLongMask(value);
1445 : : #else
1446 : : #if SIZEOF_LONG_LONG < SIZEOF_VOID_P
1447 : : # error "PyLong_AsVoidPtr: sizeof(long long) < sizeof(void*)"
1448 : : #endif
1449 : : v = (void *)PyLong_AsUnsignedLongLongMask(value);
1450 : : #endif
1451 : :
1452 [ # # ]: 0 : if (PyErr_Occurred())
1453 : 0 : return NULL;
1454 : :
1455 : 0 : *(void **)ptr = v;
1456 : 0 : _RET(value);
1457 : : }
1458 : :
1459 : : static PyObject *
1460 : 0 : P_get(void *ptr, Py_ssize_t size)
1461 : : {
1462 [ # # ]: 0 : if (*(void **)ptr == NULL) {
1463 : 0 : Py_RETURN_NONE;
1464 : : }
1465 : 0 : return PyLong_FromVoidPtr(*(void **)ptr);
1466 : : }
1467 : :
1468 : : static struct fielddesc formattable[] = {
1469 : : { 's', s_set, s_get, NULL},
1470 : : { 'b', b_set, b_get, NULL},
1471 : : { 'B', B_set, B_get, NULL},
1472 : : { 'c', c_set, c_get, NULL},
1473 : : { 'd', d_set, d_get, NULL, d_set_sw, d_get_sw},
1474 : : { 'g', g_set, g_get, NULL},
1475 : : { 'f', f_set, f_get, NULL, f_set_sw, f_get_sw},
1476 : : { 'h', h_set, h_get, NULL, h_set_sw, h_get_sw},
1477 : : { 'H', H_set, H_get, NULL, H_set_sw, H_get_sw},
1478 : : { 'i', i_set, i_get, NULL, i_set_sw, i_get_sw},
1479 : : { 'I', I_set, I_get, NULL, I_set_sw, I_get_sw},
1480 : : { 'l', l_set, l_get, NULL, l_set_sw, l_get_sw},
1481 : : { 'L', L_set, L_get, NULL, L_set_sw, L_get_sw},
1482 : : { 'q', q_set, q_get, NULL, q_set_sw, q_get_sw},
1483 : : { 'Q', Q_set, Q_get, NULL, Q_set_sw, Q_get_sw},
1484 : : { 'P', P_set, P_get, NULL},
1485 : : { 'z', z_set, z_get, NULL},
1486 : : { 'u', u_set, u_get, NULL},
1487 : : { 'U', U_set, U_get, NULL},
1488 : : { 'Z', Z_set, Z_get, NULL},
1489 : : #ifdef MS_WIN32
1490 : : { 'X', BSTR_set, BSTR_get, NULL},
1491 : : #endif
1492 : : { 'v', vBOOL_set, vBOOL_get, NULL},
1493 : : #if SIZEOF__BOOL == SIZEOF_INT
1494 : : { '?', bool_set, bool_get, NULL, I_set_sw, I_get_sw},
1495 : : #elif SIZEOF__BOOL == SIZEOF_LONG
1496 : : { '?', bool_set, bool_get, NULL, L_set_sw, L_get_sw},
1497 : : #elif SIZEOF__BOOL == SIZEOF_LONG_LONG
1498 : : { '?', bool_set, bool_get, NULL, Q_set_sw, Q_get_sw},
1499 : : #else
1500 : : { '?', bool_set, bool_get, NULL},
1501 : : #endif /* SIZEOF__BOOL */
1502 : : { 'O', O_set, O_get, NULL},
1503 : : { 0, NULL, NULL, NULL},
1504 : : };
1505 : :
1506 : : /*
1507 : : Ideas: Implement VARIANT in this table, using 'V' code.
1508 : : Use '?' as code for BOOL.
1509 : : */
1510 : :
1511 : : /* Delayed initialization. Windows cannot statically reference dynamically
1512 : : loaded addresses from DLLs. */
1513 : : void
1514 : 1 : _ctypes_init_fielddesc(void)
1515 : : {
1516 : 1 : struct fielddesc *fd = formattable;
1517 [ + + ]: 24 : for (; fd->code; ++fd) {
1518 [ + + + + : 23 : switch (fd->code) {
+ + + + +
+ + + + +
+ + + + +
+ + + +
- ]
1519 : 1 : case 's': fd->pffi_type = &ffi_type_pointer; break;
1520 : 1 : case 'b': fd->pffi_type = &ffi_type_schar; break;
1521 : 1 : case 'B': fd->pffi_type = &ffi_type_uchar; break;
1522 : 1 : case 'c': fd->pffi_type = &ffi_type_schar; break;
1523 : 1 : case 'd': fd->pffi_type = &ffi_type_double; break;
1524 : 1 : case 'g': fd->pffi_type = &ffi_type_longdouble; break;
1525 : 1 : case 'f': fd->pffi_type = &ffi_type_float; break;
1526 : 1 : case 'h': fd->pffi_type = &ffi_type_sshort; break;
1527 : 1 : case 'H': fd->pffi_type = &ffi_type_ushort; break;
1528 : 1 : case 'i': fd->pffi_type = &ffi_type_sint; break;
1529 : 1 : case 'I': fd->pffi_type = &ffi_type_uint; break;
1530 : : /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */
1531 : : /* As soon as we can get rid of the type codes, this is no longer a problem */
1532 : : #if SIZEOF_LONG == 4
1533 : : case 'l': fd->pffi_type = &ffi_type_sint32; break;
1534 : : case 'L': fd->pffi_type = &ffi_type_uint32; break;
1535 : : #elif SIZEOF_LONG == 8
1536 : 1 : case 'l': fd->pffi_type = &ffi_type_sint64; break;
1537 : 1 : case 'L': fd->pffi_type = &ffi_type_uint64; break;
1538 : : #else
1539 : : #error
1540 : : #endif
1541 : : #if SIZEOF_LONG_LONG == 8
1542 : 1 : case 'q': fd->pffi_type = &ffi_type_sint64; break;
1543 : 1 : case 'Q': fd->pffi_type = &ffi_type_uint64; break;
1544 : : #else
1545 : : #error
1546 : : #endif
1547 : 1 : case 'P': fd->pffi_type = &ffi_type_pointer; break;
1548 : 1 : case 'z': fd->pffi_type = &ffi_type_pointer; break;
1549 : 1 : case 'u':
1550 : : if (sizeof(wchar_t) == sizeof(short))
1551 : : fd->pffi_type = &ffi_type_sshort;
1552 : : else if (sizeof(wchar_t) == sizeof(int))
1553 : 1 : fd->pffi_type = &ffi_type_sint;
1554 : : else if (sizeof(wchar_t) == sizeof(long))
1555 : : fd->pffi_type = &ffi_type_slong;
1556 : : else
1557 : : Py_UNREACHABLE();
1558 : 1 : break;
1559 : 1 : case 'U': fd->pffi_type = &ffi_type_pointer; break;
1560 : 1 : case 'Z': fd->pffi_type = &ffi_type_pointer; break;
1561 : : #ifdef MS_WIN32
1562 : : case 'X': fd->pffi_type = &ffi_type_pointer; break;
1563 : : #endif
1564 : 1 : case 'v': fd->pffi_type = &ffi_type_sshort; break;
1565 : : #if SIZEOF__BOOL == 1
1566 : 1 : case '?': fd->pffi_type = &ffi_type_uchar; break; /* Also fallback for no native _Bool support */
1567 : : #elif SIZEOF__BOOL == SIZEOF_SHORT
1568 : : case '?': fd->pffi_type = &ffi_type_ushort; break;
1569 : : #elif SIZEOF__BOOL == SIZEOF_INT
1570 : : case '?': fd->pffi_type = &ffi_type_uint; break;
1571 : : #elif SIZEOF__BOOL == SIZEOF_LONG
1572 : : case '?': fd->pffi_type = &ffi_type_ulong; break;
1573 : : #elif SIZEOF__BOOL == SIZEOF_LONG_LONG
1574 : : case '?': fd->pffi_type = &ffi_type_ulong; break;
1575 : : #endif /* SIZEOF__BOOL */
1576 : 1 : case 'O': fd->pffi_type = &ffi_type_pointer; break;
1577 : 0 : default:
1578 : 0 : Py_UNREACHABLE();
1579 : : }
1580 : : }
1581 : :
1582 : 1 : }
1583 : :
1584 : : struct fielddesc *
1585 : 28 : _ctypes_get_fielddesc(const char *fmt)
1586 : : {
1587 : : static int initialized = 0;
1588 : 28 : struct fielddesc *table = formattable;
1589 : :
1590 [ + + ]: 28 : if (!initialized) {
1591 : 1 : initialized = 1;
1592 : 1 : _ctypes_init_fielddesc();
1593 : : }
1594 : :
1595 [ + - ]: 366 : for (; table->code; ++table) {
1596 [ + + ]: 366 : if (table->code == fmt[0])
1597 : 28 : return table;
1598 : : }
1599 : 0 : return NULL;
1600 : : }
1601 : :
1602 : : /*---------------- EOF ----------------*/
|