14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport unittest 24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom ctypes import * 34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport re, sys 44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif sys.byteorder == "little": 64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao THIS_ENDIAN = "<" 74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao OTHER_ENDIAN = ">" 84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoelse: 94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao THIS_ENDIAN = ">" 104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao OTHER_ENDIAN = "<" 114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef normalize(format): 134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Remove current endian specifier and white space from a format 144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # string 154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if format is None: 164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return "" 174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao format = format.replace(OTHER_ENDIAN, THIS_ENDIAN) 184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return re.sub(r"\s", "", format) 194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Test(unittest.TestCase): 214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_native_types(self): 234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for tp, fmt, shape, itemtp in native_types: 244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ob = tp() 254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao v = memoryview(ob) 264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(normalize(v.format), normalize(fmt)) 284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if shape is not None: 294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(v), shape[0]) 304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob)) 324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(v.itemsize, sizeof(itemtp)) 334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(v.shape, shape) 344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # ctypes object always have a non-strided memory block 354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(v.strides, None) 364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # they are always read/write 374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertFalse(v.readonly) 384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if v.shape: 404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = 1 414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dim in v.shape: 424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = n * dim 434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(n * v.itemsize, len(v.tobytes())) 444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except: 454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # so that we can see the failing type 464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao print(tp) 474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise 484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def test_endian_types(self): 504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for tp, fmt, shape, itemtp in endian_types: 514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ob = tp() 524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao v = memoryview(ob) 534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(v.format, fmt) 554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if shape is not None: 564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(v), shape[0]) 574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob)) 594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(v.itemsize, sizeof(itemtp)) 604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(v.shape, shape) 614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # ctypes object always have a non-strided memory block 624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(v.strides, None) 634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # they are always read/write 644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertFalse(v.readonly) 654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if v.shape: 674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = 1 684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for dim in v.shape: 694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao n = n * dim 704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.assertEqual(n, len(v)) 714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except: 724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # so that we can see the failing type 734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao print(tp) 744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise 754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# define some structure classes 774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Point(Structure): 794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _fields_ = [("x", c_long), ("y", c_long)] 804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass PackedPoint(Structure): 824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _pack_ = 2 834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _fields_ = [("x", c_long), ("y", c_long)] 844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Point2(Structure): 864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 874adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoPoint2._fields_ = [("x", c_long), ("y", c_long)] 884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass EmptyStruct(Structure): 904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _fields_ = [] 914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass aUnion(Union): 934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _fields_ = [("a", c_int)] 944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Incomplete(Structure): 964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Complete(Structure): 994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 1004adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoPComplete = POINTER(Complete) 1014adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoComplete._fields_ = [("a", c_long)] 1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao################################################################ 1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# This table contains format strings as they look on little endian 1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# machines. The test replaces '<' with '>' on big endian machines. 1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonative_types = [ 1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # type format shape calc itemsize 1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ## simple types 1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_char, "<c", None, c_char), 1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_byte, "<b", None, c_byte), 1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_ubyte, "<B", None, c_ubyte), 1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_short, "<h", None, c_short), 1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_ushort, "<H", None, c_ushort), 1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # c_int and c_uint may be aliases to c_long 1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #(c_int, "<i", None, c_int), 1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #(c_uint, "<I", None, c_uint), 1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_long, "<l", None, c_long), 1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_ulong, "<L", None, c_ulong), 1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # c_longlong and c_ulonglong are aliases on 64-bit platforms 1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #(c_longlong, "<q", None, c_longlong), 1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao #(c_ulonglong, "<Q", None, c_ulonglong), 1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_float, "<f", None, c_float), 1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_double, "<d", None, c_double), 1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # c_longdouble may be an alias to c_double 1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_bool, "<?", None, c_bool), 1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (py_object, "<O", None, py_object), 1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ## pointers 1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (POINTER(c_byte), "&<b", None, POINTER(c_byte)), 1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (POINTER(POINTER(c_long)), "&&<l", None, POINTER(POINTER(c_long))), 1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ## arrays and pointers 1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_double * 4, "(4)<d", (4,), c_double), 1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (c_float * 4 * 3 * 2, "(2,3,4)<f", (2,3,4), c_float), 1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (POINTER(c_short) * 2, "(2)&<h", (2,), POINTER(c_short)), 1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (POINTER(c_short) * 2 * 3, "(3,2)&<h", (3,2,), POINTER(c_short)), 1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (POINTER(c_short * 2), "&(2)<h", None, POINTER(c_short)), 1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ## structures and unions 1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (Point, "T{<l:x:<l:y:}", None, Point), 1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # packed structures do not implement the pep 1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (PackedPoint, "B", None, PackedPoint), 1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (Point2, "T{<l:x:<l:y:}", None, Point2), 1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (EmptyStruct, "T{}", None, EmptyStruct), 1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # the pep does't support unions 1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (aUnion, "B", None, aUnion), 1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ## pointer to incomplete structure 1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (Incomplete, "B", None, Incomplete), 1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (POINTER(Incomplete), "&B", None, POINTER(Incomplete)), 1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # 'Complete' is a structure that starts incomplete, but is completed after the 1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # pointer type to it has been created. 1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (Complete, "T{<l:a:}", None, Complete), 1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # Unfortunately the pointer format string is not fixed... 1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (POINTER(Complete), "&B", None, POINTER(Complete)), 1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ## other 1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # function signatures are not implemented 1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (CFUNCTYPE(None), "X{}", None, CFUNCTYPE(None)), 1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass BEPoint(BigEndianStructure): 1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _fields_ = [("x", c_long), ("y", c_long)] 1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass LEPoint(LittleEndianStructure): 1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _fields_ = [("x", c_long), ("y", c_long)] 1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao################################################################ 1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# This table contains format strings as they really look, on both big 1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# and little endian machines. 1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoendian_types = [ 1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (BEPoint, "T{>l:x:>l:y:}", None, BEPoint), 1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (LEPoint, "T{<l:x:<l:y:}", None, LEPoint), 1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (POINTER(BEPoint), "&T{>l:x:>l:y:}", None, POINTER(BEPoint)), 1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao (POINTER(LEPoint), "&T{<l:x:<l:y:}", None, POINTER(LEPoint)), 1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ] 1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == "__main__": 1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao unittest.main() 197