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