1import sys 2from ctypes import * 3 4_array_type = type(Array) 5 6def _other_endian(typ): 7 """Return the type with the 'other' byte order. Simple types like 8 c_int and so on already have __ctype_be__ and __ctype_le__ 9 attributes which contain the types, for more complicated types 10 arrays and structures are supported. 11 """ 12 # check _OTHER_ENDIAN attribute (present if typ is primitive type) 13 if hasattr(typ, _OTHER_ENDIAN): 14 return getattr(typ, _OTHER_ENDIAN) 15 # if typ is array 16 if isinstance(typ, _array_type): 17 return _other_endian(typ._type_) * typ._length_ 18 # if typ is structure 19 if issubclass(typ, Structure): 20 return typ 21 raise TypeError("This type does not support other endian: %s" % typ) 22 23class _swapped_meta: 24 def __setattr__(self, attrname, value): 25 if attrname == "_fields_": 26 fields = [] 27 for desc in value: 28 name = desc[0] 29 typ = desc[1] 30 rest = desc[2:] 31 fields.append((name, _other_endian(typ)) + rest) 32 value = fields 33 super().__setattr__(attrname, value) 34class _swapped_struct_meta(_swapped_meta, type(Structure)): pass 35class _swapped_union_meta(_swapped_meta, type(Union)): pass 36 37################################################################ 38 39# Note: The Structure metaclass checks for the *presence* (not the 40# value!) of a _swapped_bytes_ attribute to determine the bit order in 41# structures containing bit fields. 42 43if sys.byteorder == "little": 44 _OTHER_ENDIAN = "__ctype_be__" 45 46 LittleEndianStructure = Structure 47 48 class BigEndianStructure(Structure, metaclass=_swapped_struct_meta): 49 """Structure with big endian byte order""" 50 __slots__ = () 51 _swappedbytes_ = None 52 53 LittleEndianUnion = Union 54 55 class BigEndianUnion(Union, metaclass=_swapped_union_meta): 56 """Union with big endian byte order""" 57 __slots__ = () 58 _swappedbytes_ = None 59 60elif sys.byteorder == "big": 61 _OTHER_ENDIAN = "__ctype_le__" 62 63 BigEndianStructure = Structure 64 65 class LittleEndianStructure(Structure, metaclass=_swapped_struct_meta): 66 """Structure with little endian byte order""" 67 __slots__ = () 68 _swappedbytes_ = None 69 70 BigEndianUnion = Union 71 72 class LittleEndianUnion(Union, metaclass=_swapped_union_meta): 73 """Union with little endian byte order""" 74 __slots__ = () 75 _swappedbytes_ = None 76 77else: 78 raise RuntimeError("Invalid byteorder") 79