Skip to content

Commit

Permalink
Merge pull request #1 from sj-i/add_new_api
Browse files Browse the repository at this point in the history
Add OO api
  • Loading branch information
sj-i authored Mar 1, 2021
2 parents c50db1e + 524bfb6 commit 63f7a31
Show file tree
Hide file tree
Showing 11 changed files with 1,797 additions and 25 deletions.
242 changes: 242 additions & 0 deletions example/array_fs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
<?php

/**
* This file is part of the sj-i/php-fuse package.
*
* (c) sji <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

use FFI\CData;
use Fuse\FilesystemDefaultImplementationTrait;
use Fuse\FilesystemInterface;
use Fuse\Fuse;
use Fuse\Mounter;

require 'vendor/autoload.php';

const ENOENT = 2;
const S_IFDIR = 0040000;
const S_IFREG = 0100000;

class ArrayFs implements FilesystemInterface
{
use FilesystemDefaultImplementationTrait;

private array $array;

public function __construct(array $array)
{
$this->array = $array;
}

public function getArray(): array
{
return $this->array;
}

public function getattr(string $path, \FFI\CData $stbuf): int
{
$typename = 'struct stat';
$type = Fuse::getInstance()->ffi->type(
$typename
);
$size = FFI::sizeof(
$type
);
echo "attr read {$path}" . PHP_EOL;

FFI::memset($stbuf, 0, $size);
if ($path === '/') {
$stbuf->st_mode = S_IFDIR | 0777;
$stbuf->st_nlink = 2;
$stbuf->st_uid = getmyuid();
$stbuf->st_gid = getmygid();
return 0;
}

$element = $this->getEntry($path);
if (is_null($element)) {
return -ENOENT;
}
if (is_array($element)) {
$stbuf->st_mode = S_IFDIR | 0777;
$stbuf->st_nlink = 2;
$stbuf->st_uid = getmyuid();
$stbuf->st_gid = getmygid();
return 0;
}
$stbuf->st_mode = S_IFREG | 0777;
$stbuf->st_nlink = 1;
$stbuf->st_size = strlen((string)$element);
$stbuf->st_uid = getmyuid();
$stbuf->st_gid = getmygid();
return 0;
}

private function &getRecursive(&$array, array $offsets, ?callable $operation = null)
{
$null = null;

$count = count($offsets);

if ($count === 0) {
return $null;
}
if ($count === 1) {
if (isset($array[$offsets[0]])) {
if (!is_null($operation)) {
return $operation($array, $offsets[0]);
} else {
return $array[$offsets[0]];
}
} else {
return $null;
}
}

$offset = array_shift($offsets);
if (is_array($array[$offset])) {
return $this->getRecursive($array[$offset], $offsets);
} else {
return $null;
}
}

/**
* @param string $path
* @return string|array|null
*/
private function &getEntry(string $path)
{
$splitted = explode('/', $path);
array_shift($splitted);
return $this->getRecursive($this->array, $splitted);
}

/**
* @param string $path
* @return string|array|null
*/
private function &getParentEntry(string $path)
{
$splitted = explode('/', $path);
array_shift($splitted);
array_pop($splitted);
if (count($splitted) === 0) {
return $this->array;
}
return $this->getRecursive($this->array, $splitted);
}

/**
* @param string $path
*/
private function unsetEntry(string $path): void
{
$splitted = explode('/', $path);
array_shift($splitted);
$this->getRecursive($this->array, $splitted, function &(array &$array, $index) {
$null = null;
unset($array[$index]);
return $null;
});
}

public function readdir(string $path, CData $buf, CData $filler, int $offset, CData $fi): int
{
$filler($buf, '.', null, 0);
$filler($buf, '..', null, 0);
foreach ($this->array as $key => $value) {
$filler($buf, (string)$key, null, 0);
}

return 0;
}

public function open(string $path, CData $fi): int
{
$entry = $this->getEntry($path);
if (!is_string($entry)) {
return -ENOENT;
}

echo "open {$path}" . PHP_EOL;
return 0;
}

public function read(string $path, CData $buf, int $size, int $offset, CData $fi): int
{
$entry = $this->getEntry($path);

echo "read {$path}" . PHP_EOL;

$len = strlen($entry);

if ($offset + $size > $len) {
$size = ($len - $offset);
}

$content = substr($entry, $offset, $size);
FFI::memcpy($buf, $content, $size);

return $size;
}

public function write(string $path, string $buffer, int $size, int $offset, CData $fuse_file_info): int
{
$entry = &$this->getEntry($path);
$entry = substr_replace($entry, $buffer, $offset, $size);

return $size;
}

public function create(string $path, int $mode, CData $fuse_file_info): int
{
$entry = &$this->getParentEntry($path);
if (is_array($entry)) {
$segments = explode('/', $path);
$filename = array_pop($segments);
$entry[$filename] = '';
return 0;
} else {
return ENOENT;
}
}

public function unlink(string $path): int
{
$this->unsetEntry($path);
return 0;
}

public function rename(string $from, string $to): int
{
$fromValue = $this->getEntry($from);
$parent_entry = &$this->getParentEntry($to);
if (is_array($parent_entry)) {
$segments = explode('/', $to);
$filename = array_pop($segments);
$parent_entry[$filename] = $fromValue;
$this->unsetEntry($from);
return 0;
} else {
return ENOENT;
}
}
}


$mounter = new Mounter();
$array_fs = new ArrayFs([
1,
2,
'foo' => 'bar',
]);
$result = $mounter->mount('/tmp/example/', $array_fs);
var_dump($array_fs->getArray());
return $result;
21 changes: 9 additions & 12 deletions example/dummy_file.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use FFI\CData;
use Fuse\Fuse;
use Fuse\FuseOperations;
use Fuse\Mounter;

const FILE_PATH = '/example';
const FILE_NAME = 'example';
Expand Down Expand Up @@ -80,16 +82,11 @@ function read_cb(string $path, CData $buf, int $size, int $offset, CData $fi)
return $size;
}

$fuse_operations = new FuseOperations();
$fuse_operations->getattr = 'getattr_cb';
$fuse_operations->open = 'open_cb';
$fuse_operations->read = 'read_cb';
$fuse_operations->readdir = 'readdir_cb';

$fuse_my_operations = Fuse::getInstance()->ffi->new('struct fuse_operations');
$fuse_my_operations->getattr = Closure::fromCallable('getattr_cb');
$fuse_my_operations->open = Closure::fromCallable('open_cb');
$fuse_my_operations->read = Closure::fromCallable('read_cb');
$fuse_my_operations->readdir = Closure::fromCallable('readdir_cb');

return Fuse::getInstance()->main(
$argc,
$argv,
$fuse_my_operations,
null
);
$mounter = new Mounter();
return $mounter->mount('/tmp/example/', $fuse_operations);
92 changes: 92 additions & 0 deletions example/dummy_file_oo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

include __DIR__ . "/../vendor/autoload.php";

use FFI\CData;
use Fuse\FilesystemDefaultImplementationTrait;
use Fuse\FilesystemInterface;
use Fuse\Fuse;
use Fuse\Mounter;

const FILE_PATH = '/example';
const FILE_NAME = 'example';
const FILE_CONTENT = 'hello FUSE from PHP' . PHP_EOL;

const ENOENT = 2;
const S_IFDIR = 0040000;
const S_IFREG = 0100000;

class DummyFs implements FilesystemInterface
{
use FilesystemDefaultImplementationTrait;

public function getattr(string $path, \FFI\CData $stbuf): int
{
$typename = 'struct stat';
$type = Fuse::getInstance()->ffi->type(
$typename
);
$size = FFI::sizeof(
$type
);
echo "attr read {$path}" . PHP_EOL;

FFI::memset($stbuf, 0, $size);
if ($path === '/') {
$stbuf->st_mode = S_IFDIR | 0755;
$stbuf->st_nlink = 2;
$stbuf->st_uid = getmyuid();
$stbuf->st_gid = getmygid();
return 0;
}

if ($path === FILE_PATH) {
$stbuf->st_mode = S_IFREG | 0777;
$stbuf->st_nlink = 1;
$stbuf->st_size = strlen(FILE_CONTENT);
$stbuf->st_uid = getmyuid();
$stbuf->st_gid = getmygid();
return 0;
}

return -ENOENT;
}

public function readdir(string $path, CData $buf, CData $filler, int $offset, CData $fi): int
{
$filler($buf, '.', null, 0);
$filler($buf, '..', null, 0);
$filler($buf, FILE_NAME, null, 0);

return 0;
}

public function open(string $path, CData $fi): int
{
if ($path !== FILE_PATH) {
return -ENOENT;
}

echo "open {$path}" . PHP_EOL;
return 0;
}

public function read(string $path, CData $buf, int $size, int $offset, CData $fi): int
{
echo "read {$path}" . PHP_EOL;

$len = strlen(FILE_CONTENT);

if ($offset + $size > $len) {
$size = ($len - $offset);
}

$content = substr(FILE_CONTENT, $offset, $size);
FFI::memcpy($buf, $content, $size);

return $size;
}
}

$mounter = new Mounter();
return $mounter->mount('/tmp/example/', new DummyFs());
Loading

0 comments on commit 63f7a31

Please sign in to comment.