1
import sys, unittest, struct, math
2
from binascii import hexlify
7
return hexlify(memoryview(s)).decode().upper()
9
# Each *simple* type that supports different byte orders has an
10
# __ctype_be__ attribute that specifies the same type in BIG ENDIAN
11
# byte order, and a __ctype_le__ attribute that is the same type in
12
# LITTLE ENDIAN byte order.
14
# For Structures and Unions, these types are created on demand.
16
class Test(unittest.TestCase):
18
print(sys.byteorder, file=sys.stderr)
21
setattr(bits, "i%s" % i, 1)
24
def test_endian_short(self):
25
if sys.byteorder == "little":
26
self.failUnless(c_short.__ctype_le__ is c_short)
27
self.failUnless(c_short.__ctype_be__.__ctype_le__ is c_short)
29
self.failUnless(c_short.__ctype_be__ is c_short)
30
self.failUnless(c_short.__ctype_le__.__ctype_be__ is c_short)
31
s = c_short.__ctype_be__(0x1234)
32
self.failUnlessEqual(bin(struct.pack(">h", 0x1234)), "1234")
33
self.failUnlessEqual(bin(s), "1234")
34
self.failUnlessEqual(s.value, 0x1234)
36
s = c_short.__ctype_le__(0x1234)
37
self.failUnlessEqual(bin(struct.pack("<h", 0x1234)), "3412")
38
self.failUnlessEqual(bin(s), "3412")
39
self.failUnlessEqual(s.value, 0x1234)
41
s = c_ushort.__ctype_be__(0x1234)
42
self.failUnlessEqual(bin(struct.pack(">h", 0x1234)), "1234")
43
self.failUnlessEqual(bin(s), "1234")
44
self.failUnlessEqual(s.value, 0x1234)
46
s = c_ushort.__ctype_le__(0x1234)
47
self.failUnlessEqual(bin(struct.pack("<h", 0x1234)), "3412")
48
self.failUnlessEqual(bin(s), "3412")
49
self.failUnlessEqual(s.value, 0x1234)
51
def test_endian_int(self):
52
if sys.byteorder == "little":
53
self.failUnless(c_int.__ctype_le__ is c_int)
54
self.failUnless(c_int.__ctype_be__.__ctype_le__ is c_int)
56
self.failUnless(c_int.__ctype_be__ is c_int)
57
self.failUnless(c_int.__ctype_le__.__ctype_be__ is c_int)
59
s = c_int.__ctype_be__(0x12345678)
60
self.failUnlessEqual(bin(struct.pack(">i", 0x12345678)), "12345678")
61
self.failUnlessEqual(bin(s), "12345678")
62
self.failUnlessEqual(s.value, 0x12345678)
64
s = c_int.__ctype_le__(0x12345678)
65
self.failUnlessEqual(bin(struct.pack("<i", 0x12345678)), "78563412")
66
self.failUnlessEqual(bin(s), "78563412")
67
self.failUnlessEqual(s.value, 0x12345678)
69
s = c_uint.__ctype_be__(0x12345678)
70
self.failUnlessEqual(bin(struct.pack(">I", 0x12345678)), "12345678")
71
self.failUnlessEqual(bin(s), "12345678")
72
self.failUnlessEqual(s.value, 0x12345678)
74
s = c_uint.__ctype_le__(0x12345678)
75
self.failUnlessEqual(bin(struct.pack("<I", 0x12345678)), "78563412")
76
self.failUnlessEqual(bin(s), "78563412")
77
self.failUnlessEqual(s.value, 0x12345678)
79
def test_endian_longlong(self):
80
if sys.byteorder == "little":
81
self.failUnless(c_longlong.__ctype_le__ is c_longlong)
82
self.failUnless(c_longlong.__ctype_be__.__ctype_le__ is c_longlong)
84
self.failUnless(c_longlong.__ctype_be__ is c_longlong)
85
self.failUnless(c_longlong.__ctype_le__.__ctype_be__ is c_longlong)
87
s = c_longlong.__ctype_be__(0x1234567890ABCDEF)
88
self.failUnlessEqual(bin(struct.pack(">q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
89
self.failUnlessEqual(bin(s), "1234567890ABCDEF")
90
self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
92
s = c_longlong.__ctype_le__(0x1234567890ABCDEF)
93
self.failUnlessEqual(bin(struct.pack("<q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
94
self.failUnlessEqual(bin(s), "EFCDAB9078563412")
95
self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
97
s = c_ulonglong.__ctype_be__(0x1234567890ABCDEF)
98
self.failUnlessEqual(bin(struct.pack(">Q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
99
self.failUnlessEqual(bin(s), "1234567890ABCDEF")
100
self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
102
s = c_ulonglong.__ctype_le__(0x1234567890ABCDEF)
103
self.failUnlessEqual(bin(struct.pack("<Q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
104
self.failUnlessEqual(bin(s), "EFCDAB9078563412")
105
self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
107
def test_endian_float(self):
108
if sys.byteorder == "little":
109
self.failUnless(c_float.__ctype_le__ is c_float)
110
self.failUnless(c_float.__ctype_be__.__ctype_le__ is c_float)
112
self.failUnless(c_float.__ctype_be__ is c_float)
113
self.failUnless(c_float.__ctype_le__.__ctype_be__ is c_float)
115
self.failUnlessEqual(bin(struct.pack("f", math.pi)), bin(s))
116
# Hm, what's the precision of a float compared to a double?
117
self.failUnlessAlmostEqual(s.value, math.pi, places=6)
118
s = c_float.__ctype_le__(math.pi)
119
self.failUnlessAlmostEqual(s.value, math.pi, places=6)
120
self.failUnlessEqual(bin(struct.pack("<f", math.pi)), bin(s))
121
s = c_float.__ctype_be__(math.pi)
122
self.failUnlessAlmostEqual(s.value, math.pi, places=6)
123
self.failUnlessEqual(bin(struct.pack(">f", math.pi)), bin(s))
125
def test_endian_double(self):
126
if sys.byteorder == "little":
127
self.failUnless(c_double.__ctype_le__ is c_double)
128
self.failUnless(c_double.__ctype_be__.__ctype_le__ is c_double)
130
self.failUnless(c_double.__ctype_be__ is c_double)
131
self.failUnless(c_double.__ctype_le__.__ctype_be__ is c_double)
132
s = c_double(math.pi)
133
self.failUnlessEqual(s.value, math.pi)
134
self.failUnlessEqual(bin(struct.pack("d", math.pi)), bin(s))
135
s = c_double.__ctype_le__(math.pi)
136
self.failUnlessEqual(s.value, math.pi)
137
self.failUnlessEqual(bin(struct.pack("<d", math.pi)), bin(s))
138
s = c_double.__ctype_be__(math.pi)
139
self.failUnlessEqual(s.value, math.pi)
140
self.failUnlessEqual(bin(struct.pack(">d", math.pi)), bin(s))
142
def test_endian_other(self):
143
self.failUnless(c_byte.__ctype_le__ is c_byte)
144
self.failUnless(c_byte.__ctype_be__ is c_byte)
146
self.failUnless(c_ubyte.__ctype_le__ is c_ubyte)
147
self.failUnless(c_ubyte.__ctype_be__ is c_ubyte)
149
self.failUnless(c_char.__ctype_le__ is c_char)
150
self.failUnless(c_char.__ctype_be__ is c_char)
152
def test_struct_fields_1(self):
153
if sys.byteorder == "little":
154
base = BigEndianStructure
156
base = LittleEndianStructure
160
_fields_ = [("a", c_ubyte),
177
("a", c_int * 3 * 3 * 3)]
178
T._fields_ = _fields_
180
# these fields do not support different byte order:
181
for typ in c_wchar, c_void_p, POINTER(c_int):
182
_fields_.append(("x", typ))
185
self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
187
def test_struct_struct(self):
188
# Nested structures with different byte order not (yet) supported
189
if sys.byteorder == "little":
190
base = BigEndianStructure
192
base = LittleEndianStructure
195
_fields_ = [("a", c_int),
199
self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)])
201
def test_struct_fields_2(self):
202
# standard packing in struct uses no alignment.
203
# So, we have to align using pad bytes.
205
# Unaligned accesses will crash Python (on those platforms that
206
# don't allow it, like sparc solaris).
207
if sys.byteorder == "little":
208
base = BigEndianStructure
211
base = LittleEndianStructure
215
_fields_ = [("b", c_byte),
220
s1 = S(0x12, 0x1234, 0x12345678, 3.14)
221
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
222
self.failUnlessEqual(bin(s1), bin(s2))
224
def test_unaligned_nonnative_struct_fields(self):
225
if sys.byteorder == "little":
226
base = BigEndianStructure
229
base = LittleEndianStructure
234
_fields_ = [("b", c_byte),
249
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
250
self.failUnlessEqual(bin(s1), bin(s2))
252
def test_unaligned_native_struct_fields(self):
253
if sys.byteorder == "little":
256
base = LittleEndianStructure
261
_fields_ = [("b", c_byte),
276
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
277
self.failUnlessEqual(bin(s1), bin(s2))
279
if __name__ == "__main__":