blob: 721b0d1c9e3092350ebd860a6666e8e9c80cd8c6 [file] [log] [blame]
Thomas Hellerbabddfc2006-03-08 19:56:54 +00001import sys
2from ctypes import *
3
4_array_type = type(c_int * 3)
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
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"""
Thomas Hellerbabddfc2006-03-08 19:56:54 +000048 _swappedbytes_ = None
49
50elif sys.byteorder == "big":
51 _OTHER_ENDIAN = "__ctype_le__"
52
53 BigEndianStructure = Structure
Guido van Rossum52cc1d82007-03-18 15:41:51 +000054 class LittleEndianStructure(Structure, metaclass=_swapped_meta):
Thomas Hellerbabddfc2006-03-08 19:56:54 +000055 """Structure with little endian byte order"""
Thomas Hellerbabddfc2006-03-08 19:56:54 +000056 _swappedbytes_ = None
57
58else:
59 raise RuntimeError("Invalid byteorder")