use system.dos_attr.* for both mode and stat info

this enables getting all the info needed for the FileInfo in a single request, instead of requiring two
This commit is contained in:
Robin Appelman 2020-03-24 16:29:44 +01:00
commit b594f7c408
2 changed files with 30 additions and 36 deletions

View file

@ -11,8 +11,6 @@ use Icewind\SMB\ACL;
use Icewind\SMB\IFileInfo;
class NativeFileInfo implements IFileInfo {
const MODE_FILE = 0100000;
/**
* @var string
*/
@ -31,10 +29,7 @@ class NativeFileInfo implements IFileInfo {
/**
* @var array|null
*/
protected $statCache = null;
/** @var callable|null */
protected $statCallback = null;
protected $attributeCache = null;
/**
* @var int
@ -45,20 +40,11 @@ class NativeFileInfo implements IFileInfo {
* @param NativeShare $share
* @param string $path
* @param string $name
* @param array|callable $stat
*/
public function __construct($share, $path, $name, $stat) {
public function __construct($share, $path, $name) {
$this->share = $share;
$this->path = $path;
$this->name = $name;
if (is_array($stat)) {
$this->statCache = $stat;
} elseif (is_callable($stat)) {
$this->statCallback = $stat;
} else {
throw new \InvalidArgumentException('$stat needs to be an array or callback');
}
}
/**
@ -79,10 +65,20 @@ class NativeFileInfo implements IFileInfo {
* @return array
*/
protected function stat() {
if (is_null($this->statCache)) {
$this->statCache = call_user_func($this->statCallback);
if (is_null($this->attributeCache)) {
$rawAttributes = explode(',', $this->share->getAttribute($this->path, 'system.dos_attr.*'));
$this->attributeCache = [];
foreach ($rawAttributes as $rawAttribute) {
[$name, $value] = explode(':', $rawAttribute);
$name = strtolower($name);
if ($name == 'mode') {
$this->attributeCache[$name] = (int)hexdec(substr($value, 2));
} else {
$this->attributeCache[$name] = (int)$value;
}
return $this->statCache;
}
}
return $this->attributeCache;
}
/**
@ -98,27 +94,22 @@ class NativeFileInfo implements IFileInfo {
*/
public function getMTime() {
$stat = $this->stat();
return $stat['mtime'];
}
/**
* @return bool
*/
public function isDirectory() {
$stat = $this->stat();
return !($stat['mode'] & self::MODE_FILE);
return $stat['change_time'];
}
/**
* @return int
*/
protected function getMode() {
if (!$this->modeCache) {
$attribute = $this->share->getAttribute($this->path, 'system.dos_attr.mode');
// parse hex string
$this->modeCache = (int)hexdec(substr($attribute, 2));
return $this->stat()['mode'];
}
return $this->modeCache;
/**
* @return bool
*/
public function isDirectory() {
$mode = $this->getMode();
return (bool)($mode & IFileInfo::MODE_DIRECTORY);
}
/**

View file

@ -94,9 +94,7 @@ class NativeShare extends AbstractShare {
$name = $file['name'];
if ($name !== '.' and $name !== '..') {
$fullPath = $path . '/' . $name;
$files [] = new NativeFileInfo($this, $fullPath, $name, function () use ($fullPath) {
return $this->getStat($fullPath);
});
$files [] = new NativeFileInfo($this, $fullPath, $name);
}
}
@ -109,7 +107,12 @@ class NativeShare extends AbstractShare {
* @return \Icewind\SMB\IFileInfo
*/
public function stat($path) {
return new NativeFileInfo($this, $path, self::mb_basename($path), $this->getStat($path));
$info = new NativeFileInfo($this, $path, self::mb_basename($path));
// trigger attribute loading
$info->getSize();
return $info;
}
/**