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