blob: 37444bd6a7dd60263d2833312643b02c899776ea [file] [log] [blame]
Thomas Hellerbabddfc2006-03-08 19:56:54 +00001import sys
2from ctypes import *
3
Meador Inge8582bb12012-02-04 20:36:48 -06004_array_type = type(Array)
Thomas Hellerbabddfc2006-03-08 19:56:54 +00005
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
Victor Stinner66361212011-07-13 21:43:18 +020010 arrays and structures are supported.
Thomas Hellerbabddfc2006-03-08 19:56:54 +000011 """
Victor Stinner66361212011-07-13 21:43:18 +020012 # check _OTHER_ENDIAN attribute (present if typ is primitive type)
13 if hasattr(typ, _OTHER_ENDIAN):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000014 return getattr(typ, _OTHER_ENDIAN)
Victor Stinner66361212011-07-13 21:43:18 +020015 # 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)
Thomas Hellerbabddfc2006-03-08 19:56:54 +000022
23class _swapped_meta(type(Structure)):
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
Guido van Rossumcd16bf62007-06-13 18:07:49 +000033 super().__setattr__(attrname, value)
Thomas Hellerbabddfc2006-03-08 19:56:54 +000034
35################################################################
36
37# Note: The Structure metaclass checks for the *presence* (not the
38# value!) of a _swapped_bytes_ attribute to determine the bit order in
39# structures containing bit fields.
40
41if sys.byteorder == "little":
42 _OTHER_ENDIAN = "__ctype_be__"
43
44 LittleEndianStructure = Structure
45
Guido van Rossum52cc1d82007-03-18 15:41:51 +000046 class BigEndianStructure(Structure, metaclass=_swapped_meta):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000047 """Structure with big endian byte order"""
Antoine Pitrou5ce8f352014-08-30 00:37:18 +020048 __slots__ = ()
Thomas Hellerbabddfc2006-03-08 19:56:54 +000049 _swappedbytes_ = None
50
51elif sys.byteorder == "big":
52 _OTHER_ENDIAN = "__ctype_le__"
53
54 BigEndianStructure = Structure
Guido van Rossum52cc1d82007-03-18 15:41:51 +000055 class LittleEndianStructure(Structure, metaclass=_swapped_meta):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000056 """Structure with little endian byte order"""
Antoine Pitrou5ce8f352014-08-30 00:37:18 +020057 __slots__ = ()
Thomas Hellerbabddfc2006-03-08 19:56:54 +000058 _swappedbytes_ = None
59
60else:
61 raise RuntimeError("Invalid byteorder")