summaryrefslogtreecommitdiff
path: root/ext/ffi/tests/list.phpt
blob: 8c6e2bed44027c2a8efd655da1fb2d4b8d87542f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
--TEST--
FFI Double linked lists
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--INI--
ffi.enable=1
--FILE--
<?php
class DList {
    private static $ffi = null;
    private $root;

    function __construct() {
        if (is_null(self::$ffi)) {
            self::$ffi =
                FFI::cdef("
                    typedef struct _dlist dlist;
                    struct _dlist {
                        int data;
                        dlist *prev;
                        dlist *next;
                    };
                ");
        }
        $node = FFI::addr(self::$ffi->new("dlist", false));
        $node->data = 0;
        $node->next = $node;
        $node->prev = $node;
        $this->root = $node;
    }

    function __destruct() {
        $root = $this->root;
        $node = $root->next;
        while ($node != $root) {
            $prev = $node;
            $node = $node->next;
            FFI::free($prev);
        }
        FFI::free($root);
    }

    function add(int $data) {
        $node = FFI::addr(self::$ffi->new("dlist", false));
        $node->data = $data;
        $node->next = $this->root;
        $node->prev = $this->root->prev;
        $this->root->prev->next = $node;
        $this->root->prev = $node;
    }

    function del(int $data) {
        $root = $this->root;
        $node = $root->next;
        while ($node != $root) {
            if ($node->data == $data) {
                $node->prev->next = $node->next;
                $node->next->prev = $node->prev;
                FFI::free($node);
                break;
            }
            $node = $node->next;
        }
    }

    function print() {
        echo "[";
        $first = true;
        $root = $this->root;
        $node = $root->next;
        while ($node != $root) {
            if (!$first) {
                echo ", ";
            } else {
                $first = false;
            }
            echo $node->data;
            $node = $node->next;
        }
        echo "]\n";
    }
}

$dlist = new Dlist;
$dlist->add(1);
$dlist->add(3);
$dlist->add(5);
$dlist->print();
$dlist->del(3);
$dlist->print();
echo "OK\n";
?>
--EXPECT--
[1, 3, 5]
[1, 5]
OK