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