def test_structsformat(self): FFI = pydffi.FFI() CU = FFI.cdef(''' #include <stdbool.h> typedef struct { bool a; unsigned int b; unsigned short c; } A; typedef struct { unsigned char buf[9]; unsigned short v0; A a; unsigned short v1; } B; ''') vA = CU.types.A(a=1,b=0xAAAAAAAA,c=0x4444) buf = pydffi.view_as_bytes(vA) vAup = struct.unpack(CU.types.A.format, buf) self.assertEqual(vAup, (1,0xAAAAAAAA,0x4444)) buf_ref = bytearray(b"012345678") vB = CU.types.B(v0=1,v1=2,a=vA,buf=pydffi.view_as(CU.types.B.buf.type, buf_ref)) buf = pydffi.view_as_bytes(vB) vBup = struct.unpack(CU.types.B.format, buf) self.assertEqual(bytearray(vBup[:9]), buf_ref) self.assertEqual(vBup[9:], (1,1,0xAAAAAAAA,0x4444,2))
def test_views(self): F = self.FFI CU = F.cdef(''' #include <stdint.h> typedef struct { uint32_t a; uint64_t b; } A; ''') A = CU.types.A Len = A.size S = pydffi.view_as(pydffi.const(A), b"A" * Len) self.assertEqual(int(S.a), 0x41414141) self.assertEqual(int(S.b), 0x4141414141414141) B = bytearray(pydffi.view_as_bytes(S)) self.assertEqual(B, b"A" * Len) B = pydffi.view_as_bytes(S) One = 1 if sys.version_info >= (3, 0) else struct.pack("B", 1) B[0] = One B[1] = One B[2] = One B[3] = One self.assertEqual(int(S.a), 0x01010101)
def test_recursive_union(self): FFI = pydffi.FFI() CU = FFI.cdef(''' typedef struct { unsigned char a; int b; int c; short d; } A; typedef union _Node Node; union _Node { A v; Node* next; }; ''') A = CU.types.A Node = CU.types.Node A0 = A(a=0, b=1, c=10, d=20) A1 = A(a=1, b=2, c=-10, d=-20) N1 = Node() N1.next = pydffi.ptr(Node)() N0 = Node() N0.next = pydffi.ptr(N1) for T in self.generated_types(Node, "_Node"): V = self.purectypes.unpack(T, bytes(pydffi.view_as_bytes(N0))) self.assertEqual(V.next, int(N0.next))
def test_recursive_struct(self): FFI = pydffi.FFI() CU = FFI.cdef(''' typedef struct { unsigned char a; int b; int c; short d; } A; typedef struct _Node Node; struct _Node { A v; struct _Node* next; }; ''') A = CU.types.A Node = CU.types.Node A0 = A(a=0, b=1, c=10, d=20) A1 = A(a=1, b=2, c=-10, d=-20) N1 = Node(v=A1, next=pydffi.ptr(Node)()) N0 = Node(v=A0, next=pydffi.ptr(N1)) for T in self.generated_types(Node, "_Node"): V = self.purectypes.unpack(T, bytes(pydffi.view_as_bytes(N0))) for attr in ("a", "b", "c", "d"): self.assertEqual(getattr(V.v, attr), getattr(N0.v, attr)) self.assertEqual(V.next, int(N0.next))
def test_structs(self): FFI = self.FFI CU = FFI.compile(''' struct A { unsigned char a; short b; }; int check(struct A a, unsigned char aref, short bref) { return (a.a == aref) && (a.b == bref); } int checkptr(struct A* a, unsigned char aref, short bref) { return (a->a == aref) && (a->b == bref); } void set(struct A* a) { a->a = 59; a->b = 1111; } struct A init() { struct A ret; ret.a = 44; ret.b = 5555; return ret; } ''') A = CU.types.A fields_name = sorted((f.name for f in A)) self.assertEqual(fields_name[0], 'a') self.assertEqual(fields_name[1], 'b') Av = CU.types.A(a=1, b=2) # Direct data access throught a memoryview mv = pydffi.view_as_bytes(Av) # Set a throught mv v = 5 if sys.version_info >= (3, 0) else struct.pack("B", 5) mv[0] = v self.assertEqual(Av.a, 5) self.assertEqual(Av.b, 2) self.assertTrue(getattr(CU.funcs, "check")(Av, 5, 2)) pAv = pydffi.ptr(Av) self.assertTrue(CU.funcs.checkptr(pAv, 5, 2)) CU.funcs.set(pAv) self.assertTrue(getattr(CU.funcs, "check")(Av, 59, 1111)) self.assertEqual(Av.a, 59) self.assertEqual(Av.b, 1111) Av = CU.funcs.init() self.assertEqual(Av.a, 44) self.assertEqual(Av.b, 5555)
def test_views(self): F = self.FFI CU = F.cdef(''' typedef struct { unsigned int a; unsigned long long b; } A; ''') S = pydffi.view_as(pydffi.const(CU.types.A), b"A" * 16) self.assertEqual(int(S.a), 0x41414141) self.assertEqual(int(S.b), 0x4141414141414141) B = bytearray(pydffi.view_as_bytes(S)) self.assertEqual(B, b"A" * 16) B = pydffi.view_as_bytes(S) One = 1 if sys.version_info >= (3, 0) else struct.pack("B", 1) B[0] = One B[1] = One B[2] = One B[3] = One self.assertEqual(int(S.a), 0x01010101)
def test_structs_portable_format(self): CU = self.FFI.cdef(''' #include <stdlib.h> #include <stdbool.h> typedef struct { bool valid; void* a; unsigned short len; size_t v; } A; ''') a = CU.types.A(valid=1,len=0xBBAA,v=0xDDCCBBAA) av = pydffi.view_as_bytes(a) self.assertEqual(struct.unpack(CU.types.A.format, av), struct.unpack(CU.types.A.portable_format, av))
def test_cast(self): FFI = self.FFI # Integer casts for Ty in (FFI.UInt8, FFI.UInt16, FFI.UInt32, FFI.UInt64): v = random.getrandbits(pydffi.sizeof(Ty(0)) * 8) V = Ty(v) for CTy in (FFI.UInt8Ty, FFI.UInt16Ty, FFI.UInt32Ty, FFI.UInt64Ty): VC = pydffi.cast(V, CTy) self.assertEqual(VC.value, v & (2**(CTy.size * 8) - 1)) # Array/pointer casts CU = FFI.compile(''' #include <stdio.h> #include <stdbool.h> typedef struct { char buf[256]; } A; bool verify(const char* msg, const char* ref) { return strcmp(msg, ref) == 0; } bool verify_struct(A const* a, const char* ref) { return strcmp(a->buf, ref) == 0; } ''') verify_struct = CU.funcs.verify_struct SA = CU.types.A A = pydffi.CStructObj(SA) mem = pydffi.view_as_bytes(A) b = b"hello!\x00" mem[:len(b)] = b self.assertTrue(verify_struct(pydffi.ptr(A), b"hello!")) verify = getattr(CU.funcs, "verify") buf = A.buf buf = pydffi.cast(pydffi.ptr(buf), FFI.Int8PtrTy) self.assertTrue(verify(buf, b"hello!")) # Cast back buf = pydffi.cast(buf, FFI.pointerType(SA)) self.assertTrue(verify_struct(buf, b"hello!"))
def test_array(self): CU = self.FFI.compile(''' #include <stdio.h> #include <string.h> #include <stdbool.h> struct A { char buf[128]; }; struct A init() { struct A a; strcpy(a.buf, "hello"); return a; } bool verify(struct A const* v, const char* ref) { return strcmp(v->buf, ref) == 0; } ''') A = CU.funcs.init() Buf = A.buf self.assertEqual(Buf.get(0), "h") Buf.set(0, 'H') self.assertEqual(Buf.get(0), "H") self.assertTrue(CU.funcs.verify(pydffi.ptr(A), b"Hello")) m = pydffi.view_as_bytes(Buf) v = ord("Z") if sys.version_info >= (3, 0) else struct.pack( "B", ord("Z")) m[0] = v self.assertTrue(CU.funcs.verify(pydffi.ptr(A), b"Zello")) UIntTy = self.FFI.basicType(pydffi.BasicKind.UInt) N = 10 ArrTy = self.FFI.arrayType(UIntTy, N) Arr = pydffi.CArrayObj(ArrTy) for i in range(N): Arr.set(i, i) for i in range(N): self.assertEqual(Arr.get(i), i)
def test_union(self): FFI = pydffi.FFI() CU = FFI.cdef(''' #include <stdint.h> typedef union { struct { uint8_t v8[4]; }; uint32_t v32; } IP; ''') Obj = CU.types.IP() Obj.v32 = 0xAABBCCDD for IP in self.generated_types(CU.types.IP, "IP"): V = self.purectypes.unpack(IP, bytes(pydffi.view_as_bytes(Obj))) self.assertEqual(V.v32, 0xAABBCCDD) for i in range(4): self.assertEqual(V.v8[i], Obj.v8[i]) V = self.purectypes.pack(IP, V) V = pydffi.view_as(pydffi.const(CU.types.IP), V) self.assertEqual(V.v32, 0xAABBCCDD)
def test_struct(self): FFI = pydffi.FFI() CU = FFI.cdef(''' typedef struct { unsigned char a; int b; int c; short d; } A; ''') Obj = CU.types.A(a=1, b=2, c=10, d=20) for A in self.generated_types(CU.types.A, "A"): V = self.purectypes.unpack(A, bytes(pydffi.view_as_bytes(Obj))) self.assertEqual(V.a, 1) self.assertEqual(V.b, 2) self.assertEqual(V.c, 10) self.assertEqual(V.d, 20) V = self.purectypes.pack(A, V) V = pydffi.view_as(CU.types.A, V) self.assertEqual(Obj.a, V.a) self.assertEqual(Obj.b, V.b) self.assertEqual(Obj.c, V.c) self.assertEqual(Obj.d, V.d)
CU = FFI.cdef(''' #include <stdbool.h> typedef struct { bool a; unsigned int b; unsigned short c; } A; typedef struct { unsigned char buf[9]; unsigned short v0; A a; unsigned short v1; } B; ''') vA = CU.types.A(a=1, b=0xAAAAAAAA, c=0x4444) buf = pydffi.view_as_bytes(vA) vAup = struct.unpack(CU.types.A.format, buf) assert (vAup == (1, 0xAAAAAAAA, 0x4444)) buf_ref = bytearray(b"012345678") vB = CU.types.B(v0=1, v1=2, a=vA, buf=pydffi.view_as(CU.types.B.buf.type, buf_ref)) buf = pydffi.view_as_bytes(vB) vBup = struct.unpack(CU.types.B.format, buf) assert (bytearray(vBup[:9]) == buf_ref) assert (vBup[9:] == (1, 1, 0xAAAAAAAA, 0x4444, 2))
return a; } void dump(struct A const* v) { puts(v->buf); } ''') A = CU.funcs.init() Buf = A.buf assert(Buf.get(0) == "h") Buf.set(0, 'H') assert(Buf.get(0) == "H") # CHECK: Hello CU.funcs.dump(pydffi.ptr(A)) m = pydffi.view_as_bytes(Buf) v = ord("Z") if sys.version_info >= (3, 0) else struct.pack("B", ord("Z")) m[0] = v # CHECK: Zello CU.funcs.dump(pydffi.ptr(A)) UIntTy = FFI.basicType(pydffi.BasicKind.UInt) N = 10 ArrTy = FFI.arrayType(UIntTy, N) Arr=pydffi.CArrayObj(ArrTy) for i in range(N): Arr.set(i, i) for i in range(N): assert(Arr.get(i) == i) # TOFIX!
struct A init() { struct A ret; ret.a = 44; ret.b = 5555; return ret; } ''') A = CU.types.A fields_name = sorted((f.name for f in A)) assert (fields_name[0] == 'a') assert (fields_name[1] == 'b') Av = CU.types.A(a=1, b=2) # Direct data access throught a memoryview mv = pydffi.view_as_bytes(Av) # Set a throught mv v = 5 if sys.version_info >= (3, 0) else struct.pack("B", 5) mv[0] = v assert (Av.a == 5) assert (Av.b == 2) # CHECK: a=5, b=2 getattr(CU.funcs, "print")(Av) pAv = pydffi.ptr(Av) # CHECK: a=5, b=2 CU.funcs.printptr(pAv) CU.funcs.set(pAv) # CHECK: a=59, b=1111
char buf[256]; } A; void print(const char* msg) { puts(msg); } void print_struct(A const* a) { print(a->buf); } ''') print_struct = CU.funcs.print_struct SA = CU.types.A A = pydffi.CStructObj(SA) mem = pydffi.view_as_bytes(A) b = b"hello!\x00" mem[:len(b)] = b # CHECK: hello! print_struct(pydffi.ptr(A)) print_ = getattr(CU.funcs, "print") buf = A.buf buf = pydffi.cast(pydffi.ptr(buf),FFI.Int8PtrTy) # CHECK: hello! print_(buf) # Cast back buf = pydffi.cast(buf, FFI.pointerType(SA)) # CHECK: hello!
# You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # RUN: "%python" "%s" import pydffi import struct FFI = pydffi.FFI() CU = FFI.cdef(''' #include <stdlib.h> #include <stdbool.h> typedef struct { bool valid; void* a; unsigned short len; size_t v; } A; ''') a = CU.types.A(valid=1,len=0xBBAA,v=0xDDCCBBAA) av = pydffi.view_as_bytes(a) assert(struct.unpack(CU.types.A.format, av) == struct.unpack(CU.types.A.portable_format, av))
# RUN: "%python" "%s" import pydffi import sys import struct F = pydffi.FFI() CU = F.compile(''' #include <stdio.h> struct A { unsigned int a; unsigned long long b; }; void print(struct A a) { printf("%u %lu\\n", a.a, a.b); } ''') S = pydffi.view_as(pydffi.const(CU.types.A), b"A"*16) assert(int(S.a) == 0x41414141) assert(int(S.b) == 0x4141414141414141) B = bytearray(pydffi.view_as_bytes(S)) assert(B == b"A"*16) B = pydffi.view_as_bytes(S) One = 1 if sys.version_info >= (3, 0) else struct.pack("B", 1) B[0] = One B[1] = One B[2] = One B[3] = One assert(int(S.a) == 0x01010101)
def test_basic(self): FFI = pydffi.FFI() Obj = FFI.UIntTy(10) for T in self.generated_types(FFI.UIntTy, "__UIntTy"): V = self.purectypes.unpack(T, bytes(pydffi.view_as_bytes(Obj))) self.assertEqual(V, 10)