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_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))
Example #3
0
    def test_ptrs(self):
        F = self.FFI
        O = F.UInt32Ty(4)
        P = pydffi.ptr(O)

        NewP = F.UInt32PtrTy(int(P.value))
        self.assertEqual(NewP.obj, O)
Example #4
0
 def test_symbol(self):
     addr = 0xAABBCCDD
     pydffi.addSymbol("my_custom_symbol", 0xAABBCCDD)
     F = self.FFI
     CU = F.cdef('''
     extern void my_custom_symbol(int);
     ''')
     self.assertEqual(pydffi.ptr(CU.funcs.my_custom_symbol).value, addr)
Example #5
0
    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!"))
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    def test_new_structs(self):
        D = self.FFI
        CU = D.compile('''
        #include <stdio.h>
        struct A {
            int a;
            short b;
        };
        void print(char* ret, size_t n, struct A a) {
            snprintf(ret, n, "%d %d", a.a, a.b);
        }
        ''')

        buf = self.FFI.arrayType(self.FFI.CharTy, 128)()
        a = CU.types.A(a=4, b=10)
        getattr(CU.funcs, "print")(pydffi.ptr(buf), 128, a)
        self.assertEqual(self.cstr_from_array(buf), b"4 10")

        a = CU.types.A(a=0, b=0)
        getattr(CU.funcs, "print")(pydffi.ptr(buf), 128, a)
        self.assertEqual(self.cstr_from_array(buf), b"0 0")
Example #9
0
    def test_array_ptr(self):
        CU = self.FFI.compile('''
#include <stdio.h>
typedef int int2[2];
void foo(char* buf, size_t n, int2* ar)
{
    snprintf(buf, n, "%d %d", ar[0][0], ar[0][1]);
}
        ''')

        v = CU.types.int2()
        v.set(0, 1)
        v.set(1, 2)
        buf = self.FFI.arrayType(self.FFI.CharTy, 128)()
        CU.funcs.foo(pydffi.ptr(buf), 128, pydffi.ptr(v))
        self.assertEqual(self.cstr_from_array(buf), b"1 2")

        v[0] = 10
        v[1] = 20
        CU.funcs.foo(pydffi.ptr(buf), 128, pydffi.ptr(v))
        self.assertEqual(self.cstr_from_array(buf), b"10 20")
Example #10
0
    def test_func_ptr(self):
        FFI = self.FFI
        CU = FFI.compile('''
typedef struct
{
  int a;
  int b;
  int res;
} Res;

typedef Res(*op)(int,int);

static Res get_res(int res, int a, int b) {
  Res Ret = {a,b,res};
  return Ret;
}

static Res add(int a, int b) {
  return get_res(a+b,a,b);
}
static Res sub(int a, int b) {
  return get_res(a-b,a,b);
}

op get_op(unsigned Id)
{
  if (Id == 0) return add;
  if (Id == 1) return sub;
  return 0;
}

Res call(op f, int a, int b) {
  return f(a,b);
}
        ''')

        Add = CU.funcs.get_op(0)
        Add = Add.obj
        Res = Add(1, 4)
        self.assertEqual(Res.res, 5)

        sub_addr = pydffi.ptr(CU.funcs.sub)
        Res = CU.funcs.call(sub_addr, 1, 5)
        self.assertEqual(Res.res, -4)

        subFuncTy = pydffi.typeof(CU.funcs.sub).type
        funcByAddr = subFuncTy(sub_addr)
        self.assertEqual(funcByAddr(1, 5).res, -4)

        funcByAddr = subFuncTy(sub_addr.value)
        self.assertEqual(funcByAddr(1, 5).res, -4)
Example #11
0
    def test_buffers(self):
        CU = self.FFI.compile('''
#include <stdio.h>
#include <stdint.h>

void print(const char* msg) {
    puts(msg);
}
void print_u8(uint8_t const* buf, size_t len) {
    for (size_t i = 0; i < len; ++i) {
        printf("%02X ", buf[i]);
    }
    printf("\\n");
} 

void bytesupper(uint8_t* S) {
    const size_t Len = strlen(S);
    printf("%lu\\n", Len);
    for (size_t i = 0; i < Len; ++i) {
        S[i] = toupper(S[i]);
    }
}

void strupper(char* S) {
    bytesupper(S);
}
        ''')
        print_ = getattr(CU.funcs, "print")
        print_u8 = CU.funcs.print_u8
        bytesupper = CU.funcs.bytesupper
        strupper = CU.funcs.strupper

        # CHECK: coucou
        print_("coucou")
        # CHECK: héllo 
        print_("héllo")

        buf = u"héllo".encode("utf8")
        # CHECK: 68 C3 A9 6C 6C 6F
        print_u8(buf, len(buf))

        buf = bytearray(b"hello")
        bytesupper(buf)
        self.assertEqual(buf, b"HELLO")

        buf = bytearray(b"hello")
        buf_char = pydffi.view_as(self.FFI.arrayType(self.FFI.UInt8Ty, len(buf)), buf)
        strupper(pydffi.cast(pydffi.ptr(buf_char),self.FFI.CharPtrTy))
        self.assertEqual(buf, b"HELLO")
Example #12
0
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!
print_struct(buf)
Example #13
0
  struct A a;
  strcpy(a.buf, "hello");
  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)
Example #14
0
  Res Ret = {a,b,res};
  return Ret;
}

static Res add(int a, int b) {
  return get_res(a+b,a,b);
}
static Res sub(int a, int b) {
  return get_res(a-b,a,b);
}

op get_op(unsigned Id)
{
  if (Id == 0) return add;
  if (Id == 1) return sub;
  return 0;
}

Res call(op f, int a, int b) {
  return f(a,b);
}
''')

Add=CU.funcs.get_op(0)
Add=Add.obj
Res=Add(1,4)
assert(Res.res == 5)

Res=CU.funcs.call(pydffi.ptr(CU.funcs.sub), 1, 5)
assert(Res.res == -4)
Example #15
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" | "%FileCheck" "%s"

import pydffi
FFI = pydffi.FFI()
CU = FFI.compile('''
#include <stdio.h>
typedef int int2[2];
int foo(int2* ar)
{
    printf("%d %d\\n", ar[0][0], ar[0][1]);
}
''')

v = CU.types.int2()
v.set(0, 1)
v.set(1, 2)
# CHECK: 1 2
CU.funcs.foo(pydffi.ptr(v))

v[0] = 10
v[1] = 20
# CHECK: 10 20
CU.funcs.foo(pydffi.ptr(v))
Example #16
0
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
getattr(CU.funcs, "print")(Av)
assert (Av.a == 59)
assert (Av.b == 1111)

Av = CU.funcs.init()
assert (Av.a == 44)
assert (Av.b == 5555)
Example #17
0
}

void strupper(char* S) {
    bytesupper(S);
}
''')
print_ = getattr(CU.funcs, "print")
print_u8 = CU.funcs.print_u8
bytesupper = CU.funcs.bytesupper
strupper = CU.funcs.strupper

# CHECK: coucou
print_("coucou")
# CHECK: héllo 
print_("héllo")

buf = u"héllo".encode("utf8")
# CHECK: 68 C3 A9 6C 6C 6F
print_u8(buf, len(buf))

buf = bytearray(b"hello")
# CHECK: 5
bytesupper(buf)
assert(buf == b"HELLO")

buf = bytearray(b"hello")
buf_char = pydffi.view_as(FFI.arrayType(FFI.UInt8Ty, len(buf)), buf)
# CHECK: 5
strupper(pydffi.cast(pydffi.ptr(buf_char),FFI.CharPtrTy))
assert(buf == b"HELLO")
Example #18
0
# REQUIRES: linux
# RUN: %python "%s" "%S" |%FileCheck "%s"

# CHECK: readdir.py

import pydffi
import sys

D = pydffi.FFI()
CU = D.cdef("#include <dirent.h>")

dir_ = CU.funcs.opendir(sys.argv[1])
if not dir_:
    print("error reading directory")
    sys.exit(1)
readdir = CU.funcs.readdir
while True:
    dirent = readdir(dir_)
    if not dirent:
        break
    name = dirent.obj.d_name
    name = pydffi.cast(pydffi.ptr(name), D.CharPtrTy)
    print(name.cstr.tobytes())
CU.funcs.closedir(dir_)
Example #19
0
 def cstr_from_array(self, ar):
     return pydffi.cast(pydffi.ptr(ar), self.FFI.CharPtrTy).cstr
Example #20
0
import pydffi
import sys

pydffi.dlopen("/usr/lib/x86_64-linux-gnu/libarchive.so")
D = pydffi.FFI()
CU = D.cdef('''
#include <archive.h>
#include <archive_entry.h>
''')

funcs = CU.funcs
archive_read_next_header = funcs.archive_read_next_header
archive_entry_pathname_utf8 = funcs.archive_entry_pathname_utf8
archive_read_data_skip = funcs.archive_read_data_skip

a = funcs.archive_read_new()
funcs.archive_read_support_filter_all(a)
funcs.archive_read_support_format_all(a)
r = funcs.archive_read_open_filename(a, sys.argv[1], 10240)
if r != 0:
    raise RuntimeError("unable to open archive")
entry = pydffi.ptr(CU.types.archive_entry)()
while archive_read_next_header(a, pydffi.ptr(entry)) == 0:
    pathname = archive_entry_pathname_utf8(entry)
    print(pathname.cstr.tobytes().decode("utf8"))
    archive_read_data_skip(a)
funcs.archive_read_free(a)