10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sys, unittest, struct, math, ctypes
20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom binascii import hexlify
30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom ctypes import *
50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef bin(s):
70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return hexlify(memoryview(s)).upper()
80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Each *simple* type that supports different byte orders has an
100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# __ctype_be__ attribute that specifies the same type in BIG ENDIAN
110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# byte order, and a __ctype_le__ attribute that is the same type in
120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# LITTLE ENDIAN byte order.
130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#
140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# For Structures and Unions, these types are created on demand.
150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Test(unittest.TestCase):
170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def X_test(self):
180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        print >> sys.stderr,  sys.byteorder
190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for i in range(32):
200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            bits = BITS()
210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            setattr(bits, "i%s" % i, 1)
220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            dump(bits)
230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_endian_short(self):
250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.byteorder == "little":
260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_short.__ctype_le__ is c_short)
270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_short.__ctype_be__.__ctype_le__ is c_short)
280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_short.__ctype_be__ is c_short)
300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_short.__ctype_le__.__ctype_be__ is c_short)
310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_short.__ctype_be__(0x1234)
320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack(">h", 0x1234)), "1234")
330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "1234")
340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x1234)
350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_short.__ctype_le__(0x1234)
370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("<h", 0x1234)), "3412")
380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "3412")
390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x1234)
400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_ushort.__ctype_be__(0x1234)
420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack(">h", 0x1234)), "1234")
430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "1234")
440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x1234)
450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_ushort.__ctype_le__(0x1234)
470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("<h", 0x1234)), "3412")
480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "3412")
490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x1234)
500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_endian_int(self):
520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.byteorder == "little":
530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_int.__ctype_le__ is c_int)
540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_int.__ctype_be__.__ctype_le__ is c_int)
550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_int.__ctype_be__ is c_int)
570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_int.__ctype_le__.__ctype_be__ is c_int)
580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_int.__ctype_be__(0x12345678)
600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack(">i", 0x12345678)), "12345678")
610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "12345678")
620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x12345678)
630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_int.__ctype_le__(0x12345678)
650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("<i", 0x12345678)), "78563412")
660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "78563412")
670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x12345678)
680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_uint.__ctype_be__(0x12345678)
700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack(">I", 0x12345678)), "12345678")
710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "12345678")
720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x12345678)
730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_uint.__ctype_le__(0x12345678)
750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("<I", 0x12345678)), "78563412")
760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "78563412")
770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x12345678)
780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_endian_longlong(self):
800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.byteorder == "little":
810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_longlong.__ctype_le__ is c_longlong)
820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_longlong.__ctype_be__.__ctype_le__ is c_longlong)
830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_longlong.__ctype_be__ is c_longlong)
850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_longlong.__ctype_le__.__ctype_be__ is c_longlong)
860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_longlong.__ctype_be__(0x1234567890ABCDEF)
880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack(">q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "1234567890ABCDEF")
900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x1234567890ABCDEF)
910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_longlong.__ctype_le__(0x1234567890ABCDEF)
930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("<q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "EFCDAB9078563412")
950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x1234567890ABCDEF)
960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_ulonglong.__ctype_be__(0x1234567890ABCDEF)
980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack(">Q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "1234567890ABCDEF")
1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x1234567890ABCDEF)
1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_ulonglong.__ctype_le__(0x1234567890ABCDEF)
1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("<Q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s), "EFCDAB9078563412")
1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, 0x1234567890ABCDEF)
1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_endian_float(self):
1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.byteorder == "little":
1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_float.__ctype_le__ is c_float)
1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_float.__ctype_be__.__ctype_le__ is c_float)
1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_float.__ctype_be__ is c_float)
1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_float.__ctype_le__.__ctype_be__ is c_float)
1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_float(math.pi)
1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("f", math.pi)), bin(s))
1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Hm, what's the precision of a float compared to a double?
1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAlmostEqual(s.value, math.pi, 6)
1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_float.__ctype_le__(math.pi)
1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAlmostEqual(s.value, math.pi, 6)
1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("<f", math.pi)), bin(s))
1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_float.__ctype_be__(math.pi)
1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertAlmostEqual(s.value, math.pi, 6)
1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack(">f", math.pi)), bin(s))
1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_endian_double(self):
1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.byteorder == "little":
1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_double.__ctype_le__ is c_double)
1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_double.__ctype_be__.__ctype_le__ is c_double)
1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_double.__ctype_be__ is c_double)
1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertTrue(c_double.__ctype_le__.__ctype_be__ is c_double)
1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_double(math.pi)
1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, math.pi)
1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("d", math.pi)), bin(s))
1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_double.__ctype_le__(math.pi)
1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, math.pi)
1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack("<d", math.pi)), bin(s))
1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s = c_double.__ctype_be__(math.pi)
1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(s.value, math.pi)
1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(struct.pack(">d", math.pi)), bin(s))
1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_endian_other(self):
1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(c_byte.__ctype_le__ is c_byte)
1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(c_byte.__ctype_be__ is c_byte)
1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(c_ubyte.__ctype_le__ is c_ubyte)
1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(c_ubyte.__ctype_be__ is c_ubyte)
1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(c_char.__ctype_le__ is c_char)
1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertTrue(c_char.__ctype_be__ is c_char)
1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_struct_fields_1(self):
1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.byteorder == "little":
1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            base = BigEndianStructure
1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            base = LittleEndianStructure
1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class T(base):
1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pass
1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        _fields_ = [("a", c_ubyte),
1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("b", c_byte),
1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("c", c_short),
1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("d", c_ushort),
1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("e", c_int),
1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("f", c_uint),
1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("g", c_long),
1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("h", c_ulong),
1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("i", c_longlong),
1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("k", c_ulonglong),
1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("l", c_float),
1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("m", c_double),
1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("n", c_char),
1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("b1", c_byte, 3),
1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("b2", c_byte, 3),
1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("b3", c_byte, 2),
1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    ("a", c_int * 3 * 3 * 3)]
1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        T._fields_ = _fields_
1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # these fields do not support different byte order:
1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for typ in c_wchar, c_void_p, POINTER(c_int):
1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _fields_.append(("x", typ))
1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            class T(base):
1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass
1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_struct_struct(self):
1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # nested structures with different byteorders
1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # create nested structures with given byteorders and set memory to data
1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for nested, data in (
1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (BigEndianStructure, b'\0\0\0\1\0\0\0\2'),
1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'),
1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ):
1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for parent in (
1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                BigEndianStructure,
1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                LittleEndianStructure,
1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                Structure,
2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ):
2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                class NestedStructure(nested):
2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    _fields_ = [("x", c_uint32),
2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                ("y", c_uint32)]
2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                class TestStructure(parent):
2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    _fields_ = [("point", NestedStructure)]
2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertEqual(len(data), sizeof(TestStructure))
2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                ptr = POINTER(TestStructure)
2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                s = cast(data, ptr)[0]
2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                del ctypes._pointer_type_cache[TestStructure]
2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertEqual(s.point.x, 1)
2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.assertEqual(s.point.y, 2)
2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_struct_fields_2(self):
2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # standard packing in struct uses no alignment.
2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # So, we have to align using pad bytes.
2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #
2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Unaligned accesses will crash Python (on those platforms that
2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # don't allow it, like sparc solaris).
2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.byteorder == "little":
2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            base = BigEndianStructure
2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            fmt = ">bxhid"
2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            base = LittleEndianStructure
2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            fmt = "<bxhid"
2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class S(base):
2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _fields_ = [("b", c_byte),
2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("h", c_short),
2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("i", c_int),
2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("d", c_double)]
2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1 = S(0x12, 0x1234, 0x12345678, 3.14)
2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s1), bin(s2))
2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_unaligned_nonnative_struct_fields(self):
2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.byteorder == "little":
2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            base = BigEndianStructure
2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            fmt = ">b h xi xd"
2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            base = LittleEndianStructure
2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            fmt = "<b h xi xd"
2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class S(base):
2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _pack_ = 1
2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _fields_ = [("b", c_byte),
2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("h", c_short),
2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("_1", c_byte),
2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("i", c_int),
2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("_2", c_byte),
2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("d", c_double)]
2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1 = S()
2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1.b = 0x12
2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1.h = 0x1234
2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1.i = 0x12345678
2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1.d = 3.14
2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s1), bin(s2))
2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def test_unaligned_native_struct_fields(self):
2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if sys.byteorder == "little":
2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            fmt = "<b h xi xd"
2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            base = LittleEndianStructure
2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            fmt = ">b h xi xd"
2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        class S(Structure):
2740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _pack_ = 1
2750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _fields_ = [("b", c_byte),
2760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("h", c_short),
2780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("_1", c_byte),
2800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("i", c_int),
2810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("_2", c_byte),
2830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        ("d", c_double)]
2840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1 = S()
2860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1.b = 0x12
2870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1.h = 0x1234
2880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1.i = 0x12345678
2890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s1.d = 3.14
2900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
2910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.assertEqual(bin(s1), bin(s2))
2920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == "__main__":
2940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    unittest.main()
295