CC-2166: Packaging Improvements. Moved the Zend app into airtime_mvc. It is now installed to /var/www/airtime. Storage is now set to /srv/airtime/stor. Utils are now installed to /usr/lib/airtime/utils/. Added install/airtime-dircheck.php as a simple test to see if everything is install/uninstalled correctly.

This commit is contained in:
Paul Baranowski 2011-04-14 18:55:04 -04:00
parent 514777e8d2
commit b11cbd8159
4546 changed files with 138 additions and 51 deletions

View file

@ -0,0 +1,168 @@
<?php
/*
* $Id: BufferedReader.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/Reader.php';
/**
* Convenience class for reading files.
*
* @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
* @version $Revision: 905 $ $Date: 2010-10-05 18:28:03 +0200 (Tue, 05 Oct 2010) $
* @access public
* @see FilterReader
* @package phing.system.io
*/
class BufferedReader extends Reader {
private $bufferSize = 0;
private $buffer = null;
private $bufferPos = 0;
/**
* The Reader we are buffering for.
*/
private $in;
/**
*
* @param object $reader The reader (e.g. FileReader).
* @param integer $buffsize The size of the buffer we should use for reading files.
* A large buffer ensures that most files (all scripts?) are parsed in 1 buffer.
*/
function __construct(Reader $reader, $buffsize = 65536) {
$this->in = $reader;
$this->bufferSize = $buffsize;
}
/**
* Reads and returns a chunk of data.
* @param int $len Number of bytes to read. Default is to read configured buffer size number of bytes.
* @return mixed buffer or -1 if EOF.
*/
function read($len = null) {
// if $len is specified, we'll use that; otherwise, use the configured buffer size.
if ($len === null) $len = $this->bufferSize;
if ( ($data = $this->in->read($len)) !== -1 ) {
// not all files end with a newline character, so we also need to check EOF
if (!$this->in->eof()) {
$notValidPart = strrchr($data, "\n");
$notValidPartSize = strlen($notValidPart);
if ( $notValidPartSize > 1 ) {
// Block doesn't finish on a EOL
// Find the last EOL and forget all following stuff
$dataSize = strlen($data);
$validSize = $dataSize - $notValidPartSize + 1;
$data = substr($data, 0, $validSize);
// Rewind to the begining of the forgotten stuff.
$this->in->skip(-$notValidPartSize+1);
}
} // if !EOF
}
return $data;
}
function skip($n) {
return $this->in->skip($n);
}
function reset() {
return $this->in->reset();
}
function close() {
return $this->in->close();
}
function open() {
return $this->in->open();
}
/**
* Read a line from input stream.
*/
function readLine() {
$line = null;
while ( ($ch = $this->readChar()) !== -1 ) {
if ( $ch === "\n" ) {
break;
}
$line .= $ch;
}
// Warning : Not considering an empty line as an EOF
if ( $line === null && $ch !== -1 )
return "";
return $line;
}
/**
* Reads a single char from the reader.
* @return string single char or -1 if EOF.
*/
function readChar() {
if ( $this->buffer === null ) {
// Buffer is empty, fill it ...
$read = $this->in->read($this->bufferSize);
if ($read === -1) {
$ch = -1;
} else {
$this->buffer = $read;
return $this->readChar(); // recurse
}
} else {
// Get next buffered char ...
// handle case where buffer is read-in, but is empty. The next readChar() will return -1 EOF,
// so we just return empty string (char) at this point. (Probably could also return -1 ...?)
$ch = ($this->buffer !== "") ? $this->buffer{$this->bufferPos} : '';
$this->bufferPos++;
if ( $this->bufferPos >= strlen($this->buffer) ) {
$this->buffer = null;
$this->bufferPos = 0;
}
}
return $ch;
}
/**
* Returns whether eof has been reached in stream.
* This is important, because filters may want to know if the end of the file (and not just buffer)
* has been reached.
* @return boolean
*/
function eof() {
return $this->in->eof();
}
function getResource() {
return $this->in->getResource();
}
}

View file

@ -0,0 +1,71 @@
<?php
/*
* $Id: BufferedWriter.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/Writer.php';
/**
* Convenience class for writing files.
*
* @author Hans Lellelid <hans@xmpl.org>
* @version $Revision: 905 $
* @package phing.system.io
*/
class BufferedWriter extends Writer {
/**
* The size of the buffer in kb.
*/
private $bufferSize = 0;
/**
* @var Writer The Writer we are buffering output to.
*/
private $out;
public function __construct(Writer $writer, $buffsize = 8192) {
$this->out = $writer;
$this->bufferSize = $buffsize;
}
public function write($buf, $off = null, $len = null) {
return $this->out->write($buf, $off, $len);
}
public function newLine() {
$this->write(PHP_EOL);
}
public function getResource() {
return $this->out->getResource();
}
public function flush() {
$this->out->flush();
}
/**
* Close attached stream.
*/
public function close() {
return $this->out->close();
}
}

View file

@ -0,0 +1,84 @@
<?php
/*
* $Id: ConsoleReader.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/Reader.php';
/**
* Convenience class for reading console input.
*
* @author Hans Lellelid <hans@xmpl.org>
* @author Matthew Hershberger <matthewh@lightsp.com>
* @version $Revision: 905 $
* @package phing.system.io
*/
class ConsoleReader extends Reader {
function readLine() {
$out = fgets(STDIN); // note: default maxlen is 1kb
$out = rtrim($out);
return $out;
}
/**
*
* @param int $len Num chars to read.
* @return string chars read or -1 if eof.
*/
function read($len = null) {
$out = fread(STDIN, $len);
return $out;
// FIXME
// read by chars doesn't work (yet?) with PHP stdin. Maybe
// this is just a language feature, maybe there's a way to get
// ability to read chars w/o <enter> ?
}
function close() {
// STDIN is always open
}
function open() {
// STDIN is always open
}
/**
* Whether eof has been reached with stream.
* @return boolean
*/
function eof() {
return feof(STDIN);
}
/**
* Returns path to file we are reading.
* @return string
*/
function getResource() {
return "console";
}
}

View file

@ -0,0 +1,76 @@
<?php
/*
* $Id: FileInputStream.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
require_once 'phing/system/io/InputStream.php';
require_once 'phing/system/io/PhingFile.php';
/**
* Input stream subclass for file streams.
*
* @package phing.system.io
*/
class FileInputStream extends InputStream {
/**
* @var PhingFile The associated file.
*/
protected $file;
/**
* Construct a new FileInputStream.
* @param mixed $file
* @throws Exception - if invalid argument specified.
* @throws IOException - if unable to open file.
*/
public function __construct($file, $append = false) {
if ($file instanceof PhingFile) {
$this->file = $file;
} elseif (is_string($file)) {
$this->file = new PhingFile($file);
} else {
throw new Exception("Invalid argument type for \$file.");
}
$stream = @fopen($this->file->getAbsolutePath(), "rb");
if ($stream === false) {
throw new IOException("Unable to open " . $this->file->__toString() . " for reading: " . $php_errormsg);
}
parent::__construct($stream);
}
/**
* Returns a string representation of the attached file.
* @return string
*/
public function __toString() {
return $this->file->getPath();
}
/**
* Mark is supported by FileInputStream.
* @return boolean TRUE
*/
public function markSupported() {
return true;
}
}

View file

@ -0,0 +1,71 @@
<?php
/*
* $Id: FileOutputStream.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
require_once 'phing/system/io/OutputStream.php';
require_once 'phing/system/io/PhingFile.php';
/**
* Output stream subclass for file streams.
*
* @package phing.system.io
*/
class FileOutputStream extends OutputStream {
/**
* @var PhingFile The associated file.
*/
protected $file;
/**
* Construct a new FileOutputStream.
* @param mixed $file
* @param boolean $append Whether to append bytes to end of file rather than beginning.
* @throws Exception - if invalid argument specified.
* @throws IOException - if unable to open file.
*/
public function __construct($file, $append = false) {
if ($file instanceof PhingFile) {
$this->file = $file;
} elseif (is_string($file)) {
$this->file = new PhingFile($file);
} else {
throw new Exception("Invalid argument type for \$file.");
}
if ($append) {
$stream = @fopen($this->file->getAbsolutePath(), "ab");
} else {
$stream = @fopen($this->file->getAbsolutePath(), "wb");
}
if ($stream === false) {
throw new IOException("Unable to open " . $this->file->__toString() . " for writing: " . $php_errormsg);
}
parent::__construct($stream);
}
/**
* Returns a string representation of the attached file.
* @return string
*/
public function __toString() {
return $this->file->getPath();
}
}

View file

@ -0,0 +1,41 @@
<?php
/*
* $Id: FileReader.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
require_once 'phing/system/io/InputStreamReader.php';
require_once 'phing/system/io/FileInputStream.php';
/**
* Convenience class for reading files.
* @package phing.system.io
*/
class FileReader extends InputStreamReader {
/**
* Construct a new FileReader.
* @param mixed $file PhingFile or string pathname.
*/
public function __construct($file) {
$in = new FileInputStream($file);
parent::__construct($in);
}
}

View file

@ -0,0 +1,757 @@
<?php
/*
* $Id: FileSystem.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* This is an abstract class for platform specific filesystem implementations
* you have to implement each method in the platform specific filesystem implementation
* classes Your local filesytem implementation must extend this class.
* You should also use this class as a template to write your local implementation
* Some native PHP filesystem specific methods are abstracted here as well. Anyway
* you _must_ always use this methods via a PhingFile object (that by nature uses the
* *FileSystem drivers to access the real filesystem via this class using natives.
*
* FIXME:
* - Error handling reduced to min fallthrough runtime excetions
* more precise errorhandling is done by the PhingFile class
*
* @author Charlie Killian <charlie@tizac.com>
* @author Hans Lellelid <hans@xmpl.org>
* @version $Revision: 905 $
* @package phing.system.io
*/
abstract class FileSystem {
/* properties for simple boolean attributes */
const BA_EXISTS = 0x01;
const BA_REGULAR = 0x02;
const BA_DIRECTORY = 0x04;
const BA_HIDDEN = 0x08;
/** Instance for getFileSystem() method. */
private static $fs;
/**
* Static method to return the FileSystem singelton representing
* this platform's local filesystem driver.
* @return FileSystem
*/
public static function getFileSystem() {
if (self::$fs === null) {
switch(Phing::getProperty('host.fstype')) {
case 'UNIX':
include_once 'phing/system/io/UnixFileSystem.php';
self::$fs = new UnixFileSystem();
break;
case 'WIN32':
include_once 'phing/system/io/Win32FileSystem.php';
self::$fs = new Win32FileSystem();
break;
case 'WINNT':
include_once 'phing/system/io/WinNTFileSystem.php';
self::$fs = new WinNTFileSystem();
break;
default:
throw new Exception("Host uses unsupported filesystem, unable to proceed");
}
}
return self::$fs;
}
/* -- Normalization and construction -- */
/**
* Return the local filesystem's name-separator character.
*/
abstract function getSeparator();
/**
* Return the local filesystem's path-separator character.
*/
abstract function getPathSeparator();
/**
* Convert the given pathname string to normal form. If the string is
* already in normal form then it is simply returned.
*/
abstract function normalize($strPath);
/**
* Compute the length of this pathname string's prefix. The pathname
* string must be in normal form.
*/
abstract function prefixLength($pathname);
/**
* Resolve the child pathname string against the parent.
* Both strings must be in normal form, and the result
* will be a string in normal form.
*/
abstract function resolve($parent, $child);
/**
* Resolve the given abstract pathname into absolute form. Invoked by the
* getAbsolutePath and getCanonicalPath methods in the PhingFile class.
*/
abstract function resolveFile(PhingFile $f);
/**
* Return the parent pathname string to be used when the parent-directory
* argument in one of the two-argument PhingFile constructors is the empty
* pathname.
*/
abstract function getDefaultParent();
/**
* Post-process the given URI path string if necessary. This is used on
* win32, e.g., to transform "/c:/foo" into "c:/foo". The path string
* still has slash separators; code in the PhingFile class will translate them
* after this method returns.
*/
abstract function fromURIPath($path);
/* -- Path operations -- */
/**
* Tell whether or not the given abstract pathname is absolute.
*/
abstract function isAbsolute(PhingFile $f);
/**
* canonicalize filename by checking on disk
* @return mixed Canonical path or false if the file doesn't exist.
*/
function canonicalize($strPath) {
return @realpath($strPath);
}
/* -- Attribute accessors -- */
/**
* Return the simple boolean attributes for the file or directory denoted
* by the given abstract pathname, or zero if it does not exist or some
* other I/O error occurs.
*/
function getBooleanAttributes($f) {
throw new Exception("SYSTEM ERROR method getBooleanAttributes() not implemented by fs driver");
}
/**
* Check whether the file or directory denoted by the given abstract
* pathname may be accessed by this process. If the second argument is
* false, then a check for read access is made; if the second
* argument is true, then a check for write (not read-write)
* access is made. Return false if access is denied or an I/O error
* occurs.
*/
function checkAccess(PhingFile $f, $write = false) {
// we clear stat cache, its expensive to look up from scratch,
// but we need to be sure
@clearstatcache();
// Shouldn't this be $f->GetAbsolutePath() ?
// And why doesn't GetAbsolutePath() work?
$strPath = (string) $f->getPath();
// FIXME
// if file object does denote a file that yet not existst
// path rights are checked
if (!@file_exists($strPath) && !is_dir($strPath)) {
$strPath = $f->getParent();
if ($strPath === null || !is_dir($strPath)) {
$strPath = Phing::getProperty("user.dir");
}
//$strPath = dirname($strPath);
}
if (!$write) {
return (boolean) @is_readable($strPath);
} else {
return (boolean) @is_writable($strPath);
}
}
/**
* Whether file can be deleted.
* @param PhingFile $f
* @return boolean
*/
function canDelete(PhingFile $f)
{
clearstatcache();
$dir = dirname($f->getAbsolutePath());
return (bool) @is_writable($dir);
}
/**
* Return the time at which the file or directory denoted by the given
* abstract pathname was last modified, or zero if it does not exist or
* some other I/O error occurs.
*/
function getLastModifiedTime(PhingFile $f) {
if (!$f->exists()) {
return 0;
}
@clearstatcache();
$strPath = (string) $f->getPath();
$mtime = @filemtime($strPath);
if (false === $mtime) {
// FAILED. Log and return err.
$msg = "FileSystem::Filemtime() FAILED. Cannot can not get modified time of $strPath. $php_errormsg";
throw new Exception($msg);
} else {
return (int) $mtime;
}
}
/**
* Return the length in bytes of the file denoted by the given abstract
* pathname, or zero if it does not exist, is a directory, or some other
* I/O error occurs.
*/
function getLength(PhingFile $f) {
$strPath = (string) $f->getAbsolutePath();
$fs = filesize((string) $strPath);
if ($fs !== false) {
return $fs;
} else {
$msg = "FileSystem::Read() FAILED. Cannot get filesize of $strPath. $php_errormsg";
throw new Exception($msg);
}
}
/* -- File operations -- */
/**
* Create a new empty file with the given pathname. Return
* true if the file was created and false if a
* file or directory with the given pathname already exists. Throw an
* IOException if an I/O error occurs.
*
* @param string Path of the file to be created.
*
* @throws IOException
*/
function createNewFile($strPathname) {
if (@file_exists($strPathname))
return false;
// Create new file
$fp = @fopen($strPathname, "w");
if ($fp === false) {
throw new IOException("The file \"$strPathname\" could not be created");
}
@fclose($fp);
return true;
}
/**
* Delete the file or directory denoted by the given abstract pathname,
* returning true if and only if the operation succeeds.
*/
function delete(PhingFile $f, $recursive = false) {
if ($f->isDirectory()) {
return $this->rmdir($f->getPath(), $recursive);
} else {
return $this->unlink($f->getPath());
}
}
/**
* Arrange for the file or directory denoted by the given abstract
* pathname to be deleted when Phing::shutdown is called, returning
* true if and only if the operation succeeds.
*/
function deleteOnExit($f) {
throw new Exception("deleteOnExit() not implemented by local fs driver");
}
/**
* List the elements of the directory denoted by the given abstract
* pathname. Return an array of strings naming the elements of the
* directory if successful; otherwise, return <code>null</code>.
*/
function listDir(PhingFile $f) {
$strPath = (string) $f->getAbsolutePath();
$d = @dir($strPath);
if (!$d) {
return null;
}
$list = array();
while($entry = $d->read()) {
if ($entry != "." && $entry != "..") {
array_push($list, $entry);
}
}
$d->close();
unset($d);
return $list;
}
/**
* Create a new directory denoted by the given abstract pathname,
* returning true if and only if the operation succeeds.
*
* NOTE: umask() is reset to 0 while executing mkdir(), and restored afterwards
*/
function createDirectory(&$f, $mode = 0755) {
$old_umask = umask(0);
$return = @mkdir($f->getAbsolutePath(), $mode);
umask($old_umask);
return $return;
}
/**
* Rename the file or directory denoted by the first abstract pathname to
* the second abstract pathname, returning true if and only if
* the operation succeeds.
*
* @param PhingFile $f1 abstract source file
* @param PhingFile $f2 abstract destination file
* @return void
* @throws Exception if rename cannot be performed
*/
function rename(PhingFile $f1, PhingFile $f2) {
// get the canonical paths of the file to rename
$src = $f1->getAbsolutePath();
$dest = $f2->getAbsolutePath();
if (false === @rename($src, $dest)) {
$msg = "Rename FAILED. Cannot rename $src to $dest. $php_errormsg";
throw new Exception($msg);
}
}
/**
* Set the last-modified time of the file or directory denoted by the
* given abstract pathname returning true if and only if the
* operation succeeds.
* @return void
* @throws Exception
*/
function setLastModifiedTime(PhingFile $f, $time) {
$path = $f->getPath();
$success = @touch($path, $time);
if (!$success) {
throw new Exception("Could not touch '" . $path . "' due to: $php_errormsg");
}
}
/**
* Mark the file or directory denoted by the given abstract pathname as
* read-only, returning <code>true</code> if and only if the operation
* succeeds.
*/
function setReadOnly($f) {
throw new Exception("setReadonle() not implemented by local fs driver");
}
/* -- Filesystem interface -- */
/**
* List the available filesystem roots, return array of PhingFile objects
*/
function listRoots() {
throw new Exception("SYSTEM ERROR [listRoots() not implemented by local fs driver]");
}
/* -- Basic infrastructure -- */
/**
* Compare two abstract pathnames lexicographically.
*/
function compare($f1, $f2) {
throw new Exception("SYSTEM ERROR [compare() not implemented by local fs driver]");
}
/**
* Copy a file.
*
* @param PhingFile $src Source path and name file to copy.
* @param PhingFile $dest Destination path and name of new file.
*
* @return void
* @throws Exception if file cannot be copied.
*/
function copy(PhingFile $src, PhingFile $dest) {
global $php_errormsg;
// Recursively copy a directory
if($src->isDirectory()) {
return $this->copyr($src->getAbsolutePath(), $dest->getAbsolutePath());
}
$srcPath = $src->getAbsolutePath();
$destPath = $dest->getAbsolutePath();
if (false === @copy($srcPath, $destPath)) { // Copy FAILED. Log and return err.
// Add error from php to end of log message. $php_errormsg.
$msg = "FileSystem::copy() FAILED. Cannot copy $srcPath to $destPath. $php_errormsg";
throw new Exception($msg);
}
try {
$dest->setMode($src->getMode());
} catch(Exception $exc) {
// [MA] does chmod returns an error on systems that do not support it ?
// eat it up for now.
}
}
/**
* Copy a file, or recursively copy a folder and its contents
*
* @author Aidan Lister <aidan@php.net>
* @version 1.0.1
* @link http://aidanlister.com/repos/v/function.copyr.php
* @param string $source Source path
* @param string $dest Destination path
* @return bool Returns TRUE on success, FALSE on failure
*/
function copyr($source, $dest)
{
// Check for symlinks
if (is_link($source)) {
return symlink(readlink($source), $dest);
}
// Simple copy for a file
if (is_file($source)) {
return copy($source, $dest);
}
// Make destination directory
if (!is_dir($dest)) {
mkdir($dest);
}
// Loop through the folder
$dir = dir($source);
while (false !== $entry = $dir->read()) {
// Skip pointers
if ($entry == '.' || $entry == '..') {
continue;
}
// Deep copy directories
$this->copyr("$source/$entry", "$dest/$entry");
}
// Clean up
$dir->close();
return true;
}
/**
* Change the ownership on a file or directory.
*
* @param string $pathname Path and name of file or directory.
* @param string $user The user name or number of the file or directory. See http://us.php.net/chown
*
* @return void
* @throws Exception if operation failed.
*/
function chown($pathname, $user) {
if (false === @chown($pathname, $user)) {// FAILED.
$msg = "FileSystem::chown() FAILED. Cannot chown $pathname. User $user." . (isset($php_errormsg) ? ' ' . $php_errormsg : "");
throw new Exception($msg);
}
}
/**
* Change the group on a file or directory.
*
* @param string $pathname Path and name of file or directory.
* @param string $group The group of the file or directory. See http://us.php.net/chgrp
*
* @return void
* @throws Exception if operation failed.
*/
function chgrp($pathname, $group) {
if (false === @chgrp($pathname, $group)) {// FAILED.
$msg = "FileSystem::chgrp() FAILED. Cannot chown $pathname. Group $group." . (isset($php_errormsg) ? ' ' . $php_errormsg : "");
throw new Exception($msg);
}
}
/**
* Change the permissions on a file or directory.
*
* @param pathname String. Path and name of file or directory.
* @param mode Int. The mode (permissions) of the file or
* directory. If using octal add leading 0. eg. 0777.
* Mode is affected by the umask system setting.
*
* @return void
* @throws Exception if operation failed.
*/
function chmod($pathname, $mode) {
$str_mode = decoct($mode); // Show octal in messages.
if (false === @chmod($pathname, $mode)) {// FAILED.
$msg = "FileSystem::chmod() FAILED. Cannot chmod $pathname. Mode $str_mode." . (isset($php_errormsg) ? ' ' . $php_errormsg : "");
throw new Exception($msg);
}
}
/**
* Locks a file and throws an Exception if this is not possible.
* @return void
* @throws Exception
*/
function lock(PhingFile $f) {
$filename = $f->getPath();
$fp = @fopen($filename, "w");
$result = @flock($fp, LOCK_EX);
@fclose($fp);
if (!$result) {
throw new Exception("Could not lock file '$filename'");
}
}
/**
* Unlocks a file and throws an IO Error if this is not possible.
*
* @throws Exception
* @return void
*/
function unlock(PhingFile $f) {
$filename = $f->getPath();
$fp = @fopen($filename, "w");
$result = @flock($fp, LOCK_UN);
fclose($fp);
if (!$result) {
throw new Exception("Could not unlock file '$filename'");
}
}
/**
* Delete a file.
*
* @param file String. Path and/or name of file to delete.
*
* @return void
* @throws Exception - if an error is encountered.
*/
function unlink($file) {
global $php_errormsg;
if (false === @unlink($file)) {
$msg = "FileSystem::unlink() FAILED. Cannot unlink '$file'. $php_errormsg";
throw new Exception($msg);
}
}
/**
* Symbolically link a file to another name.
*
* Currently symlink is not implemented on Windows. Don't use if the application is to be portable.
*
* @param string $target Path and/or name of file to link.
* @param string $link Path and/or name of link to be created.
* @return void
*/
function symlink($target, $link) {
// If Windows OS then symlink() will report it is not supported in
// the build. Use this error instead of checking for Windows as the OS.
if (false === @symlink($target, $link)) {
// Add error from php to end of log message. $php_errormsg.
$msg = "FileSystem::Symlink() FAILED. Cannot symlink '$target' to '$link'. $php_errormsg";
throw new Exception($msg);
}
}
/**
* Set the modification and access time on a file to the present time.
*
* @param string $file Path and/or name of file to touch.
* @param int $time
* @return void
*/
function touch($file, $time = null) {
global $php_errormsg;
if (null === $time) {
$error = @touch($file);
} else {
$error = @touch($file, $time);
}
if (false === $error) { // FAILED.
// Add error from php to end of log message. $php_errormsg.
$msg = "FileSystem::touch() FAILED. Cannot touch '$file'. $php_errormsg";
throw new Exception($msg);
}
}
/**
* Delete an empty directory OR a directory and all of its contents.
*
* @param dir String. Path and/or name of directory to delete.
* @param children Boolean. False: don't delete directory contents.
* True: delete directory contents.
*
* @return void
*/
function rmdir($dir, $children = false) {
global $php_errormsg;
// If children=FALSE only delete dir if empty.
if (false === $children) {
if (false === @rmdir($dir)) { // FAILED.
// Add error from php to end of log message. $php_errormsg.
$msg = "FileSystem::rmdir() FAILED. Cannot rmdir $dir. $php_errormsg";
throw new Exception($msg);
}
} else { // delete contents and dir.
$handle = @opendir($dir);
if (false === $handle) { // Error.
$msg = "FileSystem::rmdir() FAILED. Cannot opendir() $dir. $php_errormsg";
throw new Exception($msg);
} else { // Read from handle.
// Don't error on readdir().
while (false !== ($entry = @readdir($handle))) {
if ($entry != '.' && $entry != '..') {
// Only add / if it isn't already the last char.
// This ONLY serves the purpose of making the Logger
// output look nice:)
if (strpos(strrev($dir), DIRECTORY_SEPARATOR) === 0) {// there is a /
$next_entry = $dir . $entry;
} else { // no /
$next_entry = $dir . DIRECTORY_SEPARATOR . $entry;
}
// NOTE: As of php 4.1.1 is_dir doesn't return FALSE it
// returns 0. So use == not ===.
// Don't error on is_dir()
if (false == @is_dir($next_entry)) { // Is file.
try {
self::unlink($next_entry); // Delete.
} catch (Exception $e) {
$msg = "FileSystem::Rmdir() FAILED. Cannot FileSystem::Unlink() $next_entry. ". $e->getMessage();
throw new Exception($msg);
}
} else { // Is directory.
try {
self::rmdir($next_entry, true); // Delete
} catch (Exception $e) {
$msg = "FileSystem::rmdir() FAILED. Cannot FileSystem::rmdir() $next_entry. ". $e->getMessage();
throw new Exception($msg);
}
} // end is_dir else
} // end .. if
} // end while
} // end handle if
// Don't error on closedir()
@closedir($handle);
if (false === @rmdir($dir)) { // FAILED.
// Add error from php to end of log message. $php_errormsg.
$msg = "FileSystem::rmdir() FAILED. Cannot rmdir $dir. $php_errormsg";
throw new Exception($msg);
}
}
}
/**
* Set the umask for file and directory creation.
*
* @param mode Int. Permissions ususally in ocatal. Use leading 0 for
* octal. Number between 0 and 0777.
*
* @return void
* @throws Exception if there is an error performing operation.
*/
function umask($mode) {
global $php_errormsg;
// CONSIDERME:
// Throw a warning if mode is 0. PHP converts illegal octal numbers to
// 0 so 0 might not be what the user intended.
$str_mode = decoct($mode); // Show octal in messages.
if (false === @umask($mode)) { // FAILED.
// Add error from php to end of log message. $php_errormsg.
$msg = "FileSystem::Umask() FAILED. Value $mode. $php_errormsg";
throw new Exception($msg);
}
}
/**
* Compare the modified time of two files.
*
* @param file1 String. Path and name of file1.
* @param file2 String. Path and name of file2.
*
* @return Int. 1 if file1 is newer.
* -1 if file2 is newer.
* 0 if files have the same time.
* Err object on failure.
*
* @throws Exception - if cannot get modified time of either file.
*/
function compareMTimes($file1, $file2) {
$mtime1 = filemtime($file1);
$mtime2 = filemtime($file2);
if ($mtime1 === false) { // FAILED. Log and return err.
// Add error from php to end of log message. $php_errormsg.
$msg = "FileSystem::compareMTimes() FAILED. Cannot can not get modified time of $file1.";
throw new Exception($msg);
} elseif ($mtime2 === false) { // FAILED. Log and return err.
// Add error from php to end of log message. $php_errormsg.
$msg = "FileSystem::compareMTimes() FAILED. Cannot can not get modified time of $file2.";
throw new Exception($msg);
} else { // Worked. Log and return compare.
// Compare mtimes.
if ($mtime1 == $mtime2) {
return 0;
} else {
return ($mtime1 < $mtime2) ? -1 : 1;
} // end compare
}
}
}

View file

@ -0,0 +1,42 @@
<?php
/*
* $Id: FileWriter.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
require_once 'phing/system/io/OutputStreamWriter.php';
require_once 'phing/system/io/FileOutputStream.php';
/**
* Convenience class for performing file write operations.
*
* @package phing.system.io
*/
class FileWriter extends OutputStreamWriter {
/**
* Construct a new FileWriter.
* @param mixed $file PhingFile or string pathname.
* @param boolean $append Append to existing file?
*/
function __construct($file, $append = false) {
$out = new FileOutputStream($file, $append);
parent::__construct($out);
}
}

View file

@ -0,0 +1,68 @@
<?php
/*
* $Id: FilterReader.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
require_once 'phing/system/io/Reader.php';
/**
* Wrapper class for readers, which can be used to apply filters.
* @package phing.system.io
*/
class FilterReader extends Reader {
/**
* @var Reader
*/
protected $in;
function __construct(Reader $in = null) {
$this->in = $in;
}
public function setReader(Reader $in) {
$this->in = $in;
}
public function skip($n) {
return $this->in->skip($n);
}
/**
* Read data from source.
* FIXME: Clean up this function signature, as it a) params aren't being used
* and b) it doesn't make much sense.
*/
public function read($len = null) {
return $this->in->read($len);
}
public function reset() {
return $this->in->reset();
}
public function close() {
return $this->in->close();
}
function getResource() {
return $this->in->getResource();
}
}

View file

@ -0,0 +1,27 @@
<?php
/*
* $Id: IOException.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* Extends Exception to take advantage of methods therein.
*
* @package phing.system.io
*/
class IOException extends Exception {}

View file

@ -0,0 +1,178 @@
<?php
/*
* $Id: InputStream.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* Wrapper class for PHP stream that supports read operations.
*
* @package phing.system.io
*/
class InputStream {
/**
* @var resource The attached PHP stream.
*/
protected $stream;
/**
* @var int Position of stream cursor.
*/
protected $currentPosition = 0;
/**
* @var int Marked position of stream cursor.
*/
protected $mark = 0;
/**
* Construct a new InputStream.
* @param resource $stream Configured PHP stream for writing.
*/
public function __construct($stream) {
if (!is_resource($stream)) {
throw new IOException("Passed argument is not a valid stream.");
}
$this->stream = $stream;
}
/**
* Skip over $n bytes.
* @param int $n
*/
public function skip($n) {
$start = $this->currentPosition;
$ret = @fseek($this->stream, $n, SEEK_CUR);
if ( $ret === -1 )
return -1;
$this->currentPosition = ftell($this->stream);
if ( $start > $this->currentPosition )
$skipped = $start - $this->currentPosition;
else
$skipped = $this->currentPosition - $start;
return $skipped;
}
/**
* Read data from stream until $len chars or EOF.
* @param int $len Num chars to read. If not specified this stream will read until EOF.
* @return string chars read or -1 if eof.
*/
public function read($len = null) {
if ($this->eof()) {
return -1;
}
if ($len === null) { // we want to keep reading until we get an eof
$out = "";
while(!$this->eof()) {
$out .= fread($this->stream, 8192);
$this->currentPosition = ftell($this->stream);
}
} else {
$out = fread($this->stream, $len); // adding 1 seems to ensure that next call to read() will return EOF (-1)
$this->currentPosition = ftell($this->stream);
}
return $out;
}
/**
* Marks the current position in this input stream.
* @throws IOException - if the underlying stream doesn't support this method.
*/
public function mark() {
if (!$this->markSupported()) {
throw new IOException(get_class($this) . " does not support mark() and reset() methods.");
}
$this->mark = $this->currentPosition;
}
/**
* Whether the input stream supports mark and reset methods.
* @return boolean
*/
public function markSupported() {
return false;
}
/**
* Repositions this stream to the position at the time the mark method was last called on this input stream.
* @throws IOException - if the underlying stream doesn't support this method.
*/
function reset() {
if (!$this->markSupported()) {
throw new IOException(get_class($this) . " does not support mark() and reset() methods.");
}
// goes back to last mark, by default this would be 0 (i.e. rewind file).
fseek($this->stream, SEEK_SET, $this->mark);
$this->mark = 0;
}
/**
* Closes stream.
* @throws IOException if stream cannot be closed (note that calling close() on an already-closed stream will not raise an exception)
*/
public function close() {
if ($this->stream === null) {
return;
}
if (false === @fclose($this->stream)) {
// FAILED.
$msg = "Cannot fclose " . $this->file->__toString() . " $php_errormsg";
throw new IOException($msg);
}
$this->stream = null;
}
/**
* Whether eof has been reached with stream.
* @return boolean
*/
public function eof() {
return feof($this->stream);
}
/**
* Reads a entire until EOF and places contents in passed-in variable. Stream is closed after read.
*
* @param string &$rBuffer String variable where read contents will be put.
* @return TRUE on success.
* @author Charlie Killian, charlie@tizac.com
* @throws IOException - if there is an error reading from stream.
* @deprecated - Instead, use the read() method or a BufferedReader.
*/
public function readInto(&$rBuffer) {
$rBuffer = $this->read();
$this->close();
}
/**
* Returns string representation of attached stream.
* @return string
*/
public function __toString() {
return (string) $this->stream;
}
}

View file

@ -0,0 +1,127 @@
<?php
/*
* $Id: InputStreamReader.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/PhingFile.php';
include_once 'phing/system/io/Reader.php';
/**
* Writer class for OutputStream objects.
*
* Unlike the Java counterpart, this class does not (yet) handle
* character set transformations. This will be an important function
* of this class with move to supporting PHP6.
*
* @package phing.system.io
*/
class InputStreamReader extends Reader {
/**
* @var InputStream
*/
protected $inStream;
/**
* Construct a new InputStreamReader.
* @param InputStream $$inStream InputStream to read from
*/
public function __construct(InputStream $inStream) {
$this->inStream = $inStream;
}
/**
* Close the stream.
*/
public function close() {
return $this->inStream->close();
}
/**
* Skip over $n bytes.
* @param int $n
*/
public function skip($n) {
return $this->inStream->skip($n);
}
/**
* Read data from file.
* @param int $len Num chars to read.
* @return string chars read or -1 if eof.
*/
public function read($len = null) {
return $this->inStream->read($len);
}
/**
* Marks the current position in this input stream.
* @throws IOException - if the underlying stream doesn't support this method.
*/
public function mark() {
$this->inStream->mark();
}
/**
* Whether the attached stream supports mark/reset.
* @return boolean
*/
public function markSupported() {
return $this->inStream->markSupported();
}
/**
* Repositions this stream to the position at the time the mark method was last called on this input stream.
* @throws IOException - if the underlying stream doesn't support this method.
*/
public function reset() {
$this->inStream->reset();
}
/**
* Whether eof has been reached with stream.
* @return boolean
*/
public function eof() {
return $this->inStream->eof();
}
/**
* Reads a entire file and stores the data in the variable
* passed by reference.
*
* @param string $file String. Path and/or name of file to read.
* @param object &$rBuffer Reference. Variable of where to put contents.
*
* @return TRUE on success. Err object on failure.
* @author Charlie Killian, charlie@tizac.com
* @deprecated Use read() or BufferedReader instead.
*/
public function readInto(&$rBuffer) {
return $this->inStream->readInto($rBuffer);
}
/**
* Returns string representation of attached stream.
* @return string
*/
public function getResource() {
return $this->inStream->__toString();
}
}

View file

@ -0,0 +1,108 @@
<?php
/*
* $Id: OutputStream.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* Wrapper class for PHP stream that supports write operations.
*
* @package phing.system.io
*/
class OutputStream {
/**
* @var resource The configured PHP stream.
*/
protected $stream;
/**
* Construct a new OutputStream.
* @param resource $stream Configured PHP stream for writing.
*/
public function __construct($stream) {
if (!is_resource($stream)) {
throw new IOException("Passed argument is not a valid stream.");
}
$this->stream = $stream;
}
/**
* Closes attached stream, flushing output first.
* @throws IOException if cannot close stream (note that attempting to close an already closed stream will not raise an IOException)
* @return void
*/
public function close() {
if ($this->stream === null) {
return;
}
$this->flush();
if (false === @fclose($this->stream)) {
$msg = "Cannot close " . $this->getResource() . ": $php_errormsg";
throw new IOException($msg);
}
$this->stream = null;
}
/**
* Flushes stream.
*
* @throws IOException if unable to flush data (e.g. stream is not open).
*/
public function flush() {
if (false === @fflush($this->stream)) {
throw new IOException("Could not flush stream: " . $php_errormsg);
}
}
/**
* Writes data to stream.
*
* @param string $buf Binary/character data to write.
* @param int $off (Optional) offset.
* @param int $len (Optional) number of bytes/chars to write.
* @return void
* @throws IOException - if there is an error writing to stream
*/
public function write($buf, $off = null, $len = null) {
if ( $off === null && $len === null ) {
$to_write = $buf;
} elseif ($off !== null && $len === null) {
$to_write = substr($buf, $off);
} elseif ($off === null && $len !== null) {
$to_write = substr($buf, 0, $len);
} else {
$to_write = substr($buf, $off, $len);
}
$result = @fwrite($this->stream, $to_write);
if ( $result === false ) {
throw new IOException("Error writing to stream.");
}
}
/**
* Returns a string representation of the attached PHP stream.
* @return string
*/
public function __toString() {
return (string) $this->stream;
}
}

View file

@ -0,0 +1,84 @@
<?php
/*
* $Id: OutputStreamWriter.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/PhingFile.php';
require_once 'phing/system/io/Writer.php';
/**
* Writer class for OutputStream objects.
*
* Unlike the Java counterpart, this class does not (yet) handle
* character set transformations. This will be an important function
* of this class with move to supporting PHP6.
*
* @package phing.system.io
*/
class OutputStreamWriter extends Writer {
/**
* @var OutputStream
*/
protected $outStream;
/**
* Construct a new OutputStreamWriter.
* @param OutputStream $outStream OutputStream to write to
*/
public function __construct(OutputStream $outStream) {
$this->outStream = $outStream;
}
/**
* Close the stream.
*/
public function close() {
return $this->outStream->close();
}
/**
* Write char data to stream.
*
* @param unknown_type $buf
* @param unknown_type $off
* @param unknown_type $len
* @return unknown
*/
public function write($buf, $off = null, $len = null) {
return $this->outStream->write($buf, $off, $len);
}
/**
* Flush output to the stream.
*/
public function flush() {
$this->outStream->flush();
}
/**
* Gets a string representation of attached stream resource.
*
* @return string String representation of output stream
*/
public function getResource() {
return $this->outStream->__toString();
}
}

View file

@ -0,0 +1,951 @@
<?php
/*
* $Id: PhingFile.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/FileSystem.php';
include_once 'phing/system/lang/NullPointerException.php';
/**
* An abstract representation of file and directory pathnames.
*
* @version $Revision: 905 $
* @package phing.system.io
*/
class PhingFile {
/** separator string, static, obtained from FileSystem */
public static $separator;
/** path separator string, static, obtained from FileSystem (; or :)*/
public static $pathSeparator;
/**
* This abstract pathname's normalized pathname string. A normalized
* pathname string uses the default name-separator character and does not
* contain any duplicate or redundant separators.
*/
private $path = null;
/** The length of this abstract pathname's prefix, or zero if it has no prefix. */
private $prefixLength = 0;
/** constructor */
function __construct($arg1 = null, $arg2 = null) {
if (self::$separator === null || self::$pathSeparator === null) {
$fs = FileSystem::getFileSystem();
self::$separator = $fs->getSeparator();
self::$pathSeparator = $fs->getPathSeparator();
}
/* simulate signature identified constructors */
if ($arg1 instanceof PhingFile && is_string($arg2)) {
$this->_constructFileParentStringChild($arg1, $arg2);
} elseif (is_string($arg1) && ($arg2 === null)) {
$this->_constructPathname($arg1);
} elseif(is_string($arg1) && is_string($arg2)) {
$this->_constructStringParentStringChild($arg1, $arg2);
} else {
if ($arg1 === null) {
throw new NullPointerException("Argument1 to function must not be null");
}
$this->path = (string) $arg1;
$this->prefixLength = (int) $arg2;
}
}
/** Returns the length of this abstract pathname's prefix. */
function getPrefixLength() {
return (int) $this->prefixLength;
}
/* -- constructors not called by signature match, so we need some helpers --*/
function _constructPathname($pathname) {
// obtain ref to the filesystem layer
$fs = FileSystem::getFileSystem();
if ($pathname === null) {
throw new NullPointerException("Argument to function must not be null");
}
$this->path = (string) $fs->normalize($pathname);
$this->prefixLength = (int) $fs->prefixLength($this->path);
}
function _constructStringParentStringChild($parent, $child = null) {
// obtain ref to the filesystem layer
$fs = FileSystem::getFileSystem();
if ($child === null) {
throw new NullPointerException("Argument to function must not be null");
}
if ($parent !== null) {
if ($parent === "") {
$this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child));
} else {
$this->path = $fs->resolve($fs->normalize($parent), $fs->normalize($child));
}
} else {
$this->path = (string) $fs->normalize($child);
}
$this->prefixLength = (int) $fs->prefixLength($this->path);
}
function _constructFileParentStringChild($parent, $child = null) {
// obtain ref to the filesystem layer
$fs = FileSystem::getFileSystem();
if ($child === null) {
throw new NullPointerException("Argument to function must not be null");
}
if ($parent !== null) {
if ($parent->path === "") {
$this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child));
} else {
$this->path = $fs->resolve($parent->path, $fs->normalize($child));
}
} else {
$this->path = $fs->normalize($child);
}
$this->prefixLength = $fs->prefixLength($this->path);
}
/* -- Path-component accessors -- */
/**
* Returns the name of the file or directory denoted by this abstract
* pathname. This is just the last name in the pathname's name
* sequence. If the pathname's name sequence is empty, then the empty
* string is returned.
*
* @return The name of the file or directory denoted by this abstract
* pathname, or the empty string if this pathname's name sequence
* is empty
*/
function getName() {
// that's a lastIndexOf
$index = ((($res = strrpos($this->path, self::$separator)) === false) ? -1 : $res);
if ($index < $this->prefixLength) {
return substr($this->path, $this->prefixLength);
}
return substr($this->path, $index + 1);
}
/**
* Returns the pathname string of this abstract pathname's parent, or
* null if this pathname does not name a parent directory.
*
* The parent of an abstract pathname consists of the pathname's prefix,
* if any, and each name in the pathname's name sequence except for the last.
* If the name sequence is empty then the pathname does not name a parent
* directory.
*
* @return The pathname string of the parent directory named by this
* abstract pathname, or null if this pathname does not name a parent
*/
function getParent() {
// that's a lastIndexOf
$index = ((($res = strrpos($this->path, self::$separator)) === false) ? -1 : $res);
if ($index < $this->prefixLength) {
if (($this->prefixLength > 0) && (strlen($this->path) > $this->prefixLength)) {
return substr($this->path, 0, $this->prefixLength);
}
return null;
}
return substr($this->path, 0, $index);
}
/**
* Returns the abstract pathname of this abstract pathname's parent,
* or null if this pathname does not name a parent directory.
*
* The parent of an abstract pathname consists of the pathname's prefix,
* if any, and each name in the pathname's name sequence except for the
* last. If the name sequence is empty then the pathname does not name
* a parent directory.
*
* @return The abstract pathname of the parent directory named by this
* abstract pathname, or null if this pathname
* does not name a parent
*/
function getParentFile() {
$p = $this->getParent();
if ($p === null) {
return null;
}
return new PhingFile((string) $p, (int) $this->prefixLength);
}
/**
* Converts this abstract pathname into a pathname string. The resulting
* string uses the default name-separator character to separate the names
* in the name sequence.
*
* @return The string form of this abstract pathname
*/
function getPath() {
return (string) $this->path;
}
/**
* Returns path without leading basedir.
*
* @param string $basedir Base directory to strip
*
* @return string Path without basedir
*
* @uses getPath()
*/
function getPathWithoutBase($basedir)
{
if (!StringHelper::endsWith(self::$separator, $basedir)) {
$basedir .= self::$separator;
}
$path = $this->getPath();
if (!substr($path, 0, strlen($basedir)) == $basedir) {
//path does not begin with basedir, we don't modify it
return $path;
}
return substr($path, strlen($basedir));
}
/**
* Tests whether this abstract pathname is absolute. The definition of
* absolute pathname is system dependent. On UNIX systems, a pathname is
* absolute if its prefix is "/". On Win32 systems, a pathname is absolute
* if its prefix is a drive specifier followed by "\\", or if its prefix
* is "\\".
*
* @return true if this abstract pathname is absolute, false otherwise
*/
function isAbsolute() {
return ($this->prefixLength !== 0);
}
/**
* Returns the absolute pathname string of this abstract pathname.
*
* If this abstract pathname is already absolute, then the pathname
* string is simply returned as if by the getPath method.
* If this abstract pathname is the empty abstract pathname then
* the pathname string of the current user directory, which is named by the
* system property user.dir, is returned. Otherwise this
* pathname is resolved in a system-dependent way. On UNIX systems, a
* relative pathname is made absolute by resolving it against the current
* user directory. On Win32 systems, a relative pathname is made absolute
* by resolving it against the current directory of the drive named by the
* pathname, if any; if not, it is resolved against the current user
* directory.
*
* @return The absolute pathname string denoting the same file or
* directory as this abstract pathname
* @see #isAbsolute()
*/
function getAbsolutePath() {
$fs = FileSystem::getFileSystem();
return $fs->resolveFile($this);
}
/**
* Returns the absolute form of this abstract pathname. Equivalent to
* getAbsolutePath.
*
* @return The absolute abstract pathname denoting the same file or
* directory as this abstract pathname
*/
function getAbsoluteFile() {
return new PhingFile((string) $this->getAbsolutePath());
}
/**
* Returns the canonical pathname string of this abstract pathname.
*
* A canonical pathname is both absolute and unique. The precise
* definition of canonical form is system-dependent. This method first
* converts this pathname to absolute form if necessary, as if by invoking the
* getAbsolutePath() method, and then maps it to its unique form in a
* system-dependent way. This typically involves removing redundant names
* such as "." and .. from the pathname, resolving symbolic links
* (on UNIX platforms), and converting drive letters to a standard case
* (on Win32 platforms).
*
* Every pathname that denotes an existing file or directory has a
* unique canonical form. Every pathname that denotes a nonexistent file
* or directory also has a unique canonical form. The canonical form of
* the pathname of a nonexistent file or directory may be different from
* the canonical form of the same pathname after the file or directory is
* created. Similarly, the canonical form of the pathname of an existing
* file or directory may be different from the canonical form of the same
* pathname after the file or directory is deleted.
*
* @return The canonical pathname string denoting the same file or
* directory as this abstract pathname
*/
function getCanonicalPath() {
$fs = FileSystem::getFileSystem();
return $fs->canonicalize($this->path);
}
/**
* Returns the canonical form of this abstract pathname. Equivalent to
* getCanonicalPath(.
*
* @return PhingFile The canonical pathname string denoting the same file or
* directory as this abstract pathname
*/
function getCanonicalFile() {
return new PhingFile($this->getCanonicalPath());
}
/**
* Converts this abstract pathname into a file: URL. The
* exact form of the URL is system-dependent. If it can be determined that
* the file denoted by this abstract pathname is a directory, then the
* resulting URL will end with a slash.
*
* Usage note: This method does not automatically escape
* characters that are illegal in URLs. It is recommended that new code
* convert an abstract pathname into a URL by first converting it into a
* URI, via the toURI() method, and then converting the URI
* into a URL via the URI::toURL()
*
* @return A URL object representing the equivalent file URL
*
*
*/
function toURL() {
/*
// URL class not implemented yet
return new URL("file", "", $this->_slashify($this->getAbsolutePath(), $this->isDirectory()));
*/
}
/**
* Constructs a file: URI that represents this abstract pathname.
* Not implemented yet
*/
function toURI() {
/*
$f = $this->getAbsoluteFile();
$sp = (string) $this->slashify($f->getPath(), $f->isDirectory());
if (StringHelper::startsWith('//', $sp))
$sp = '//' + sp;
return new URI('file', null, $sp, null);
*/
}
function _slashify($path, $isDirectory) {
$p = (string) $path;
if (self::$separator !== '/') {
$p = str_replace(self::$separator, '/', $p);
}
if (!StringHelper::startsWith('/', $p)) {
$p = '/'.$p;
}
if (!StringHelper::endsWith('/', $p) && $isDirectory) {
$p = $p.'/';
}
return $p;
}
/* -- Attribute accessors -- */
/**
* Tests whether the application can read the file denoted by this
* abstract pathname.
*
* @return true if and only if the file specified by this
* abstract pathname exists and can be read by the
* application; false otherwise
*/
function canRead() {
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess($this)) {
return (boolean) @is_readable($this->getAbsolutePath());
}
return false;
}
/**
* Tests whether the application can modify to the file denoted by this
* abstract pathname.
*
* @return true if and only if the file system actually
* contains a file denoted by this abstract pathname and
* the application is allowed to write to the file;
* false otherwise.
*
*/
function canWrite() {
$fs = FileSystem::getFileSystem();
return $fs->checkAccess($this, true);
}
/**
* Tests whether the file denoted by this abstract pathname exists.
*
* @return true if and only if the file denoted by this
* abstract pathname exists; false otherwise
*
*/
function exists() {
clearstatcache();
if (is_link($this->path)) {
return true;
} else if ($this->isFile()) {
return @file_exists($this->path) || is_link($this->path);
} else {
return @is_dir($this->path);
}
}
/**
* Tests whether the file denoted by this abstract pathname is a
* directory.
*
* @return true if and only if the file denoted by this
* abstract pathname exists and is a directory;
* false otherwise
*
*/
function isDirectory() {
clearstatcache();
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess($this) !== true) {
throw new IOException("No read access to ".$this->path);
}
return @is_dir($this->path) && !@is_link($this->path);
}
/**
* Tests whether the file denoted by this abstract pathname is a normal
* file. A file is normal if it is not a directory and, in
* addition, satisfies other system-dependent criteria. Any non-directory
* file created by a Java application is guaranteed to be a normal file.
*
* @return true if and only if the file denoted by this
* abstract pathname exists and is a normal file;
* false otherwise
*/
function isFile() {
clearstatcache();
//$fs = FileSystem::getFileSystem();
return @is_file($this->path);
}
/**
* Tests whether the file named by this abstract pathname is a hidden
* file. The exact definition of hidden is system-dependent. On
* UNIX systems, a file is considered to be hidden if its name begins with
* a period character ('.'). On Win32 systems, a file is considered to be
* hidden if it has been marked as such in the filesystem. Currently there
* seems to be no way to dermine isHidden on Win file systems via PHP
*
* @return true if and only if the file denoted by this
* abstract pathname is hidden according to the conventions of the
* underlying platform
*/
function isHidden() {
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess($this) !== true) {
throw new IOException("No read access to ".$this->path);
}
return (($fs->getBooleanAttributes($this) & $fs->BA_HIDDEN) !== 0);
}
/**
* Tests whether the file denoted by this abstract pathname is a symbolic link.
*
* @return true if and only if the file denoted by this
* abstract pathname exists and is a symbolic link;
* false otherwise
*/
public function isLink()
{
clearstatcache();
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess($this) !== true) {
throw new IOException("No read access to ".$this->path);
}
return @is_link($this->path);
}
/**
* Returns the target of the symbolic link denoted by this abstract pathname
*
* @return the target of the symbolic link denoted by this abstract pathname
*/
public function getLinkTarget()
{
return @readlink($this->path);
}
/**
* Returns the time that the file denoted by this abstract pathname was
* last modified.
*
* @return A integer value representing the time the file was
* last modified, measured in milliseconds since the epoch
* (00:00:00 GMT, January 1, 1970), or 0 if the
* file does not exist or if an I/O error occurs
*/
function lastModified() {
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess($this) !== true) {
throw new IOException("No read access to " . $this->path);
}
return $fs->getLastModifiedTime($this);
}
/**
* Returns the length of the file denoted by this abstract pathname.
* The return value is unspecified if this pathname denotes a directory.
*
* @return The length, in bytes, of the file denoted by this abstract
* pathname, or 0 if the file does not exist
*/
function length() {
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess($this) !== true) {
throw new IOException("No read access to ".$this->path."\n");
}
return $fs->getLength($this);
}
/**
* Convenience method for returning the contents of this file as a string.
* This method uses file_get_contents() to read file in an optimized way.
* @return string
* @throws Exception - if file cannot be read
*/
function contents() {
if (!$this->canRead() || !$this->isFile()) {
throw new IOException("Cannot read file contents!");
}
return file_get_contents($this->getAbsolutePath());
}
/* -- File operations -- */
/**
* Atomically creates a new, empty file named by this abstract pathname if
* and only if a file with this name does not yet exist. The check for the
* existence of the file and the creation of the file if it does not exist
* are a single operation that is atomic with respect to all other
* filesystem activities that might affect the file.
*
* @return true if the named file does not exist and was
* successfully created; <code>false</code> if the named file
* already exists
* @throws IOException if file can't be created
*/
function createNewFile($parents=true, $mode=0777) {
$file = FileSystem::getFileSystem()->createNewFile($this->path);
return $file;
}
/**
* Deletes the file or directory denoted by this abstract pathname. If
* this pathname denotes a directory, then the directory must be empty in
* order to be deleted.
*
* @return true if and only if the file or directory is
* successfully deleted; false otherwise
*/
function delete($recursive = false) {
$fs = FileSystem::getFileSystem();
if ($fs->canDelete($this) !== true) {
throw new IOException("Cannot delete " . $this->path . "\n");
}
return $fs->delete($this, $recursive);
}
/**
* Requests that the file or directory denoted by this abstract pathname
* be deleted when php terminates. Deletion will be attempted only for
* normal termination of php and if and if only Phing::shutdown() is
* called.
*
* Once deletion has been requested, it is not possible to cancel the
* request. This method should therefore be used with care.
*
*/
function deleteOnExit() {
$fs = FileSystem::getFileSystem();
$fs->deleteOnExit($this);
}
/**
* Returns an array of strings naming the files and directories in the
* directory denoted by this abstract pathname.
*
* If this abstract pathname does not denote a directory, then this
* method returns null Otherwise an array of strings is
* returned, one for each file or directory in the directory. Names
* denoting the directory itself and the directory's parent directory are
* not included in the result. Each string is a file name rather than a
* complete path.
*
* There is no guarantee that the name strings in the resulting array
* will appear in any specific order; they are not, in particular,
* guaranteed to appear in alphabetical order.
*
* @return An array of strings naming the files and directories in the
* directory denoted by this abstract pathname. The array will be
* empty if the directory is empty. Returns null if
* this abstract pathname does not denote a directory, or if an
* I/O error occurs.
*
*/
function listDir($filter = null) {
$fs = FileSystem::getFileSystem();
return $fs->lister($this, $filter);
}
function listFiles($filter = null) {
$ss = $this->listDir($filter);
if ($ss === null) {
return null;
}
$n = count($ss);
$fs = array();
for ($i = 0; $i < $n; $i++) {
$fs[$i] = new PhingFile((string)$this->path, (string)$ss[$i]);
}
return $fs;
}
/**
* Creates the directory named by this abstract pathname, including any
* necessary but nonexistent parent directories. Note that if this
* operation fails it may have succeeded in creating some of the necessary
* parent directories.
*
* @return true if and only if the directory was created,
* along with all necessary parent directories; false
* otherwise
* @throws IOException
*/
function mkdirs($mode = 0755) {
if ($this->exists()) {
return false;
}
try {
if ($this->mkdir($mode)) {
return true;
}
} catch (IOException $ioe) {
// IOException from mkdir() means that directory propbably didn't exist.
}
$parentFile = $this->getParentFile();
return (($parentFile !== null) && ($parentFile->mkdirs($mode) && $this->mkdir($mode)));
}
/**
* Creates the directory named by this abstract pathname.
*
* @return true if and only if the directory was created; false otherwise
* @throws IOException
*/
function mkdir($mode = 0755) {
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess(new PhingFile($this->path), true) !== true) {
throw new IOException("No write access to " . $this->getPath());
}
return $fs->createDirectory($this, $mode);
}
/**
* Renames the file denoted by this abstract pathname.
*
* @param destFile The new abstract pathname for the named file
* @return true if and only if the renaming succeeded; false otherwise
*/
function renameTo(PhingFile $destFile) {
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess($this) !== true) {
throw new IOException("No write access to ".$this->getPath());
}
return $fs->rename($this, $destFile);
}
/**
* Simple-copies file denoted by this abstract pathname into another
* PhingFile
*
* @param PhingFile $destFile The new abstract pathname for the named file
* @return true if and only if the renaming succeeded; false otherwise
*/
function copyTo(PhingFile $destFile) {
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess($this) !== true) {
throw new IOException("No read access to ".$this->getPath()."\n");
}
if ($fs->checkAccess($destFile, true) !== true) {
throw new IOException("File::copyTo() No write access to ".$destFile->getPath());
}
return $fs->copy($this, $destFile);
}
/**
* Sets the last-modified time of the file or directory named by this
* abstract pathname.
*
* All platforms support file-modification times to the nearest second,
* but some provide more precision. The argument will be truncated to fit
* the supported precision. If the operation succeeds and no intervening
* operations on the file take place, then the next invocation of the
* lastModified method will return the (possibly truncated) time argument
* that was passed to this method.
*
* @param time The new last-modified time, measured in milliseconds since
* the epoch (00:00:00 GMT, January 1, 1970)
* @return true if and only if the operation succeeded; false otherwise
*/
function setLastModified($time) {
$time = (int) $time;
if ($time < 0) {
throw new Exception("IllegalArgumentException, Negative $time\n");
}
$fs = FileSystem::getFileSystem();
return $fs->setLastModifiedTime($this, $time);
}
/**
* Marks the file or directory named by this abstract pathname so that
* only read operations are allowed. After invoking this method the file
* or directory is guaranteed not to change until it is either deleted or
* marked to allow write access. Whether or not a read-only file or
* directory may be deleted depends upon the underlying system.
*
* @return true if and only if the operation succeeded; false otherwise
*/
function setReadOnly() {
$fs = FileSystem::getFileSystem();
if ($fs->checkAccess($this, true) !== true) {
// Error, no write access
throw new IOException("No write access to " . $this->getPath());
}
return $fs->setReadOnly($this);
}
/**
* Sets the owner of the file.
* @param mixed $user User name or number.
*/
public function setUser($user) {
$fs = FileSystem::getFileSystem();
return $fs->chown($this->getPath(), $user);
}
/**
* Retrieve the owner of this file.
* @return int User ID of the owner of this file.
*/
function getUser() {
return @fileowner($this->getPath());
}
/**
* Sets the group of the file.
* @param mixed $user User name or number.
*/
public function setGroup($group) {
$fs = FileSystem::getFileSystem();
return $fs->chgrp($this->getPath(), $group);
}
/**
* Retrieve the group of this file.
* @return int User ID of the owner of this file.
*/
function getGroup() {
return @filegroup($this->getPath());
}
/**
* Sets the mode of the file
* @param int $mode Ocatal mode.
*/
function setMode($mode) {
$fs = FileSystem::getFileSystem();
return $fs->chmod($this->getPath(), $mode);
}
/**
* Retrieve the mode of this file.
* @return int
*/
function getMode() {
return @fileperms($this->getPath());
}
/* -- Filesystem interface -- */
/**
* List the available filesystem roots.
*
* A particular platform may support zero or more hierarchically-organized
* file systems. Each file system has a root directory from which all
* other files in that file system can be reached.
* Windows platforms, for example, have a root directory for each active
* drive; UNIX platforms have a single root directory, namely "/".
* The set of available filesystem roots is affected by various system-level
* operations such the insertion or ejection of removable media and the
* disconnecting or unmounting of physical or virtual disk drives.
*
* This method returns an array of PhingFile objects that
* denote the root directories of the available filesystem roots. It is
* guaranteed that the canonical pathname of any file physically present on
* the local machine will begin with one of the roots returned by this
* method.
*
* The canonical pathname of a file that resides on some other machine
* and is accessed via a remote-filesystem protocol such as SMB or NFS may
* or may not begin with one of the roots returned by this method. If the
* pathname of a remote file is syntactically indistinguishable from the
* pathname of a local file then it will begin with one of the roots
* returned by this method. Thus, for example, PhingFile objects
* denoting the root directories of the mapped network drives of a Windows
* platform will be returned by this method, while PhingFile
* objects containing UNC pathnames will not be returned by this method.
*
* @return An array of PhingFile objects denoting the available
* filesystem roots, or null if the set of roots
* could not be determined. The array will be empty if there are
* no filesystem roots.
*/
function listRoots() {
$fs = FileSystem::getFileSystem();
return (array) $fs->listRoots();
}
/* -- Tempfile management -- */
/**
* Returns the path to the temp directory.
*/
function getTempDir() {
return Phing::getProperty('php.tmpdir');
}
/**
* Static method that creates a unique filename whose name begins with
* $prefix and ends with $suffix in the directory $directory. $directory
* is a reference to a PhingFile Object.
* Then, the file is locked for exclusive reading/writing.
*
* @author manuel holtgrewe, grin@gmx.net
* @throws IOException
* @access public
*/
function createTempFile($prefix, $suffix, PhingFile $directory) {
// quick but efficient hack to create a unique filename ;-)
$result = null;
do {
$result = new PhingFile($directory, $prefix . substr(md5(time()), 0, 8) . $suffix);
} while (file_exists($result->getPath()));
$fs = FileSystem::getFileSystem();
$fs->createNewFile($result->getPath());
$fs->lock($result);
return $result;
}
/**
* If necessary, $File the lock on $File is removed and then the file is
* deleted
*
* @access public
*/
function removeTempFile() {
$fs = FileSystem::getFileSystem();
// catch IO Exception
$fs->unlock($this);
$this->delete();
}
/* -- Basic infrastructure -- */
/**
* Compares two abstract pathnames lexicographically. The ordering
* defined by this method depends upon the underlying system. On UNIX
* systems, alphabetic case is significant in comparing pathnames; on Win32
* systems it is not.
*
* @param PhingFile $file Th file whose pathname sould be compared to the pathname of this file.
*
* @return int Zero if the argument is equal to this abstract pathname, a
* value less than zero if this abstract pathname is
* lexicographically less than the argument, or a value greater
* than zero if this abstract pathname is lexicographically
* greater than the argument
*/
function compareTo(PhingFile $file) {
$fs = FileSystem::getFileSystem();
return $fs->compare($this, $file);
}
/**
* Tests this abstract pathname for equality with the given object.
* Returns <code>true</code> if and only if the argument is not
* <code>null</code> and is an abstract pathname that denotes the same file
* or directory as this abstract pathname. Whether or not two abstract
* pathnames are equal depends upon the underlying system. On UNIX
* systems, alphabetic case is significant in comparing pathnames; on Win32
* systems it is not.
* @return boolean
*/
function equals($obj) {
if (($obj !== null) && ($obj instanceof PhingFile)) {
return ($this->compareTo($obj) === 0);
}
return false;
}
/** Backwards compatibility -- use PHP5's native __tostring method. */
function toString() {
return $this->getPath();
}
/** PHP5's native method. */
function __toString() {
return $this->getPath();
}
}

View file

@ -0,0 +1,91 @@
<?php
/*
* $Id: Reader.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* Abstract class for reading character streams.
*
* @author Hans Lellelid <hans@xmpl.org>
* @author Yannick Lecaillez <yl@seasonfive.com>
* @version $Revision: 905 $
* @package phing.system.io
*/
abstract class Reader {
/**
* Read data from source.
*
* If length is specified, then only that number of chars is read,
* otherwise stream is read until EOF.
*
* @param int $len
*/
abstract public function read($len = null);
/**
* Close stream.
* @throws IOException if there is an error closing stream
*/
abstract public function close();
/**
* Returns the filename, url, etc. that is being read from.
* This is critical for, e.g., ExpatParser's ability to know
* the filename that is throwing an ExpatParserException, etc.
* @return string
*/
abstract function getResource();
/**
* Move stream position relative to current pos.
* @param int $n
*/
public function skip($n) {}
/**
* Reset the current position in stream to beginning or last mark (if supported).
*/
public function reset() {}
/**
* If supported, places a "marker" (like a bookmark) at current stream position.
* A subsequent call to reset() will move stream position back
* to last marker (if supported).
*/
public function mark() {}
/**
* Whether marking is supported.
* @return boolean
*/
public function markSupported() {
return false;
}
/**
* Is stream ready for reading.
* @return boolean
*/
public function ready() {
return true;
}
}

View file

@ -0,0 +1,84 @@
<?php
/*
* $Id: StringReader.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* Dummy class for reading from string of characters.
* @package phing.system.io
*/
class StringReader extends Reader {
/**
* @var string
*/
private $_string;
/**
* @var int
*/
private $mark = 0;
/**
* @var int
*/
private $currPos = 0;
function __construct($string) {
$this->_string = $string;
}
function skip($n) {}
function read($len = null) {
if ($len === null) {
return $this->_string;
} else {
if ($this->currPos >= strlen($this->_string)) {
return -1;
}
$out = substr($this->_string, $this->currPos, $len);
$this->currPos += $len;
return $out;
}
}
function mark() {
$this->mark = $this->currPos;
}
function reset() {
$this->currPos = $this->mark;
}
function close() {}
function open() {}
function ready() {}
function markSupported() {
return true;
}
function getResource() {
return '(string) "'.$this->_string . '"';
}
}

View file

@ -0,0 +1,306 @@
<?php
/*
* $Id: UnixFileSystem.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/FileSystem.php';
/**
* UnixFileSystem class. This class encapsulates the basic file system functions
* for platforms using the unix (posix)-stylish filesystem. It wraps php native
* functions suppressing normal PHP error reporting and instead uses Exception
* to report and error.
*
* This class is part of a oop based filesystem abstraction and targeted to run
* on all supported php platforms.
*
* Note: For debugging turn track_errors on in the php.ini. The error messages
* and log messages from this class will then be clearer because $php_errormsg
* is passed as part of the message.
*
* FIXME:
* - Comments
* - Error handling reduced to min, error are handled by PhingFile mainly
*
* @author Andreas Aderhold, andi@binarycloud.com
* @version $Revision: 905 $
* @package phing.system.io
*/
class UnixFileSystem extends FileSystem {
/**
* returns OS dependant path separator char
*/
function getSeparator() {
return '/';
}
/**
* returns OS dependant directory separator char
*/
function getPathSeparator() {
return ':';
}
/**
* A normal Unix pathname contains no duplicate slashes and does not end
* with a slash. It may be the empty string.
*
* Check that the given pathname is normal. If not, invoke the real
* normalizer on the part of the pathname that requires normalization.
* This way we iterate through the whole pathname string only once.
*/
function normalize($strPathname) {
if (!strlen($strPathname)) {
return;
}
// Resolve home directories. We assume /home is where all home
// directories reside, b/c there is no other way to do this with
// PHP AFAIK.
if ($strPathname{0} === "~") {
if ($strPathname{1} === "/") { // like ~/foo => /home/user/foo
$strPathname = "/home/" . get_current_user() . substr($strPathname, 1);
} else { // like ~foo => /home/foo
$pos = strpos($strPathname, "/");
$name = substr($strPathname, 1, $pos - 2);
$strPathname = "/home/" . $name . substr($strPathname, $pos);
}
}
$n = strlen($strPathname);
$prevChar = 0;
for ($i=0; $i < $n; $i++) {
$c = $strPathname{$i};
if (($prevChar === '/') && ($c === '/')) {
return self::normalizer($strPathname, $n, $i - 1);
}
$prevChar = $c;
}
if ($prevChar === '/') {
return self::normalizer($strPathname, $n, $n - 1);
}
return $strPathname;
}
/**
* Normalize the given pathname, whose length is $len, starting at the given
* $offset; everything before this offset is already normal.
*/
protected function normalizer($pathname, $len, $offset) {
if ($len === 0) {
return $pathname;
}
$n = (int) $len;
while (($n > 0) && ($pathname{$n-1} === '/')) {
$n--;
}
if ($n === 0) {
return '/';
}
$sb = "";
if ($offset > 0) {
$sb .= substr($pathname, 0, $offset);
}
$prevChar = 0;
for ($i = $offset; $i < $n; $i++) {
$c = $pathname{$i};
if (($prevChar === '/') && ($c === '/')) {
continue;
}
$sb .= $c;
$prevChar = $c;
}
return $sb;
}
/**
* Compute the length of the pathname string's prefix. The pathname
* string must be in normal form.
*/
function prefixLength($pathname) {
if (strlen($pathname === 0)) {
return 0;
}
return (($pathname{0} === '/') ? 1 : 0);
}
/**
* Resolve the child pathname string against the parent.
* Both strings must be in normal form, and the result
* will be in normal form.
*/
function resolve($parent, $child) {
if ($child === "") {
return $parent;
}
if ($child{0} === '/') {
if ($parent === '/') {
return $child;
}
return $parent.$child;
}
if ($parent === '/') {
return $parent.$child;
}
return $parent.'/'.$child;
}
function getDefaultParent() {
return '/';
}
function isAbsolute(PhingFile $f) {
return ($f->getPrefixLength() !== 0);
}
/**
* the file resolver
*/
function resolveFile(PhingFile $f) {
// resolve if parent is a file oject only
if ($this->isAbsolute($f)) {
return $f->getPath();
} else {
return $this->resolve(Phing::getProperty("user.dir"), $f->getPath());
}
}
/* -- most of the following is mapped to the php natives wrapped by FileSystem */
/* -- Attribute accessors -- */
function getBooleanAttributes(&$f) {
//$rv = getBooleanAttributes0($f);
$name = $f->getName();
$hidden = (strlen($name) > 0) && ($name{0} == '.');
return ($hidden ? $this->BA_HIDDEN : 0);
}
/**
* set file readonly on unix
*/
function setReadOnly($f) {
if ($f instanceof File) {
$strPath = (string) $f->getPath();
$perms = (int) (@fileperms($strPath) & 0444);
return FileSystem::Chmod($strPath, $perms);
} else {
throw new Exception("IllegalArgutmentType: Argument is not File");
}
}
/**
* compares file paths lexicographically
*/
function compare($f1, $f2) {
if ( ($f1 instanceof PhingFile) && ($f2 instanceof PhingFile) ) {
$f1Path = $f1->getPath();
$f2Path = $f2->getPath();
return (boolean) strcmp((string) $f1Path, (string) $f2Path);
} else {
throw new Exception("IllegalArgutmentType: Argument is not PhingFile");
}
}
/**
* Copy a file, takes care of symbolic links
*
* @param PhingFile $src Source path and name file to copy.
* @param PhingFile $dest Destination path and name of new file.
*
* @return void
* @throws Exception if file cannot be copied.
*/
function copy(PhingFile $src, PhingFile $dest) {
global $php_errormsg;
if (!$src->isLink())
{
return parent::copy($src, $dest);
}
$srcPath = $src->getAbsolutePath();
$destPath = $dest->getAbsolutePath();
$linkTarget = $src->getLinkTarget();
if (false === @symlink($linkTarget, $destPath))
{
$msg = "FileSystem::copy() FAILED. Cannot create symlink from $destPath to $linkTarget.";
throw new Exception($msg);
}
}
/* -- fs interface --*/
function listRoots() {
if (!$this->checkAccess('/', false)) {
die ("Can not access root");
}
return array(new PhingFile("/"));
}
/**
* returns the contents of a directory in an array
*/
function lister($f) {
$dir = @opendir($f->getAbsolutePath());
if (!$dir) {
throw new Exception("Can't open directory " . $f->__toString());
}
$vv = array();
while (($file = @readdir($dir)) !== false) {
if ($file == "." || $file == "..") {
continue;
}
$vv[] = (string) $file;
}
@closedir($dir);
return $vv;
}
function fromURIPath($p) {
if (StringHelper::endsWith("/", $p) && (strlen($p) > 1)) {
// "/foo/" --> "/foo", but "/" --> "/"
$p = substr($p, 0, strlen($p) - 1);
}
return $p;
}
/**
* Whether file can be deleted.
* @param PhingFile $f
* @return boolean
*/
function canDelete(PhingFile $f)
{
@clearstatcache();
$dir = dirname($f->getAbsolutePath());
return (bool) @is_writable($dir);
}
}

View file

@ -0,0 +1,477 @@
<?php
/*
* $Id: Win32FileSystem.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/FileSystem.php';
/**
* @package phing.system.io
*/
class Win32FileSystem extends FileSystem {
protected $slash;
protected $altSlash;
protected $semicolon;
private static $driveDirCache = array();
function __construct() {
$this->slash = self::getSeparator();
$this->semicolon = self::getPathSeparator();
$this->altSlash = ($this->slash === '\\') ? '/' : '\\';
}
function isSlash($c) {
return ($c == '\\') || ($c == '/');
}
function isLetter($c) {
return ((ord($c) >= ord('a')) && (ord($c) <= ord('z')))
|| ((ord($c) >= ord('A')) && (ord($c) <= ord('Z')));
}
function slashify($p) {
if ((strlen($p) > 0) && ($p{0} != $this->slash)) {
return $this->slash.$p;
}
else {
return $p;
}
}
/* -- Normalization and construction -- */
function getSeparator() {
// the ascii value of is the \
return chr(92);
}
function getPathSeparator() {
return ';';
}
/**
* A normal Win32 pathname contains no duplicate slashes, except possibly
* for a UNC prefix, and does not end with a slash. It may be the empty
* string. Normalized Win32 pathnames have the convenient property that
* the length of the prefix almost uniquely identifies the type of the path
* and whether it is absolute or relative:
*
* 0 relative to both drive and directory
* 1 drive-relative (begins with '\\')
* 2 absolute UNC (if first char is '\\'), else directory-relative (has form "z:foo")
* 3 absolute local pathname (begins with "z:\\")
*/
function normalizePrefix($strPath, $len, &$sb) {
$src = 0;
while (($src < $len) && $this->isSlash($strPath{$src})) {
$src++;
}
$c = "";
if (($len - $src >= 2)
&& $this->isLetter($c = $strPath{$src})
&& $strPath{$src + 1} === ':') {
/* Remove leading slashes if followed by drive specifier.
* This hack is necessary to support file URLs containing drive
* specifiers (e.g., "file://c:/path"). As a side effect,
* "/c:/path" can be used as an alternative to "c:/path". */
$sb .= $c;
$sb .= ':';
$src += 2;
}
else {
$src = 0;
if (($len >= 2)
&& $this->isSlash($strPath{0})
&& $this->isSlash($strPath{1})) {
/* UNC pathname: Retain first slash; leave src pointed at
* second slash so that further slashes will be collapsed
* into the second slash. The result will be a pathname
* beginning with "\\\\" followed (most likely) by a host
* name. */
$src = 1;
$sb.=$this->slash;
}
}
return $src;
}
/** Normalize the given pathname, whose length is len, starting at the given
offset; everything before this offset is already normal. */
protected function normalizer($strPath, $len, $offset) {
if ($len == 0) {
return $strPath;
}
if ($offset < 3) {
$offset = 0; //Avoid fencepost cases with UNC pathnames
}
$src = 0;
$slash = $this->slash;
$sb = "";
if ($offset == 0) {
// Complete normalization, including prefix
$src = $this->normalizePrefix($strPath, $len, $sb);
} else {
// Partial normalization
$src = $offset;
$sb .= substr($strPath, 0, $offset);
}
// Remove redundant slashes from the remainder of the path, forcing all
// slashes into the preferred slash
while ($src < $len) {
$c = $strPath{$src++};
if ($this->isSlash($c)) {
while (($src < $len) && $this->isSlash($strPath{$src})) {
$src++;
}
if ($src === $len) {
/* Check for trailing separator */
$sn = (int) strlen($sb);
if (($sn == 2) && ($sb{1} === ':')) {
// "z:\\"
$sb .= $slash;
break;
}
if ($sn === 0) {
// "\\"
$sb .= $slash;
break;
}
if (($sn === 1) && ($this->isSlash($sb{0}))) {
/* "\\\\" is not collapsed to "\\" because "\\\\" marks
the beginning of a UNC pathname. Even though it is
not, by itself, a valid UNC pathname, we leave it as
is in order to be consistent with the win32 APIs,
which treat this case as an invalid UNC pathname
rather than as an alias for the root directory of
the current drive. */
$sb .= $slash;
break;
}
// Path does not denote a root directory, so do not append
// trailing slash
break;
} else {
$sb .= $slash;
}
} else {
$sb.=$c;
}
}
$rv = (string) $sb;
return $rv;
}
/**
* Check that the given pathname is normal. If not, invoke the real
* normalizer on the part of the pathname that requires normalization.
* This way we iterate through the whole pathname string only once.
* @param string $strPath
* @return string
*/
function normalize($strPath) {
$n = strlen($strPath);
$slash = $this->slash;
$altSlash = $this->altSlash;
$prev = 0;
for ($i = 0; $i < $n; $i++) {
$c = $strPath{$i};
if ($c === $altSlash) {
return $this->normalizer($strPath, $n, ($prev === $slash) ? $i - 1 : $i);
}
if (($c === $slash) && ($prev === $slash) && ($i > 1)) {
return $this->normalizer($strPath, $n, $i - 1);
}
if (($c === ':') && ($i > 1)) {
return $this->normalizer($strPath, $n, 0);
}
$prev = $c;
}
if ($prev === $slash) {
return $this->normalizer($strPath, $n, $n - 1);
}
return $strPath;
}
function prefixLength($strPath) {
$path = (string) $strPath;
$slash = (string) $this->slash;
$n = (int) strlen($path);
if ($n === 0) {
return 0;
}
$c0 = $path{0};
$c1 = ($n > 1) ? $path{1} :
0;
if ($c0 === $slash) {
if ($c1 === $slash) {
return 2; // absolute UNC pathname "\\\\foo"
}
return 1; // drive-relative "\\foo"
}
if ($this->isLetter($c0) && ($c1 === ':')) {
if (($n > 2) && ($path{2}) === $slash) {
return 3; // Absolute local pathname "z:\\foo" */
}
return 2; // Directory-relative "z:foo"
}
return 0; // Completely relative
}
function resolve($parent, $child) {
$parent = (string) $parent;
$child = (string) $child;
$slash = (string) $this->slash;
$pn = (int) strlen($parent);
if ($pn === 0) {
return $child;
}
$cn = (int) strlen($child);
if ($cn === 0) {
return $parent;
}
$c = $child;
if (($cn > 1) && ($c{0} === $slash)) {
if ($c{1} === $slash) {
// drop prefix when child is a UNC pathname
$c = substr($c, 2);
}
else {
//Drop prefix when child is drive-relative */
$c = substr($c, 1);
}
}
$p = $parent;
if ($p{$pn - 1} === $slash) {
$p = substr($p, 0, $pn - 1);
}
return $p.$this->slashify($c);
}
function getDefaultParent() {
return (string) ("".$this->slash);
}
function fromURIPath($strPath) {
$p = (string) $strPath;
if ((strlen($p) > 2) && ($p{2} === ':')) {
// "/c:/foo" --> "c:/foo"
$p = substr($p,1);
// "c:/foo/" --> "c:/foo", but "c:/" --> "c:/"
if ((strlen($p) > 3) && StringHelper::endsWith('/', $p)) {
$p = substr($p, 0, strlen($p) - 1);
}
} elseif ((strlen($p) > 1) && StringHelper::endsWith('/', $p)) {
// "/foo/" --> "/foo"
$p = substr($p, 0, strlen($p) - 1);
}
return (string) $p;
}
/* -- Path operations -- */
function isAbsolute(PhingFile $f) {
$pl = (int) $f->getPrefixLength();
$p = (string) $f->getPath();
return ((($pl === 2) && ($p{0} === $this->slash)) || ($pl === 3) || ($pl === 1 && $p{0} === $this->slash));
}
/** private */
function _driveIndex($d) {
$d = (string) $d{0};
if ((ord($d) >= ord('a')) && (ord($d) <= ord('z'))) {
return ord($d) - ord('a');
}
if ((ord($d) >= ord('A')) && (ord($d) <= ord('Z'))) {
return ord($d) - ord('A');
}
return -1;
}
/** private */
function _getDriveDirectory($drive) {
$drive = (string) $drive{0};
$i = (int) $this->_driveIndex($drive);
if ($i < 0) {
return null;
}
$s = (isset(self::$driveDirCache[$i]) ? self::$driveDirCache[$i] : null);
if ($s !== null) {
return $s;
}
$s = $this->_getDriveDirectory($i + 1);
self::$driveDirCache[$i] = $s;
return $s;
}
function _getUserPath() {
//For both compatibility and security, we must look this up every time
return (string) $this->normalize(Phing::getProperty("user.dir"));
}
function _getDrive($path) {
$path = (string) $path;
$pl = $this->prefixLength($path);
return ($pl === 3) ? substr($path, 0, 2) : null;
}
function resolveFile(PhingFile $f) {
$path = $f->getPath();
$pl = (int) $f->getPrefixLength();
if (($pl === 2) && ($path{0} === $this->slash)) {
return $path; // UNC
}
if ($pl === 3) {
return $path; // Absolute local
}
if ($pl === 0) {
return (string) ($this->_getUserPath().$this->slashify($path)); //Completely relative
}
if ($pl === 1) { // Drive-relative
$up = (string) $this->_getUserPath();
$ud = (string) $this->_getDrive($up);
if ($ud !== null) {
return (string) $ud.$path;
}
return (string) $up.$path; //User dir is a UNC path
}
if ($pl === 2) { // Directory-relative
$up = (string) $this->_getUserPath();
$ud = (string) $this->_getDrive($up);
if (($ud !== null) && StringHelper::startsWith($ud, $path)) {
return (string) ($up . $this->slashify(substr($path,2)));
}
$drive = (string) $path{0};
$dir = (string) $this->_getDriveDirectory($drive);
$np = (string) "";
if ($dir !== null) {
/* When resolving a directory-relative path that refers to a
drive other than the current drive, insist that the caller
have read permission on the result */
$p = (string) $drive . (':'.$dir.$this->slashify(substr($path,2)));
if (!$this->checkAccess($p, false)) {
// FIXME
// throw security error
die("Can't resolve path $p");
}
return $p;
}
return (string) $drive.':'.$this->slashify(substr($path,2)); //fake it
}
throw new Exception("Unresolvable path: " . $path);
}
/* -- most of the following is mapped to the functions mapped th php natives in FileSystem */
/* -- Attribute accessors -- */
function setReadOnly($f) {
// dunno how to do this on win
throw new Exception("WIN32FileSystem doesn't support read-only yet.");
}
/* -- Filesystem interface -- */
protected function _access($path) {
if (!$this->checkAccess($path, false)) {
throw new Exception("Can't resolve path $p");
}
return true;
}
function _nativeListRoots() {
// FIXME
}
function listRoots() {
$ds = _nativeListRoots();
$n = 0;
for ($i = 0; $i < 26; $i++) {
if ((($ds >> $i) & 1) !== 0) {
if (!$this->access((string)( chr(ord('A') + $i) . ':' . $this->slash))) {
$ds &= ~(1 << $i);
} else {
$n++;
}
}
}
$fs = array();
$j = (int) 0;
$slash = (string) $this->slash;
for ($i = 0; $i < 26; $i++) {
if ((($ds >> $i) & 1) !== 0) {
$fs[$j++] = new PhingFile(chr(ord('A') + $i) . ':' . $this->slash);
}
}
return $fs;
}
/* -- Basic infrastructure -- */
/** compares file paths lexicographically */
function compare(PhingFile $f1, PhingFile $f2) {
$f1Path = $f1->getPath();
$f2Path = $f2->getPath();
return (boolean) strcasecmp((string) $f1Path, (string) $f2Path);
}
/**
* returns the contents of a directory in an array
*/
function lister($f) {
$dir = @opendir($f->getAbsolutePath());
if (!$dir) {
throw new Exception("Can't open directory " . $f->__toString());
}
$vv = array();
while (($file = @readdir($dir)) !== false) {
if ($file == "." || $file == "..") {
continue;
}
$vv[] = (string) $file;
}
@closedir($dir);
return $vv;
}
}

View file

@ -0,0 +1,35 @@
<?php
/*
* $Id: WinNTFileSystem.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/Win32FileSystem.php';
/**
* FileSystem for Windows NT/2000.
* @package phing.system.io
*/
class WinNTFileSystem extends Win32FileSystem {
/* -- class only for convenience and future use everything is inherinted --*/
}

View file

@ -0,0 +1,53 @@
<?php
/*
* $Id: Writer.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* Abstract class for writing character streams.
*
* @package phing.system.io
*/
abstract class Writer {
/**
* Writes data to output stream.
* @param string $buf
* @param int $off
* @param int $len
*/
abstract public function write($buf, $off = null, $len = null);
/**
* Close the stream.
* @throws IOException - if there is an error closing stream.
*/
abstract public function close();
/**
* Flush the stream, if supported by the stream.
*/
public function flush() {}
/**
* Returns a string representation of resource filename, url, etc. that is being written to.
* @return string
*/
abstract public function getResource();
}

View file

@ -0,0 +1,49 @@
<?php
/*
* $Id: Character.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* @package phing.system.lang
*/
class Character {
// this class might be extended with plenty of ordinal char constants
// and the like to support the multibyte aware datatype (char) in php
// in form of an object.
// anyway just a thought
public static function isLetter($char) {
if (strlen($char) !== 1)
$char = 0;
$char = (int) ord($char);
if ($char >= ord('A') && $char <= ord('Z'))
return true;
if ($char >= ord('a') && $char <= ord('z'))
return true;
return false;
}
}

View file

@ -0,0 +1,52 @@
<?php
/*
* $Id: EventObject.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* @package phing.system.lang
*/
class EventObject {
/** The object on which the Event initially occurred. */
protected $source;
/** Constructs a prototypical Event. */
function __construct($source) {
if ($source === null) {
throw new Exception("Null source");
}
$this->source = $source;
}
/** The object on which the Event initially occurred. */
function getSource() {
return $this->source;
}
/** Returns a String representation of this EventObject.*/
function toString() {
if (method_exists($this->source, "toString")) {
return get_class($this)."[source=".$this->source->toString()."]";
} else {
return get_class($this)."[source=".get_class($this->source)."]";
}
}
}

View file

@ -0,0 +1,26 @@
<?php
/*
* $Id: FileNotFoundException.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* @package phing.system.lang
*/
class FileNotFoundException extends Exception {}

View file

@ -0,0 +1,26 @@
<?php
/*
* $Id: NullPointerException.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* @package phing.system.lang
*/
class NullPointerException extends Exception {}

View file

@ -0,0 +1,26 @@
<?php
/*
* $Id: SecurityException.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* @package phing.system.lang
*/
class SecurityException extends Exception {}

View file

@ -0,0 +1,289 @@
<?php
/*
* $Id: Properties.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
include_once 'phing/system/io/PhingFile.php';
include_once 'phing/system/io/FileWriter.php';
/**
* Convenience class for reading and writing property files.
*
* FIXME
* - Add support for arrays (separated by ',')
*
* @package phing.system.util
* @version $Revision: 905 $
*/
class Properties {
private $properties = array();
/**
* Load properties from a file.
*
* @param PhingFile $file
* @return void
* @throws IOException - if unable to read file.
*/
function load(PhingFile $file) {
if ($file->canRead()) {
$this->parse($file->getPath(), false);
} else {
throw new IOException("Can not read file ".$file->getPath());
}
}
/**
* Replaces parse_ini_file() or better_parse_ini_file().
* Saves a step since we don't have to parse and then check return value
* before throwing an error or setting class properties.
*
* @param string $filePath
* @param boolean $processSections Whether to honor [SectionName] sections in INI file.
* @return array Properties loaded from file (no prop replacements done yet).
*/
protected function parse($filePath) {
// load() already made sure that file is readable
// but we'll double check that when reading the file into
// an array
if (($lines = @file($filePath)) === false) {
throw new IOException("Unable to parse contents of $filePath");
}
$this->properties = array();
$sec_name = "";
foreach($lines as $line) {
$line = trim($line);
if($line == "")
continue;
if ($line{0} == '#' or $line{0} == ';') {
// it's a comment, so continue to next line
continue;
} else {
$pos = strpos($line, '=');
$property = trim(substr($line, 0, $pos));
$value = trim(substr($line, $pos + 1));
$this->properties[$property] = $this->inVal($value);
}
} // for each line
}
/**
* Process values when being read in from properties file.
* does things like convert "true" => true
* @param string $val Trimmed value.
* @return mixed The new property value (may be boolean, etc.)
*/
protected function inVal($val) {
if ($val === "true") {
$val = true;
} elseif ($val === "false") {
$val = false;
}
return $val;
}
/**
* Process values when being written out to properties file.
* does things like convert true => "true"
* @param mixed $val The property value (may be boolean, etc.)
* @return string
*/
protected function outVal($val) {
if ($val === true) {
$val = "true";
} elseif ($val === false) {
$val = "false";
}
return $val;
}
/**
* Create string representation that can be written to file and would be loadable using load() method.
*
* Essentially this function creates a string representation of properties that is ready to
* write back out to a properties file. This is used by store() method.
*
* @return string
*/
public function toString() {
$buf = "";
foreach($this->properties as $key => $item) {
$buf .= $key . "=" . $this->outVal($item) . PHP_EOL;
}
return $buf;
}
/**
* Stores current properties to specified file.
*
* @param PhingFile $file File to create/overwrite with properties.
* @param string $header Header text that will be placed (within comments) at the top of properties file.
* @return void
* @throws IOException - on error writing properties file.
*/
function store(PhingFile $file, $header = null) {
// stores the properties in this object in the file denoted
// if file is not given and the properties were loaded from a
// file prior, this method stores them in the file used by load()
try {
$fw = new FileWriter($file);
if ($header !== null) {
$fw->write( "# " . $header . PHP_EOL );
}
$fw->write($this->toString());
$fw->close();
} catch (IOException $e) {
throw new IOException("Error writing property file: " . $e->getMessage());
}
}
/**
* Returns copy of internal properties hash.
* Mostly for performance reasons, property hashes are often
* preferable to passing around objects.
*
* @return array
*/
function getProperties() {
return $this->properties;
}
/**
* Get value for specified property.
* This is the same as get() method.
*
* @param string $prop The property name (key).
* @return mixed
* @see get()
*/
function getProperty($prop) {
if (!isset($this->properties[$prop])) {
return null;
}
return $this->properties[$prop];
}
/**
* Get value for specified property.
* This function exists to provide a hashtable-like interface for
* properties.
*
* @param string $prop The property name (key).
* @return mixed
* @see getProperty()
*/
function get($prop) {
if (!isset($this->properties[$prop])) {
return null;
}
return $this->properties[$prop];
}
/**
* Set the value for a property.
*
* @param string $key
* @param mixed $value
* @return mixed Old property value or NULL if none was set.
*/
function setProperty($key, $value) {
$oldValue = null;
if (isset($this->properties[$key])) {
$oldValue = $this->properties[$key];
}
$this->properties[$key] = $value;
return $oldValue;
}
/**
* Set the value for a property.
* This function exists to provide hashtable-lie
* interface for properties.
*
* @param string $key
* @param mixed $value
*/
function put($key, $value) {
return $this->setProperty($key, $value);
}
/**
* Appends a value to a property if it already exists with a delimiter
*
* If the property does not, it just adds it.
*
* @param string $key
* @param mixed $value
* @param string $delimiter
*/
function append($key, $value, $delimiter = ',') {
$newValue = $value;
if (isset($this->properties[$key]) && !empty($this->properties[$key]) ) {
$newValue = $this->properties[$key] . $delimiter . $value;
}
$this->properties[$key] = $newValue;
}
/**
* Same as keys() function, returns an array of property names.
* @return array
*/
function propertyNames() {
return $this->keys();
}
/**
* Whether loaded properties array contains specified property name.
* @return boolean
*/
function containsKey($key) {
return isset($this->properties[$key]);
}
/**
* Returns properties keys.
* Use this for foreach() {} iterations, as this is
* faster than looping through property values.
* @return array
*/
function keys() {
return array_keys($this->properties);
}
/**
* Whether properties list is empty.
* @return boolean
*/
function isEmpty() {
return empty($this->properties);
}
}

View file

@ -0,0 +1,115 @@
<?php
/**
* Static class to handle a slot-listening system.
*
* Unlike the slots/signals Qt model, this class manages something that is
* more like a simple hashtable, where each slot has only one value. For that
* reason "Registers" makes more sense, the reference being to CPU registers.
*
* This could be used for anything, but it's been built for a pretty specific phing
* need, and that is to allow access to dynamic values that are set by logic
* that is not represented in a build file. For exampe, we need a system for getting
* the current resource (file) that is being processed by a filterchain in a fileset.
*
* Each slot corresponds to only one read-only, dynamic-value RegisterSlot object. In
* a build.xml register slots are expressed using a syntax similar to variables:
*
* <replaceregexp>
* <regexp pattern="\n" replace="%{task.current_file}"/>
* </replaceregexp>
*
* The task/type must provide a supporting setter for the attribute:
*
* <code>
* function setListeningReplace(RegisterSlot $slot) {
* $this->replace = $slot;
* }
*
* // in main()
* if ($this->replace instanceof RegisterSlot) {
* $this->regexp->setReplace($this->replace->getValue());
* } else {
* $this->regexp->setReplace($this->replace);
* }
* </code>
*
* @author Hans Lellelid <hans@xmpl.org>
* @version $Revision: 905 $
* @package phing.system.util
*/
class Register {
/** Slots that have been registered */
private static $slots = array();
/**
* Returns RegisterSlot for specified key.
*
* If not slot exists a new one is created for key.
*
* @param string $key
* @return RegisterSlot
*/
public static function getSlot($key) {
if (!isset(self::$slots[$key])) {
self::$slots[$key] = new RegisterSlot($key);
}
return self::$slots[$key];
}
}
/**
* Represents a slot in the register.
*/
class RegisterSlot {
/** The name of this slot. */
private $key;
/** The value for this slot. */
private $value;
/**
* Constructs a new RegisterSlot, setting the key to passed param.
* @param string $key
*/
public function __construct($key) {
$this->key = (string) $key;
}
/**
* Sets the key / name for this slot.
* @param string $k
*/
public function setKey($k) {
$this->key = (string) $k;
}
/**
* Gets the key / name for this slot.
* @return string
*/
public function getKey() {
return $this->key;
}
/**
* Sets the value for this slot.
* @param mixed
*/
public function setValue($v) {
$this->value = $v;
}
/**
* Returns the value at this slot.
* @return mixed
*/
public function getValue() {
return $this->value;
}
}

View file

@ -0,0 +1,96 @@
<?php
/*
* $Id: Timer.php 905 2010-10-05 16:28:03Z mrook $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information please see
* <http://phing.info>.
*/
/**
* This class can be used to obtain the execution time of all of the scripts
* that are executed in the process of building a page.
*
* Example:
* To be done before any scripts execute:
*
* $Timer = new Timer;
* $Timer->Start_Timer();
*
* To be done after all scripts have executed:
*
* $timer->Stop_Timer();
* $timer->Get_Elapsed_Time(int number_of_places);
*
* @author Charles Killian
* @author Hans Lellelid <hans@xmpl.org>
* @package phing.system.util
* @version $Revision: 905 $ $Date: 2010-10-05 18:28:03 +0200 (Tue, 05 Oct 2010) $
*/
class Timer {
/** start time */
protected $stime;
/** end time */
protected $etime;
/**
* This function sets the class variable $stime to the current time in
* microseconds.
* @return void
*/
public function start() {
$this->stime = $this->getMicrotime();
}
/**
* This function sets the class variable $etime to the current time in
* microseconds.
* @return void
*/
function stop() {
$this->etime = $this->getMicrotime();
}
/**
* This function returns the elapsed time in seconds.
*
* Call start_time() at the beginning of script execution and end_time() at
* the end of script execution. Then, call elapsed_time() to obtain the
* difference between start_time() and end_time().
*
* @param $places decimal place precision of elapsed time (default is 5)
* @return string Properly formatted time.
*/
function getElapsedTime($places=5) {
$etime = $this->etime - $this->stime;
$format = "%0.".$places."f";
return (sprintf ($format, $etime));
}
/**
* This function returns the current time in microseconds.
*
* @author Everett Michaud, Zend.com
* @return current time in microseconds
* @access private
*/
function getMicrotime() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
}