1--TEST-- 2FFI Double linked lists 3--SKIPIF-- 4<?php require_once('skipif.inc'); ?> 5--INI-- 6ffi.enable=1 7--FILE-- 8<?php 9class DList { 10 private static $ffi = null; 11 private $root; 12 13 function __construct() { 14 if (is_null(self::$ffi)) { 15 self::$ffi = 16 FFI::cdef(" 17 typedef struct _dlist dlist; 18 struct _dlist { 19 int data; 20 dlist *prev; 21 dlist *next; 22 }; 23 "); 24 } 25 $node = FFI::addr(self::$ffi->new("dlist", false)); 26 $node->data = 0; 27 $node->next = $node; 28 $node->prev = $node; 29 $this->root = $node; 30 } 31 32 function __destruct() { 33 $root = $this->root; 34 $node = $root->next; 35 while ($node != $root) { 36 $prev = $node; 37 $node = $node->next; 38 FFI::free($prev); 39 } 40 FFI::free($root); 41 } 42 43 function add(int $data) { 44 $node = FFI::addr(self::$ffi->new("dlist", false)); 45 $node->data = $data; 46 $node->next = $this->root; 47 $node->prev = $this->root->prev; 48 $this->root->prev->next = $node; 49 $this->root->prev = $node; 50 } 51 52 function del(int $data) { 53 $root = $this->root; 54 $node = $root->next; 55 while ($node != $root) { 56 if ($node->data == $data) { 57 $node->prev->next = $node->next; 58 $node->next->prev = $node->prev; 59 FFI::free($node); 60 break; 61 } 62 $node = $node->next; 63 } 64 } 65 66 function print() { 67 echo "["; 68 $first = true; 69 $root = $this->root; 70 $node = $root->next; 71 while ($node != $root) { 72 if (!$first) { 73 echo ", "; 74 } else { 75 $first = false; 76 } 77 echo $node->data; 78 $node = $node->next; 79 } 80 echo "]\n"; 81 } 82} 83 84$dlist = new Dlist; 85$dlist->add(1); 86$dlist->add(3); 87$dlist->add(5); 88$dlist->print(); 89$dlist->del(3); 90$dlist->print(); 91echo "OK\n"; 92--EXPECT-- 93[1, 3, 5] 94[1, 5] 95OK 96