[ctypes-commit] ctypes/source ctypes.h,1.74.2.6,1.74.2.7 cfield.c,1.74.2.7,1.74.2.8 _ctypes.c,1.226.
Brought to you by:
theller
From: Thomas H. <th...@us...> - 2005-11-29 20:15:28
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12399 Modified Files: Tag: branch_1_0 ctypes.h cfield.c _ctypes.c Log Message: Implement simple data types with different byte order (endian). Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.74.2.6 retrieving revision 1.74.2.7 diff -C2 -d -r1.74.2.6 -r1.74.2.7 *** ctypes.h 11 Nov 2005 08:10:26 -0000 1.74.2.6 --- ctypes.h 29 Nov 2005 20:15:17 -0000 1.74.2.7 *************** *** 159,162 **** --- 159,164 ---- GETFUNC getfunc; ffi_type *pffi_type; /* always statically allocated */ + SETFUNC setfunc_swapped; + GETFUNC getfunc_swapped; }; Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.74.2.7 retrieving revision 1.74.2.8 diff -C2 -d -r1.74.2.7 -r1.74.2.8 *** cfield.c 14 Nov 2005 18:43:31 -0000 1.74.2.7 --- cfield.c 29 Nov 2005 20:15:17 -0000 1.74.2.8 *************** *** 420,423 **** --- 420,451 ---- : v) + /* byte swapping macros */ + #define SWAP_2(v) \ + ( ( (v >> 8) & 0x00FF) | \ + ( (v << 8) & 0xFF00) ) + + #define SWAP_4(v) \ + ( ( (v & 0x000000FF) << 24 ) | \ + ( (v & 0x0000FF00) << 8 ) | \ + ( (v & 0x00FF0000) >> 8 ) | \ + ( ((v >> 24) & 0xFF)) ) + + #define SWAP_8(v) \ + ( ( (v & 0x00000000000000FF) << 56 ) | \ + ( (v & 0x000000000000FF00) << 40 ) | \ + ( (v & 0x0000000000FF0000) << 24 ) | \ + ( (v & 0x00000000FF000000) << 8 ) | \ + ( (v & 0x000000FF00000000) >> 8 ) | \ + ( (v & 0x0000FF0000000000) >> 24 ) | \ + ( (v & 0x00FF000000000000) >> 40 ) | \ + ( ((v >> 56) & 0xFF)) ) + + #define SWAP_INT SWAP_4 + + #if SIZEOF_LONG == 4 + # define SWAP_LONG SWAP_4 + #elif SIZEOF_LONG == 8 + # define SWAP_LONG SWAP_4 + #endif /***************************************************************** * The setter methods return an object which must be kept alive, to keep the *************** *** 495,498 **** --- 523,539 ---- static PyObject * + h_set_sw(void *ptr, PyObject *value, unsigned size) + { + long val; + short field; + if (get_long(value, &val) < 0) + return NULL; + field = SWAP_2(*(short *)ptr); + field = SET(field, (short)val, size); + *(short *)ptr = SWAP_2(field); + _RET(value); + } + + static PyObject * h_get(void *ptr, unsigned size) { *************** *** 503,506 **** --- 544,556 ---- static PyObject * + h_get_sw(void *ptr, unsigned size) + { + short val = *(short *)ptr; + val = SWAP_2(val); + GET_BITFIELD(val, size); + return PyInt_FromLong(val); + } + + static PyObject * H_set(void *ptr, PyObject *value, unsigned size) { *************** *** 513,521 **** } static PyObject * H_get(void *ptr, unsigned size) { ! unsigned short val = *(short *)ptr; GET_BITFIELD(val, size); return PyInt_FromLong(val); --- 563,593 ---- } + static PyObject * + H_set_sw(void *ptr, PyObject *value, unsigned size) + { + unsigned long val; + unsigned short field; + if (get_ulong(value, &val) < 0) + return NULL; + field = SWAP_2(*(unsigned short *)ptr); + field = SET(field, (unsigned short)val, size); + *(unsigned short *)ptr = SWAP_2(field); + _RET(value); + } + static PyObject * H_get(void *ptr, unsigned size) { ! unsigned short val = *(unsigned short *)ptr; ! GET_BITFIELD(val, size); ! return PyInt_FromLong(val); ! } ! ! static PyObject * ! H_get_sw(void *ptr, unsigned size) ! { ! unsigned short val = *(unsigned short *)ptr; ! val = SWAP_2(val); GET_BITFIELD(val, size); return PyInt_FromLong(val); *************** *** 532,535 **** --- 604,620 ---- } + static PyObject * + i_set_sw(void *ptr, PyObject *value, unsigned size) + { + long val; + int field; + if (get_long(value, &val) < 0) + return NULL; + field = SWAP_INT(*(int *)ptr); + field = SET(field, (int)val, size); + *(int *)ptr = SWAP_INT(field); + _RET(value); + } + static PyObject * *************** *** 541,544 **** --- 626,638 ---- } + static PyObject * + i_get_sw(void *ptr, unsigned size) + { + int val = *(int *)ptr; + val = SWAP_INT(val); + GET_BITFIELD(val, size); + return PyInt_FromLong(val); + } + #ifdef MS_WIN32 /* short BOOL - VARIANT_BOOL */ *************** *** 575,578 **** --- 669,685 ---- } + static PyObject * + I_set_sw(void *ptr, PyObject *value, unsigned size) + { + unsigned long val; + unsigned int field; + if (get_ulong(value, &val) < 0) + return NULL; + field = SWAP_INT(*(unsigned int *)val); + field = (unsigned int)SET(field, (unsigned int)val, size); + *(unsigned int *)ptr = field; + _RET(value); + } + static PyObject * *************** *** 585,588 **** --- 692,704 ---- static PyObject * + I_get_sw(void *ptr, unsigned size) + { + unsigned int val = *(unsigned int *)ptr; + val = SWAP_INT(val); + GET_BITFIELD(val, size); + return PyLong_FromUnsignedLong(val); + } + + static PyObject * l_set(void *ptr, PyObject *value, unsigned size) { *************** *** 594,597 **** --- 710,726 ---- } + static PyObject * + l_set_sw(void *ptr, PyObject *value, unsigned size) + { + long val; + long field; + if (get_long(value, &val) < 0) + return NULL; + field = *(long *)ptr; + field = (long)SET(field, val, size); + *(long *)ptr = SWAP_INT(field); + _RET(value); + } + static PyObject * *************** *** 604,607 **** --- 733,745 ---- static PyObject * + l_get_sw(void *ptr, unsigned size) + { + long val = *(long *)ptr; + val = SWAP_INT(val); + GET_BITFIELD(val, size); + return PyInt_FromLong(val); + } + + static PyObject * L_set(void *ptr, PyObject *value, unsigned size) { *************** *** 613,616 **** --- 751,767 ---- } + static PyObject * + L_set_sw(void *ptr, PyObject *value, unsigned size) + { + unsigned long val; + unsigned long field; + if (get_ulong(value, &val) < 0) + return NULL; + field = SWAP_LONG(*(unsigned long *)ptr); + field = (unsigned long)SET(field, val, size); + *(unsigned long *)ptr = SWAP_LONG(field); + _RET(value); + } + static PyObject * *************** *** 622,625 **** --- 773,785 ---- } + static PyObject * + L_get_sw(void *ptr, unsigned size) + { + unsigned long val = *(unsigned long *)ptr; + val = SWAP_LONG(val); + GET_BITFIELD(val, size); + return PyLong_FromUnsignedLong(val); + } + #ifdef HAVE_LONG_LONG static PyObject * *************** *** 634,637 **** --- 794,810 ---- static PyObject * + q_set_sw(void *ptr, PyObject *value, unsigned size) + { + PY_LONG_LONG val; + PY_LONG_LONG field; + if (get_longlong(value, &val) < 0) + return NULL; + field = SWAP_8(*(PY_LONG_LONG *)ptr); + field = (PY_LONG_LONG)SET(field, val, size); + *(PY_LONG_LONG *)ptr = SWAP_8(field); + _RET(value); + } + + static PyObject * q_get(void *ptr, unsigned size) { *************** *** 642,645 **** --- 815,827 ---- static PyObject * + q_get_sw(void *ptr, unsigned size) + { + PY_LONG_LONG val = *(PY_LONG_LONG *)ptr; + val = SWAP_8(val); + GET_BITFIELD(val, size); + return PyLong_FromLongLong(val); + } + + static PyObject * Q_set(void *ptr, PyObject *value, unsigned size) { *************** *** 652,655 **** --- 834,850 ---- static PyObject * + Q_set_sw(void *ptr, PyObject *value, unsigned size) + { + unsigned PY_LONG_LONG val; + unsigned PY_LONG_LONG field; + if (get_ulonglong(value, &val) < 0) + return NULL; + field = SWAP_8(*(unsigned PY_LONG_LONG *)ptr); + field = (unsigned PY_LONG_LONG)SET(field, val, size); + *(unsigned PY_LONG_LONG *)ptr = SWAP_8(field); + _RET(value); + } + + static PyObject * Q_get(void *ptr, unsigned size) { *************** *** 658,661 **** --- 853,865 ---- return PyLong_FromUnsignedLongLong(val); } + + static PyObject * + Q_get_sw(void *ptr, unsigned size) + { + unsigned PY_LONG_LONG val = *(unsigned PY_LONG_LONG *)ptr; + val = SWAP_8(val); + GET_BITFIELD(val, size); + return PyLong_FromUnsignedLongLong(val); + } #endif *************** *** 1136,1159 **** { 'B', B_set, B_get, &ffi_type_uchar}, { 'c', c_set, c_get, &ffi_type_schar}, ! { 'd', d_set, d_get, &ffi_type_double}, ! { 'f', f_set, f_get, &ffi_type_float}, ! { 'h', h_set, h_get, &ffi_type_sshort}, ! { 'H', H_set, H_get, &ffi_type_ushort}, ! { 'i', i_set, i_get, &ffi_type_sint}, ! { 'I', I_set, I_get, &ffi_type_uint}, /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ /* As soon as we can get rid of the type codes, this is no longer a problem */ #if SIZEOF_LONG == 4 ! { 'l', l_set, l_get, &ffi_type_sint}, ! { 'L', L_set, L_get, &ffi_type_uint}, #elif SIZEOF_LONG == 8 ! { 'l', l_set, l_get, &ffi_type_slong}, ! { 'L', L_set, L_get, &ffi_type_ulong}, #else # error #endif #ifdef HAVE_LONG_LONG ! { 'q', q_set, q_get, &ffi_type_slong}, ! { 'Q', Q_set, Q_get, &ffi_type_ulong}, #endif { 'P', P_set, P_get, &ffi_type_pointer}, --- 1340,1363 ---- { 'B', B_set, B_get, &ffi_type_uchar}, { 'c', c_set, c_get, &ffi_type_schar}, ! { 'd', d_set, d_get, &ffi_type_double/*, d_set_sw, d_get_sw*/}, ! { 'f', f_set, f_get, &ffi_type_float/*, f_set_sw, f_get_sw*/}, ! { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw}, ! { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw}, ! { 'i', i_set, i_get, &ffi_type_sint, i_set_sw, i_get_sw}, ! { 'I', I_set, I_get, &ffi_type_uint, I_set_sw, I_get_sw}, /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ /* As soon as we can get rid of the type codes, this is no longer a problem */ #if SIZEOF_LONG == 4 ! { 'l', l_set, l_get, &ffi_type_sint, l_set_sw, l_get_sw}, ! { 'L', L_set, L_get, &ffi_type_uint, L_set_sw, L_get_sw}, #elif SIZEOF_LONG == 8 ! { 'l', l_set, l_get, &ffi_type_slong, l_set_sw, l_get_sw}, ! { 'L', L_set, L_get, &ffi_type_ulong, L_set_sw, L_get_sw}, #else # error #endif #ifdef HAVE_LONG_LONG ! { 'q', q_set, q_get, &ffi_type_slong, q_set_sw, q_get_sw}, ! { 'Q', Q_set, Q_get, &ffi_type_ulong, Q_set_sw, Q_get_sw}, #endif { 'P', P_set, P_get, &ffi_type_pointer}, Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.226.2.36 retrieving revision 1.226.2.37 diff -C2 -d -r1.226.2.36 -r1.226.2.37 *** _ctypes.c 8 Nov 2005 20:34:23 -0000 1.226.2.36 --- _ctypes.c 29 Nov 2005 20:15:17 -0000 1.226.2.37 *************** *** 1230,1233 **** --- 1230,1295 ---- #endif + static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds, + PyObject *proto, struct fielddesc *fmt) + { + PyTypeObject *result; + StgDictObject *stgdict; + PyObject *name = PyTuple_GET_ITEM(args, 0); + PyObject *swapped_args = PyTuple_New(PyTuple_GET_SIZE(args)); + static PyObject *suffix; + int i; + + if (suffix == NULL) + #ifdef IS_BIG_ENDIAN + suffix = PyString_FromString("_le"); + #else + suffix = PyString_FromString("_be"); + #endif + + Py_INCREF(suffix); + PyString_ConcatAndDel(&name, suffix); + + PyTuple_SET_ITEM(swapped_args, 0, name); + for (i=1; i<PyTuple_GET_SIZE(args); ++i) { + PyObject *v = PyTuple_GET_ITEM(args, i); + Py_INCREF(v); + PyTuple_SET_ITEM(swapped_args, i, v); + } + + /* create the new instance (which is a class, + since we are a metatype!) */ + result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds); + Py_DECREF(swapped_args); + if (result == NULL) + return NULL; + + stgdict = (StgDictObject *)PyObject_CallObject( + (PyObject *)&StgDict_Type, NULL); + if (!stgdict) /* XXX leaks result! */ + return NULL; + + stgdict->ffi_type = *fmt->pffi_type; + stgdict->align = fmt->pffi_type->alignment; + stgdict->length = 0; + stgdict->size = fmt->pffi_type->size; + stgdict->setfunc = fmt->setfunc_swapped; + stgdict->getfunc = fmt->getfunc_swapped; + + Py_INCREF(proto); + stgdict->proto = proto; + + /* replace the class dict by our updated spam dict */ + if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { + Py_DECREF(result); + Py_DECREF((PyObject *)stgdict); + return NULL; + } + Py_DECREF(result->tp_dict); + result->tp_dict = (PyObject *)stgdict; + + return (PyObject *)result; + } + + static PyObject * SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) *************** *** 1341,1344 **** --- 1403,1427 ---- } } + + if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { + PyObject *swapped = CreateSwappedType(type, args, kwds, + proto, fmt); + if (swapped == NULL) { + Py_DECREF(result); + return NULL; + } + #ifdef IS_BIG_ENDIAN + PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped); + PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result); + PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result); + PyObject_SetAttrString(swapped, "__ctype_le__", swapped); + #else + PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped); + PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result); + PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result); + PyObject_SetAttrString(swapped, "__ctype_be__", swapped); + #endif + }; + return (PyObject *)result; } |