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; use Icewind\SMB\IFileInfo;
class NativeFileInfo implements IFileInfo { class NativeFileInfo implements IFileInfo {
const MODE_FILE = 0100000;
/** /**
* @var string * @var string
*/ */
@ -31,10 +29,7 @@ class NativeFileInfo implements IFileInfo {
/** /**
* @var array|null * @var array|null
*/ */
protected $statCache = null; protected $attributeCache = null;
/** @var callable|null */
protected $statCallback = null;
/** /**
* @var int * @var int
@ -45,20 +40,11 @@ class NativeFileInfo implements IFileInfo {
* @param NativeShare $share * @param NativeShare $share
* @param string $path * @param string $path
* @param string $name * @param string $name
* @param array|callable $stat
*/ */
public function __construct($share, $path, $name, $stat) { public function __construct($share, $path, $name) {
$this->share = $share; $this->share = $share;
$this->path = $path; $this->path = $path;
$this->name = $name; $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 * @return array
*/ */
protected function stat() { protected function stat() {
if (is_null($this->statCache)) { if (is_null($this->attributeCache)) {
$this->statCache = call_user_func($this->statCallback); $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() { public function getMTime() {
$stat = $this->stat(); $stat = $this->stat();
return $stat['mtime']; return $stat['change_time'];
}
/**
* @return bool
*/
public function isDirectory() {
$stat = $this->stat();
return !($stat['mode'] & self::MODE_FILE);
} }
/** /**
* @return int * @return int
*/ */
protected function getMode() { protected function getMode() {
if (!$this->modeCache) { return $this->stat()['mode'];
$attribute = $this->share->getAttribute($this->path, 'system.dos_attr.mode'); }
// parse hex string
$this->modeCache = (int)hexdec(substr($attribute, 2)); /**
} * @return bool
return $this->modeCache; */
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']; $name = $file['name'];
if ($name !== '.' and $name !== '..') { if ($name !== '.' and $name !== '..') {
$fullPath = $path . '/' . $name; $fullPath = $path . '/' . $name;
$files [] = new NativeFileInfo($this, $fullPath, $name, function () use ($fullPath) { $files [] = new NativeFileInfo($this, $fullPath, $name);
return $this->getStat($fullPath);
});
} }
} }
@ -109,7 +107,12 @@ class NativeShare extends AbstractShare {
* @return \Icewind\SMB\IFileInfo * @return \Icewind\SMB\IFileInfo
*/ */
public function stat($path) { 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;
} }
/** /**