summaryrefslogtreecommitdiff
path: root/buildscripts/phing/classes/phing/system/io
diff options
context:
space:
mode:
Diffstat (limited to 'buildscripts/phing/classes/phing/system/io')
-rw-r--r--buildscripts/phing/classes/phing/system/io/BufferedReader.php170
-rw-r--r--buildscripts/phing/classes/phing/system/io/BufferedWriter.php72
-rw-r--r--buildscripts/phing/classes/phing/system/io/ConsoleReader.php84
-rw-r--r--buildscripts/phing/classes/phing/system/io/FileReader.php179
-rw-r--r--buildscripts/phing/classes/phing/system/io/FileSystem.php657
-rw-r--r--buildscripts/phing/classes/phing/system/io/FileWriter.php139
-rw-r--r--buildscripts/phing/classes/phing/system/io/FilterReader.php72
-rw-r--r--buildscripts/phing/classes/phing/system/io/IOException.php28
-rw-r--r--buildscripts/phing/classes/phing/system/io/PhingFile.php866
-rw-r--r--buildscripts/phing/classes/phing/system/io/Reader.php88
-rw-r--r--buildscripts/phing/classes/phing/system/io/StringReader.php73
-rw-r--r--buildscripts/phing/classes/phing/system/io/TokenReader.php51
-rw-r--r--buildscripts/phing/classes/phing/system/io/UnixFileSystem.php266
-rw-r--r--buildscripts/phing/classes/phing/system/io/Win32FileSystem.php477
-rw-r--r--buildscripts/phing/classes/phing/system/io/WinNTFileSystem.php35
-rw-r--r--buildscripts/phing/classes/phing/system/io/Writer.php48
16 files changed, 3305 insertions, 0 deletions
diff --git a/buildscripts/phing/classes/phing/system/io/BufferedReader.php b/buildscripts/phing/classes/phing/system/io/BufferedReader.php
new file mode 100644
index 00000000..4946985c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/BufferedReader.php
@@ -0,0 +1,170 @@
+<?php
+/*
+ * $Id: BufferedReader.php,v 1.6 2005/12/27 19:12:13 hlellelid Exp $
+ *
+ * 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: 1.6 $ $Date: 2005/12/27 19:12:13 $
+ * @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 $_bufferSize chunk of data.
+ * @return mixed buffer or -1 if EOF.
+ */
+ function read($len = null) {
+ // ignore $len param, not sure how to hanlde it, since
+ // this should only read bufferSize amount of data.
+ if ($len !== null) {
+ $this->currentPosition = ftell($this->fd);
+ }
+
+ if ( ($data = $this->in->read($this->bufferSize)) !== -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 forgot 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();
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/BufferedWriter.php b/buildscripts/phing/classes/phing/system/io/BufferedWriter.php
new file mode 100644
index 00000000..c982db28
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/BufferedWriter.php
@@ -0,0 +1,72 @@
+<?php
+/*
+ * $Id: BufferedWriter.php,v 1.10 2005/05/26 13:10:52 mrook Exp $
+ *
+ * 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: 1.10 $
+ * @package phing.system.io
+ */
+class BufferedWriter extends Writer {
+
+ /**
+ * The size of the buffer in kb.
+ */
+ private $bufferSize = 0;
+
+ /**
+ * The Writer we are buffering output to.
+ */
+ private $out;
+
+ function __construct(Writer $writer, $buffsize = 8192) {
+ $this->out = $writer;
+ $this->bufferSize = $buffsize;
+ }
+
+ function write($buf, $off = null, $len = null) {
+ return $this->out->write($buf, $off, $len);
+ }
+
+ function newLine() {
+ $this->write(Phing::getProperty('line.separator'));
+ }
+
+ function getResource() {
+ return $this->out->getResource();
+ }
+
+ function reset() {
+ return $this->out->reset();
+ }
+
+ function close() {
+ return $this->out->close();
+ }
+
+ function open() {
+ return $this->out->open();
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/system/io/ConsoleReader.php b/buildscripts/phing/classes/phing/system/io/ConsoleReader.php
new file mode 100644
index 00000000..33b37619
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/ConsoleReader.php
@@ -0,0 +1,84 @@
+<?php
+/*
+ * $Id: ConsoleReader.php,v 1.4 2004/08/12 16:26:12 matthewh Exp $
+ *
+ * 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: 1.4 $
+ * @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";
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/FileReader.php b/buildscripts/phing/classes/phing/system/io/FileReader.php
new file mode 100644
index 00000000..cbea2c7e
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/FileReader.php
@@ -0,0 +1,179 @@
+<?php
+/*
+ * $Id: FileReader.php,v 1.9 2005/05/26 13:10:52 mrook Exp $
+ *
+ * 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';
+
+/**
+ * Convenience class for reading files. The constructor of this
+ * @package phing.system.io
+ */
+
+class FileReader extends Reader {
+
+ protected $file;
+ protected $fd;
+
+ protected $currentPosition = 0;
+ protected $mark = 0;
+
+ function __construct($file, $exclusive = false) {
+
+ if ($file instanceof PhingFile) {
+ $this->file = $file;
+ } elseif (is_string($file)) {
+ $this->file = new PhingFile($file);
+ } else {
+ throw new Exception("Illegal argument type to " . __METHOD__);
+ }
+ }
+
+ function skip($n) {
+ $this->open();
+
+ $start = $this->currentPosition;
+
+ $ret = @fseek($this->fd, $n, SEEK_CUR);
+ if ( $ret === -1 )
+ return -1;
+
+ $this->currentPosition = ftell($this->fd);
+
+ if ( $start > $this->currentPosition )
+ $skipped = $start - $this->currentPosition;
+ else
+ $skipped = $this->currentPosition - $start;
+
+ return $skipped;
+ }
+
+ /**
+ * Read data from file.
+ * @param int $len Num chars to read.
+ * @return string chars read or -1 if eof.
+ */
+ function read($len = null) {
+ $this->open();
+ if (feof($this->fd)) {
+ return -1;
+ }
+
+ // Compute length to read
+ // possible that filesize($this->file) will be larger than
+ // available bytes to read, but that's fine -- better to err on high end
+ $length = ($len === null) ? filesize($this->file->getAbsolutePath()) : $len;
+
+ // Read data
+ $out = fread($this->fd, $length + 1); // adding 1 seems to ensure that next call to read() will return EOF (-1)
+ $this->currentPosition = ftell($this->fd);
+
+ return $out;
+ }
+
+ function mark($n = null) {
+ $this->mark = $this->currentPosition;
+ }
+
+ function reset() {
+ // goes back to last mark, by default this would be 0 (i.e. rewind file).
+ fseek($this->fd, SEEK_SET, $this->mark);
+ $this->mark = 0;
+ }
+
+ function close() {
+ if ($this->fd === null) {
+ return true;
+ }
+
+ if (false === @fclose($this->fd)) {
+ // FAILED.
+ $msg = "Cannot fclose " . $this->file->__toString() . " $php_errormsg";
+ throw new IOException($msg);
+ } else {
+ $this->fd = null;
+ return true;
+ }
+ }
+
+ function open() {
+ global $php_errormsg;
+
+ if ($this->fd === null) {
+ $this->fd = @fopen($this->file->getAbsolutePath(), "rb");
+ }
+
+ if ($this->fd === false) {
+ // fopen FAILED.
+ // Add error from php to end of log message. $php_errormsg.
+ $msg = "Cannot fopen ".$this->file->getAbsolutePath().". $php_errormsg";
+ throw new IOException($msg);
+ }
+
+ if (false) {
+ // Locks don't seem to work on windows??? HELP!!!!!!!!!
+ // if (FALSE === @flock($fp, LOCK_EX)) { // FAILED.
+ $msg = "Cannot acquire flock on $file. $php_errormsg";
+ throw new IOException($msg);
+ }
+
+ return true;
+ }
+
+ /**
+ * Whether eof has been reached with stream.
+ * @return boolean
+ */
+ function eof() {
+ return feof($this->fd);
+ }
+
+ /**
+ * 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
+ */
+ function readInto(&$rBuffer) {
+
+ $this->open();
+
+ $fileSize = $this->file->length();
+ if ($fileSize === false) {
+ $msg = "Cannot get filesize of " . $this->file->__toString() . " $php_errormsg";
+ throw new IOException($msg);
+ }
+ $rBuffer = fread($this->fd, $fileSize);
+ $this->close();
+ }
+
+ /**
+ * Returns path to file we are reading.
+ * @return string
+ */
+ function getResource() {
+ return $this->file->toString();
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/FileSystem.php b/buildscripts/phing/classes/phing/system/io/FileSystem.php
new file mode 100644
index 00000000..2802ddfb
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/FileSystem.php
@@ -0,0 +1,657 @@
+<?php
+
+/*
+ * $Id: FileSystem.php,v 1.11 2005/12/01 20:56:59 hlellelid Exp $
+ *
+ * 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: 1.11 $
+ * @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.
+ */
+ 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);
+ }
+ }
+
+ /**
+ * 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) {
+ if ($f->isDirectory()) {
+ return $this->rmdir($f->getPath());
+ } 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.
+ */
+ function createDirectory(&$f) {
+ return @mkdir($f->getAbsolutePath(),0755);
+ }
+
+ /**
+ * 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 create directory 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;
+ $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.
+ }
+ }
+
+ /**
+ * 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. $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
+ }
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/system/io/FileWriter.php b/buildscripts/phing/classes/phing/system/io/FileWriter.php
new file mode 100644
index 00000000..d6265777
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/FileWriter.php
@@ -0,0 +1,139 @@
+<?php
+/*
+ * $Id: FileWriter.php,v 1.7 2005/05/26 13:10:52 mrook Exp $
+ *
+ * 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/Writer.php';
+
+/**
+ * Convenience class for reading files. The constructor of this
+ *
+ * @package phing.system.io
+ */
+class FileWriter extends Writer {
+
+ protected $file;
+ protected $fd;
+
+ /** Whether to append contents to file. */
+ protected $append;
+
+ /** Whether we should attempt to lock the file (currently disabled). */
+ protected $exclusive;
+
+ /**
+ * Construct a new FileWriter.
+ * @param mixed $file PhingFile or string pathname.
+ * @param boolean $append Append to existing file?
+ * @param boolean $exclusive Lock file? (currently disabled due to windows incompatibility)
+ */
+ function __construct($file, $append = false, $exclusive = 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.");
+ }
+ $this->append = $append;
+ $this->exclusive = $exclusive;
+ }
+
+ function close() {
+ if ($this->fd === null) {
+ return true;
+ }
+
+ if (false === @fclose($this->fd)) {
+ // FAILED.
+ $msg = "Cannot fclose " . $this->file->__toString() . " $php_errormsg";
+ throw new IOException($msg);
+ } else {
+ $this->fd = null;
+ return true;
+ }
+ }
+
+ function open() {
+ if ($this->fd === null) {
+ if ($this->append) { $flags = "ab"; } else { $flags = "wb"; }
+ $this->fd = @fopen($this->file->getPath(), $flags);
+ }
+
+ if ($this->fd === false) {
+ // fopen FAILED.
+ // Add error from php to end of log message. $php_errormsg.
+ $msg = "Cannot fopen ".$this->file->getPath()." $php_errormsg";
+ throw new IOException($msg);
+ }
+
+ if (false) {
+ // Locks don't seem to work on windows??? HELP!!!!!!!!!
+ // if (FALSE === @flock($fp, LOCK_EX)) { // FAILED.
+ $msg = "Cannot acquire flock on $file. $php_errormsg";
+ throw new IOException($msg);
+ }
+
+ return true;
+ }
+
+ function reset() {
+ // FIXME -- what exactly should this do, if anything?
+ // reset to beginning of file (i.e. re-open)?
+ }
+
+ function writeBuffer($buffer) {
+
+ if (!$this->file->canWrite()) {
+ throw new IOException("No permission to write to file: " . $this->file->__toString());
+ }
+
+ $this->open();
+ $result = @fwrite($this->fd, $buffer);
+ $this->close();
+
+ if ($result === false) {
+ throw new IOException("Error writing file: ". $this->file->toString());
+ } else {
+ return true;
+ }
+ }
+
+ function write($buf, $off = null, $len = null) {
+ if ( $off === null && $len === null )
+ $to_write = $buf;
+ else
+ $to_write = substr($buf, $off, $len);
+
+ $this->open();
+ $result = @fwrite($this->fd, $to_write);
+
+ if ( $result === false ) {
+ throw new IOException("Error writing file.");
+ } else {
+ return true;
+ }
+ }
+
+ function getResource() {
+ return $this->file->toString();
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/FilterReader.php b/buildscripts/phing/classes/phing/system/io/FilterReader.php
new file mode 100644
index 00000000..8c683408
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/FilterReader.php
@@ -0,0 +1,72 @@
+<?php
+/*
+ * $Id: FilterReader.php,v 1.6 2005/05/26 13:10:52 mrook Exp $
+ *
+ * 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. The constructor of this
+ * @package phing.system.io
+ *
+ * TODO: All filters should be ProjectComponents, too!
+ */
+class FilterReader extends Reader {
+
+ protected $in;
+
+ function __construct(Reader $in = null) {
+ $this->in = $in;
+ //parent::__construct(new FileReader($file, $exclusive));
+ }
+
+ 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();
+ }
+
+ public function open() {
+ return $this->in->open();
+ }
+
+ function getResource() {
+ return $this->in->getResource();
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/IOException.php b/buildscripts/phing/classes/phing/system/io/IOException.php
new file mode 100644
index 00000000..e2c73b27
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/IOException.php
@@ -0,0 +1,28 @@
+<?php
+/*
+ * $Id: IOException.php,v 1.4 2005/02/27 20:52:09 mrook Exp $
+ *
+ * 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 {}
+?> \ No newline at end of file
diff --git a/buildscripts/phing/classes/phing/system/io/PhingFile.php b/buildscripts/phing/classes/phing/system/io/PhingFile.php
new file mode 100644
index 00000000..cd881963
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/PhingFile.php
@@ -0,0 +1,866 @@
+<?php
+/*
+ * $Id: PhingFile.php,v 1.1 2005/05/26 13:10:52 mrook Exp $
+ *
+ * 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: 1.1 $
+ * @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;
+ }
+
+ /**
+ * 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() {
+ if ($this->isFile()) {
+ return @file_exists($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() {
+ $fs = FileSystem::getFileSystem();
+ if ($fs->checkAccess($this) !== true) {
+ throw new IOException("No read access to ".$this->path);
+ }
+ return @is_dir($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() {
+ //$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);
+ }
+
+ /**
+ * 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() {
+ $fs = FileSystem::getFileSystem();
+ if ($fs->checkAccess($this, true) !== true) {
+ throw new IOException("No read access to " . $this->path."\n");
+ }
+ return $fs->delete($this);
+ }
+
+ /**
+ * 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() {
+ if ($this->exists()) {
+ return false;
+ }
+ try {
+ if ($this->mkdir()) {
+ return true;
+ }
+ } catch (IOException $ioe) {
+ // IOException from mkdir() means that directory propbably didn't exist.
+ }
+ $parentFile = $this->getParentFile();
+ return (($parentFile !== null) && ($parentFile->mkdirs() && $this->mkdir()));
+ }
+
+ /**
+ * Creates the directory named by this abstract pathname.
+ *
+ * @return true if and only if the directory was created; false otherwise
+ * @throws IOException
+ */
+ function mkdir() {
+ $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);
+ }
+
+ /**
+ * 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");
+ }
+
+ // FIXME check if accessible
+ $fs = FileSystem::getFileSystem();
+ if ($fs->checkAccess($this, true) !== true) {
+ throw new IOException("File::setLastModified(). No write access to file\n");
+ }
+ 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 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();
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/Reader.php b/buildscripts/phing/classes/phing/system/io/Reader.php
new file mode 100644
index 00000000..1e377378
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/Reader.php
@@ -0,0 +1,88 @@
+<?php
+/*
+ * $Id: Reader.php,v 1.5 2003/12/24 12:38:40 hlellelid Exp $
+ *
+ * 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: 1.5 $
+ * @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.
+ */
+ abstract public function close();
+
+ /**
+ * Open stream for reading.
+ */
+ abstract public function open();
+
+ /**
+ * 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() {}
+
+ /**
+ * Is stream ready for reading.
+ * @return boolean
+ */
+ public function ready() {}
+
+}
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/StringReader.php b/buildscripts/phing/classes/phing/system/io/StringReader.php
new file mode 100644
index 00000000..689a2115
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/StringReader.php
@@ -0,0 +1,73 @@
+<?php
+/*
+ * $Id: StringReader.php,v 1.8 2005/05/26 13:10:52 mrook Exp $
+ *
+ * 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 character streams.
+ * @package phing.system.io
+ */
+class StringReader extends Reader {
+
+ private $_string;
+ private $mark = 0;
+ 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 . '"';
+ }
+}
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/TokenReader.php b/buildscripts/phing/classes/phing/system/io/TokenReader.php
new file mode 100644
index 00000000..a57d994c
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/TokenReader.php
@@ -0,0 +1,51 @@
+<?php
+/*
+ * $Id: TokenReader.php,v 1.3 2003/11/19 05:48:29 hlellelid Exp $
+ *
+ * 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';
+include_once 'phing/filters/ReplaceTokens.php'; // for class Token
+
+/**
+ * Abstract class for reading Tokens from a resource
+ *
+ * @author Manuel Holtgewe
+ * @version $Revision: 1.3 $
+ * @access public
+ * @package phing.system.io
+ */
+class TokenReader extends Reader {
+
+ /**
+ * Constructor
+ */
+ function __construct() {
+ }
+
+ /**
+ * Reads a token from the resource and returns it as a
+ * Token object.
+ *
+ * @access public
+ */
+ function readToken() {
+ }
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/UnixFileSystem.php b/buildscripts/phing/classes/phing/system/io/UnixFileSystem.php
new file mode 100644
index 00000000..fb4e49b4
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/UnixFileSystem.php
@@ -0,0 +1,266 @@
+<?php
+/*
+ * $Id: UnixFileSystem.php,v 1.10 2005/05/26 13:10:52 mrook Exp $
+ *
+ * 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: 1.10 $
+ * @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 (empty($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");
+ }
+ }
+
+ /* -- 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;
+ }
+
+}
diff --git a/buildscripts/phing/classes/phing/system/io/Win32FileSystem.php b/buildscripts/phing/classes/phing/system/io/Win32FileSystem.php
new file mode 100644
index 00000000..c32c21ff
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/Win32FileSystem.php
@@ -0,0 +1,477 @@
+<?php
+/*
+ * $Id: Win32FileSystem.php,v 1.10 2005/05/26 13:10:52 mrook Exp $
+ *
+ * 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;
+ }
+
+}
+
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/WinNTFileSystem.php b/buildscripts/phing/classes/phing/system/io/WinNTFileSystem.php
new file mode 100644
index 00000000..86f76d80
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/WinNTFileSystem.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * $Id: WinNTFileSystem.php,v 1.3 2003/11/19 05:48:29 hlellelid Exp $
+ *
+ * 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 --*/
+
+
+}
+?>
diff --git a/buildscripts/phing/classes/phing/system/io/Writer.php b/buildscripts/phing/classes/phing/system/io/Writer.php
new file mode 100644
index 00000000..5e1a69b9
--- /dev/null
+++ b/buildscripts/phing/classes/phing/system/io/Writer.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * $Id: Writer.php,v 1.6 2005/05/26 13:10:52 mrook Exp $
+ *
+ * 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 {
+
+ abstract public function write($buf, $off = null, $len = null);
+
+ abstract public function reset();
+
+ abstract public function close();
+
+ abstract public function open();
+
+ public function mark() {}
+
+ public function ready() {}
+
+ public function markSupported() {}
+
+ /**
+ * Returns the filename, url, etc. that is being written to.
+ * @return string
+ */
+ abstract function getResource();
+}
+?>