10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi###################################################################### 20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# This file should be kept compatible with Python 2.3, see PEP 291. # 30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi###################################################################### 40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sys 50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom ctypes import * 60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_array_type = type(Array) 80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _other_endian(typ): 100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Return the type with the 'other' byte order. Simple types like 110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c_int and so on already have __ctype_be__ and __ctype_le__ 120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi attributes which contain the types, for more complicated types 130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi arrays and structures are supported. 140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """ 150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # check _OTHER_ENDIAN attribute (present if typ is primitive type) 160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if hasattr(typ, _OTHER_ENDIAN): 170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return getattr(typ, _OTHER_ENDIAN) 180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if typ is array 190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if isinstance(typ, _array_type): 200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return _other_endian(typ._type_) * typ._length_ 210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # if typ is structure 220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if issubclass(typ, Structure): 230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return typ 240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise TypeError("This type does not support other endian: %s" % typ) 250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass _swapped_meta(type(Structure)): 270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def __setattr__(self, attrname, value): 280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if attrname == "_fields_": 290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fields = [] 300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for desc in value: 310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi name = desc[0] 320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi typ = desc[1] 330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi rest = desc[2:] 340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fields.append((name, _other_endian(typ)) + rest) 350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value = fields 360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi super(_swapped_meta, self).__setattr__(attrname, value) 370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi################################################################ 390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Note: The Structure metaclass checks for the *presence* (not the 410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# value!) of a _swapped_bytes_ attribute to determine the bit order in 420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# structures containing bit fields. 430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif sys.byteorder == "little": 450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _OTHER_ENDIAN = "__ctype_be__" 460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi LittleEndianStructure = Structure 480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi class BigEndianStructure(Structure): 500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Structure with big endian byte order""" 510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __metaclass__ = _swapped_meta 520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _swappedbytes_ = None 530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yielif sys.byteorder == "big": 550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _OTHER_ENDIAN = "__ctype_le__" 560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi BigEndianStructure = Structure 580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi class LittleEndianStructure(Structure): 590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Structure with little endian byte order""" 600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi __metaclass__ = _swapped_meta 610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi _swappedbytes_ = None 620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yielse: 640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise RuntimeError("Invalid byteorder") 65