def test_sizeof_cdata(self): ffi = FFI(backend=self.Backend()) assert ffi.sizeof(ffi.new("short")) == SIZE_OF_PTR assert ffi.sizeof(ffi.cast("short", 123)) == SIZE_OF_SHORT # a = ffi.new("int[]", [10, 11, 12, 13, 14]) assert len(a) == 5 assert ffi.sizeof(a) == 5 * SIZE_OF_INT
def test_pointer_init(self): ffi = FFI(backend=self.Backend()) n = ffi.new("int", 24) a = ffi.new("int *[10]", [None, None, n, n, None]) for i in range(10): if i not in (2, 3): assert a[i] is None assert a[2] == a[3] == n
def test_new_array_of_pointer_2(self): ffi = FFI(backend=self.Backend()) n = ffi.new("int[1]", [99]) p = ffi.new("int*[4]") p[3] = n a = p[3] assert repr(a) == "<cdata 'int *'>" assert a[0] == 99
def test_anonymous_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("typedef struct { int a; } foo_t;") ffi.cdef("typedef struct { char b, c; } bar_t;") f = ffi.new("foo_t", [12345]) b = ffi.new("bar_t", ["B", "C"]) assert f.a == 12345 assert f.b == "B" assert f.c == "C"
def test_new_single_integer(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int") # similar to ffi.new("int[1]") assert p[0] == 0 p[0] = -123 assert p[0] == -123 p = ffi.new("int", -42) assert p[0] == -42 assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT
def test_none_as_null(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int*[1]") assert p[0] is None # n = ffi.new("int", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 p[0] = None assert p[0] is None
def test_fetch_const_char_p_field(self): # 'const' is ignored so far ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { const char *name; };") t = ffi.new("const char[]", "testing") s = ffi.new("struct foo", [t]) assert type(s.name) is not str assert str(s.name) == "testing" s.name = None assert s.name is None
def test_new_pointer_to_array(self): ffi = FFI(backend=self.Backend()) a = ffi.new("int[4]", [100, 102, 104, 106]) p = ffi.new("int *", a) assert p[0] == ffi.cast("int *", a) assert p[0][2] == 104 p = ffi.cast("int *", a) assert p[0] == 100 assert p[1] == 102 assert p[2] == 104 assert p[3] == 106
def test_union_simple(self): ffi = FFI(backend=self.Backend()) ffi.cdef("union foo { int a; short b, c; };") u = ffi.new("union foo") assert u.a == u.b == u.c == 0 u.b = -23 assert u.b == -23 assert u.a != 0 py.test.raises(OverflowError, "u.b = 32768") # u = ffi.new("union foo", -2) assert u.a == -2 py.test.raises((AttributeError, TypeError), "del u.a") assert repr(u) == "<cdata 'union foo *' owning %d bytes>" % SIZE_OF_INT
def test_string_from_char_array(self): ffi = FFI(backend=self.Backend()) assert str(ffi.cast("char", "x")) == "x" p = ffi.new("char[]", "hello.") p[5] = '!' assert str(p) == "hello!" p[6] = '?' assert str(p) == "hello!?" p[3] = '\x00' assert str(p) == "hel" py.test.raises(IndexError, "p[7] = 'X'") # a = ffi.new("char[]", "hello\x00world") assert len(a) == 12 p = ffi.cast("char *", a) assert str(p) == 'hello'
def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) py.test.raises(TypeError, ffi.callback, "int(*)(int)") py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) def cb(n): return n + 1 p = ffi.callback("int(*)(int)", cb) res = p(41) # calling an 'int(*)(int)', i.e. a function pointer assert res == 42 and type(res) is int res = p(ffi.cast("int", -41)) assert res == -40 and type(res) is int assert repr(p).startswith( "<cdata 'int(*)(int)' calling <function cb at 0x") assert ffi.typeof(p) is ffi.typeof("int(*)(int)") q = ffi.new("int(*)(int)", p) assert repr( q) == "<cdata 'int(* *)(int)' owning %d bytes>" % (SIZE_OF_PTR) py.test.raises(TypeError, "q(43)") res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) assert repr(q) == "<cdata 'int(*)(int)'>" res = q(45) assert res == 46
def test_constructor_struct_from_dict(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a; short b, c; };") s = ffi.new("struct foo", {'b': 123, 'c': 456}) assert s.a == 0 assert s.b == 123 assert s.c == 456 py.test.raises(KeyError, ffi.new, "struct foo", {'d': 456})
def test_strchr(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" char *strchr(const char *s, int c); """) p = ffi.new("char[]", "hello world!") q = ffi.C.strchr(p, ord('w')) assert str(q) == "world!"
def test_new_array_of_array(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int[3][4]") p[0][0] = 10 p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 py.test.raises(IndexError, "p[1][-1]")
def test_passing_array(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int strlen(char[]); """) p = ffi.new("char[]", "hello") res = ffi.C.strlen(p) assert res == 5
def test_char(self): ffi = FFI(backend=self.Backend()) assert ffi.new("char", "\xff")[0] == '\xff' assert ffi.new("char")[0] == '\x00' assert int(ffi.cast("char", 300)) == 300 - 256 assert bool(ffi.new("char")) py.test.raises(TypeError, ffi.new, "char", 32) py.test.raises(TypeError, ffi.new, "char", "foo") # p = ffi.new("char[]", ['a', 'b', '\x9c']) assert len(p) == 3 assert p[0] == 'a' assert p[1] == 'b' assert p[2] == '\x9c' p[0] = '\xff' assert p[0] == '\xff' p = ffi.new("char[]", "abcd") assert len(p) == 5 assert p[4] == '\x00' # like in C, with: char[] p = "abcd"; # p = ffi.new("char[4]", "ab") assert len(p) == 4 assert [p[i] for i in range(4)] == ['a', 'b', '\x00', '\x00'] p = ffi.new("char[2]", "ab") assert len(p) == 2 assert [p[i] for i in range(2)] == ['a', 'b'] py.test.raises(IndexError, ffi.new, "char[2]", "abc")
def test_struct_pointer(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a; short b, c; };") s = ffi.new("struct foo") assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 py.test.raises(OverflowError, "s[0].b = -32769") py.test.raises(IndexError, "s[1]")
def test_struct_simple(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a; short b, c; };") s = ffi.new("struct foo") assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 py.test.raises(OverflowError, "s.b = 32768") # s = ffi.new("struct foo", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 py.test.raises((AttributeError, TypeError), "del s.a") assert repr(s) == "<cdata 'struct foo *' owning %d bytes>" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # py.test.raises(ValueError, ffi.new, "struct foo", [1, 2, 3, 4])
def test_function_with_struct_argument(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" struct in_addr { unsigned int s_addr; }; char *inet_ntoa(struct in_addr in); """) ina = ffi.new("struct in_addr", [0x04040404]) a = ffi.C.inet_ntoa(ina[0]) assert str(a) == '4.4.4.4'
def test_new_array_varsize(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 py.test.raises(IndexError, "p[10]") # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 py.test.raises(IndexError, "p[2]") assert repr(p) == "<cdata 'int[]' owning %d bytes>" % (2 * SIZE_OF_INT) # p = ffi.new("int[]", 0) py.test.raises(IndexError, "p[0]") py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "<cdata 'int[]' owning 0 bytes>"
def test_new_array_varsize(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 py.test.raises(IndexError, "p[10]") # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 py.test.raises(IndexError, "p[2]") assert repr(p) == "<cdata 'int[]' owning %d bytes>" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) py.test.raises(IndexError, "p[0]") py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "<cdata 'int[]' owning 0 bytes>"
def test_ffi_string(self): ffi = FFI(backend=self.Backend()) a = ffi.new("int[]", range(100, 110)) s = ffi.string(ffi.cast("void *", a), 8) assert type(s) is str if sys.byteorder == 'little': assert s == '\x64\x00\x00\x00\x65\x00\x00\x00' else: assert s == '\x00\x00\x00\x64\x00\x00\x00\x65'
def test_cast_array_to_charp(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) p = ffi.cast("char*", a) data = ''.join([p[i] for i in range(4)]) if sys.byteorder == 'little': assert data == '\x34\x12\x78\x56' else: assert data == '\x12\x34\x56\x78'
def test_array_of_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") py.test.raises(AttributeError, 's.b') py.test.raises(AttributeError, 's.b = 412') s[0].b = 412 assert s[0].b == 412 py.test.raises(IndexError, 's[1]')
def test_new_array_args(self): ffi = FFI(backend=self.Backend()) # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" # then here we must enclose the items in a list p = ffi.new("int[5]", [10, 20, 30, 40, 50]) assert p[0] == 10 assert p[1] == 20 assert p[2] == 30 assert p[3] == 40 assert p[4] == 50 p = ffi.new("int[4]", [25]) assert p[0] == 25 assert p[1] == 0 # follow C convention rather than LuaJIT's assert p[2] == 0 assert p[3] == 0 p = ffi.new("int[4]", [ffi.cast("int", -5)]) assert p[0] == -5 assert repr(p) == "<cdata 'int[4]' owning %d bytes>" % (4*SIZE_OF_INT)
def test_cast_pointer_and_int(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) l1 = ffi.cast("intptr_t", a) p = ffi.cast("short*", a) l2 = ffi.cast("intptr_t", p) assert int(l1) == int(l2) != 0 q = ffi.cast("short*", l1) assert q == ffi.cast("short*", int(l1)) assert q[0] == 0x1234
def test_constructor_struct_of_array(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a[2]; char b[3]; };") s = ffi.new("struct foo", [[10, 11], ['a', 'b', 'c']]) assert s.a[1] == 11 assert s.b[2] == 'c' s.b[1] = 'X' assert s.b[0] == 'a' assert s.b[1] == 'X' assert s.b[2] == 'c'
def test_new_array_args(self): ffi = FFI(backend=self.Backend()) # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" # then here we must enclose the items in a list p = ffi.new("int[5]", [10, 20, 30, 40, 50]) assert p[0] == 10 assert p[1] == 20 assert p[2] == 30 assert p[3] == 40 assert p[4] == 50 p = ffi.new("int[4]", [25]) assert p[0] == 25 assert p[1] == 0 # follow C convention rather than LuaJIT's assert p[2] == 0 assert p[3] == 0 p = ffi.new("int[4]", [ffi.cast("int", -5)]) assert p[0] == -5 assert repr(p) == "<cdata 'int[4]' owning %d bytes>" % (4 * SIZE_OF_INT)
def test_recursive_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int value; struct foo *next; };") s = ffi.new("struct foo") t = ffi.new("struct foo") s.value = 123 s.next = t t.value = 456 assert s.value == 123 assert s.next.value == 456
def test_array_indexing(self): ffi = FFI(backend=self.Backend()) p = ffi.new("int[10]") p[0] = 42 p[9] = 43 assert p[0] == 42 assert p[9] == 43 py.test.raises(IndexError, "p[10]") py.test.raises(IndexError, "p[10] = 44") py.test.raises(IndexError, "p[-1]") py.test.raises(IndexError, "p[-1] = 44")
def test_voidp(self): ffi = FFI(backend=self.Backend()) py.test.raises(TypeError, ffi.new, "void") p = ffi.new("void *") assert p[0] is None a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void *", a) vp = p[0] py.test.raises(TypeError, "vp[0]") py.test.raises(TypeError, ffi.new, "short *", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo") s.p = a # works s.q = a # works py.test.raises(TypeError, "s.r = a") # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works py.test.raises(TypeError, "s.r = b") # fails
def test_cast_between_pointers(self): ffi = FFI(backend=self.Backend()) a = ffi.new("short int[]", [0x1234, 0x5678]) p = ffi.cast("short*", a) p2 = ffi.cast("int*", p) q = ffi.cast("char*", p2) data = ''.join([q[i] for i in range(4)]) if sys.byteorder == 'little': assert data == '\x34\x12\x78\x56' else: assert data == '\x12\x34\x56\x78'
def test_pointer_to_struct(self): ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a; short b, c; };") s = ffi.new("struct foo") s.a = -42 assert s[0].a == -42 p = ffi.new("struct foo *", s) assert p[0].a == -42 assert p[0][0].a == -42 p[0].a = -43 assert s.a == -43 assert s[0].a == -43 p[0][0].a = -44 assert s.a == -44 assert s[0].a == -44 s.a = -45 assert p[0].a == -45 assert p[0][0].a == -45 s[0].a = -46 assert p[0].a == -46 assert p[0][0].a == -46