Arquivos
hhvm/hphp/system/classes/directoryiterator.php
T
Paul Tarjan 7f4e3c39d6 implement SplFileObject
This diff started off with trying to actually build `SplFileObject` since it was just stubbed out. But then I had to implement everything that extended from it since C++ classes can't extend PHP classes. And then it ballooend into what you see here. I actually think this is better in the long run, so that's why I kept going down this road.

The only thing that doesn't work in pure PHP is `sscanf`. @mwilliams has a fix for that. We need variable args by reference.

I implemented `RecursiveIteratorIterator` in a similar way to our C++ code instead of copying Zend. It translated to PHP a bit nicer. We still don't support the `RecursiveTreeIterator`, but I havn't come accross a need for that yet. I changed the implementation to actually use the `getChildren()` methods instead of peaking inside the `RecursiveDirectoryIterator`.
2013-06-03 10:55:24 -07:00

455 linhas
13 KiB
PHP

<?php
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/class.directoryiterator.php )
*
* The DirectoryIterator class provides a simple interface for viewing the
* contents of filesystem directories.
*
*/
class DirectoryIterator extends SplFileInfo
implements Traversable, SeekableIterator {
private $dir;
private $dirName;
private $index;
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/directoryiterator.construct.php
* )
*
* Constructs a new directory iterator from a path.
*
* @path mixed The path of the directory to traverse.
*/
public function __construct($path) {
// next() will fill in the correct filename
parent::__construct(null);
if (!is_dir($path)) {
throw new UnexpectedValueException(
"DirectoryIterator::__construct($path): failed to open dir"
);
}
$this->dirName = rtrim($path, DIRECTORY_SEPARATOR);
$this->dir = opendir($path);
$this->rewind();
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/directoryiterator.current.php )
*
* Get the current DirectoryIterator item.
*
* @return mixed The current DirectoryIterator item.
*/
public function current() {
return clone $this;
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/directoryiterator.key.php )
*
* Get the key for the current DirectoryIterator item.
*
* @return mixed The key for the current DirectoryIterator item.
*/
public function key() {
return $this->index;
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/directoryiterator.next.php )
*
* Move forward to the next DirectoryIterator item.
*
* @return mixed No value is returned.
*/
public function next() {
$file_name = readdir($this->dir);
if ($file_name === false) {
$this->setPathname(false);
} else {
$this->setPathname($this->dirName.DIRECTORY_SEPARATOR.$file_name);
}
$this->index++;
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/directoryiterator.rewind.php )
*
* Rewind the DirectoryIterator back to the start.
*
* @return mixed No value is returned.
*/
public function rewind() {
rewinddir($this->dir);
$this->index = -1;
$this->next();
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/directoryiterator.seek.php )
*
* Seek to a given position in the DirectoryIterator.
*
* @position mixed The zero-based numeric position to seek to.
*
* @return mixed No value is returned.
*/
public function seek($position) {
for ($i = $this->index; $i < $position; $i++) {
$this->next();
}
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/directoryiterator.tostring.php )
*
* Get the file name of the current DirectoryIterator item.
*
* @return mixed Returns the file name of the current
* DirectoryIterator item.
*/
public function __toString() {
return $this->getFilename();
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/directoryiterator.valid.php )
*
* Check whether current DirectoryIterator position is a valid file.
*
* @return mixed Returns TRUE if the position is valid, otherwise
* FALSE
*/
public function valid() {
return $this->getPathname() !== false;
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/directoryiterator.isdot.php )
*
* Determines if the current DirectoryIterator item is a directory and
* either . or ...
*
* @return mixed TRUE if the entry is . or .., otherwise FALSE
*/
public function isDot() {
return $this->getFilename() == '.' || $this->getFilename() == '..';
}
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/class.filesystemiterator.php )
*
* The Filesystem iterator
*
*/
class FilesystemIterator extends DirectoryIterator
implements SeekableIterator, Traversable, Iterator {
const CURRENT_AS_PATHNAME = 32;
const CURRENT_AS_FILEINFO = 0;
const CURRENT_AS_SELF = 16;
const CURRENT_MODE_MASK = 240;
const KEY_AS_PATHNAME = 0;
const KEY_AS_FILENAME = 256;
const FOLLOW_SYMLINKS = 512;
const KEY_MODE_MASK = 3840;
const NEW_CURRENT_AND_KEY = 256;
const SKIP_DOTS = 4096;
const UNIX_PATHS = 8192;
private $flags;
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/filesystemiterator.construct.php
* )
*
* Constructs a new filesystem iterator from the path.
*
* @path mixed The path of the filesystem item to be iterated over.
* @flags mixed Flags may be provided which will affect the behavior
* of some methods. A list of the flags can found under
* FilesystemIterator predefined constants. They can
* also be set later with
* FilesystemIterator::setFlags()
*
* @return mixed No value is returned.
*/
public function __construct(string $path, int $flags = null) {
parent::__construct($path);
if ($flags === null) {
$flags = FilesystemIterator::KEY_AS_PATHNAME |
FilesystemIterator::CURRENT_AS_FILEINFO |
FilesystemIterator::SKIP_DOTS;
}
$this->flags = $flags;
$this->goPastDotsIfNeeded();
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/filesystemiterator.current.php )
*
* Get file information of the current element.
*
* @return mixed The filename, file information, or $this depending
* on the set flags. See the FilesystemIterator
* constants.
*/
public function current() {
$f = parent::current();
if ($this->flags & FilesystemIterator::CURRENT_AS_PATHNAME) {
return $f->getPathname();
} else if ($this->flags & FilesystemIterator::CURRENT_AS_SELF) {
return $this;
}
// FilesystemIterator::CURRENT_AS_FILEINFO == 0
return $f;
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/filesystemiterator.getflags.php
* )
*
* Gets the handling flags, as set in FilesystemIterator::__construct() or
* FilesystemIterator::setFlags().
*
* @return mixed The integer value of the set flags.
*/
public function getFlags() {
return $this->flags;
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/filesystemiterator.key.php )
*
*
* @return mixed Returns the pathname or filename depending on the
* set flags. See the FilesystemIterator constants.
*/
public function key() {
if ($this->flags & FilesystemIterator::KEY_AS_FILENAME) {
return parent::current()->getFileName();
}
// FilesystemIterator::KEY_AS_PATHNAME == 0
return parent::current()->getPathName();
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/filesystemiterator.next.php )
*
* Move to the next file.
*
* @return mixed No value is returned.
*/
public function next() {
parent::next();
$this->goPastDotsIfNeeded();
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/filesystemiterator.rewind.php )
*
* Rewinds the directory back to the start.
*
* @return mixed No value is returned.
*/
public function rewind() {
parent::rewind();
$this->goPastDotsIfNeeded();
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from http://php.net/manual/en/filesystemiterator.setflags.php
* )
*
* Sets handling flags.
*
* @flags mixed The handling flags to set. See the
* FilesystemIterator constants.
*
* @return mixed No value is returned.
*/
public function setFlags(int $flags) {
$this->flags = $flags;
}
private function goPastDotsIfNeeded() {
if ($this->flags & FilesystemIterator::SKIP_DOTS) {
$f = parent::current();
while ($f && $f->isDot()) {
parent::next();
$f = parent::current();
}
}
}
public function __toString() {
return $this->getPathname();
}
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from
* http://php.net/manual/en/class.recursivedirectoryiterator.php )
*
* The RecursiveDirectoryIterator provides an interface for iterating
* recursively over filesystem directories.
*
*/
class RecursiveDirectoryIterator extends FilesystemIterator
implements RecursiveIterator {
const FOLLOW_SYMLINKS = 512;
private $subPath;
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from
* http://php.net/manual/en/recursivedirectoryiterator.construct.php )
*
* Constructs a RecursiveDirectoryIterator() for the provided path.
*
* @path mixed The path of the directory to be iterated over.
* @flags mixed Flags may be provided which will affect the behavior
* of some methods. A list of the flags can found under
* FilesystemIterator predefined constants. They can
* also be set later with
* FilesystemIterator::setFlags().
*
* @return mixed Returns the newly created
* RecursiveDirectoryIterator.
*/
public function __construct($path, $flags = null) {
if ($flags === null) {
$flags = FilesystemIterator::KEY_AS_PATHNAME |
FilesystemIterator::CURRENT_AS_FILEINFO;
}
parent::__construct($path, $flags);
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from
* http://php.net/manual/en/recursivedirectoryiterator.haschildren.php )
*
*
* @return mixed Returns whether the current entry is a directory,
* but not '.' or '..'
*/
public function hasChildren() {
if ($this->isDot()) {
return false;
}
if (is_link($this->getFilename()) &&
!($this->flags & self::FOLLOW_SYMLINKS)) {
return false;
}
return $this->isDir();
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from
* http://php.net/manual/en/recursivedirectoryiterator.getchildren.php )
*
*
* @return mixed The filename, file information, or $this depending
* on the set flags. See the FilesystemIterator
* constants.
*/
public function getChildren() {
if ($this->getFlags() & FilesystemIterator::CURRENT_AS_PATHNAME) {
return $this->current();
}
$child = new self($this->getPathname(), $this->getFlags());
$child->subPath = $this->subPath;
if ($child->subPath) {
$child->subPath .= DIRECTORY_SEPARATOR;
}
$child->subPath .= $this->getPathname();
return $child;
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from
* http://php.net/manual/en/recursivedirectoryiterator.getsubpath.php )
*
* Gets the sub path. WarningThis function is currently not documented;
* only its argument list is available.
*
* @return mixed The sub path (sub directory).
*/
public function getSubPath() {
return $this->subPath;
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from
* http://php.net/manual/en/recursivedirectoryiterator.getsubpathname.php )
*
* Gets the sub path and filename. WarningThis function is currently not
* documented; only its argument list is available.
*
* @return mixed The sub path (sub directory) and filename.
*/
public function getSubPathname() {
return ($this->subPath ? $this->subPath . DIRECTORY_SEPARATOR : '') .
$this->getPathname();
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from
* http://php.net/manual/en/recursivedirectoryiterator.rewind.php )
*
*
* @return mixed No value is returned.
*/
public function rewind() {
parent::rewind();
if ($this->isDot()) {
$this->next();
}
}
// This doc comment block generated by idl/sysdoc.php
/**
* ( excerpt from
* http://php.net/manual/en/recursivedirectoryiterator.next.php )
*
*
* @return mixed No value is returned.
*/
public function next() {
do {
parent::next();
} while ($this->valid() && $this->isDot());
}
}