[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/vendor/phing/system/io/ -> Win32FileSystem.php (source)

   1  <?php
   2  /*
   3   *  $Id: Win32FileSystem.php 3076 2006-12-18 08:52:12Z fabien $
   4   *
   5   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   6   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   7   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   8   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   9   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16   *
  17   * This software consists of voluntary contributions made by many individuals
  18   * and is licensed under the LGPL. For more information please see
  19   * <http://phing.info>. 
  20   */
  21  
  22  include_once 'phing/system/io/FileSystem.php';
  23  
  24  /**
  25   *  @package   phing.system.io
  26   */
  27  class Win32FileSystem extends FileSystem {
  28  
  29      protected $slash;
  30      protected $altSlash;
  31      protected $semicolon;
  32  
  33      private static $driveDirCache = array();
  34  
  35      function __construct() {
  36          $this->slash = self::getSeparator();
  37          $this->semicolon = self::getPathSeparator();
  38          $this->altSlash = ($this->slash === '\\') ? '/' : '\\';
  39      }
  40  
  41      function isSlash($c) {
  42          return ($c == '\\') || ($c == '/');
  43      }
  44  
  45      function isLetter($c) {
  46          return ((ord($c) >= ord('a')) && (ord($c) <= ord('z')))
  47                 || ((ord($c) >= ord('A')) && (ord($c) <= ord('Z')));
  48      }
  49  
  50      function slashify($p) {
  51          if ((strlen($p) > 0) && ($p{0} != $this->slash)) {
  52              return $this->slash.$p;
  53          }
  54          else {
  55              return $p;
  56          }
  57      }
  58  
  59      /* -- Normalization and construction -- */
  60  
  61      function getSeparator() {
  62          // the ascii value of is the \
  63          return chr(92);
  64      }
  65  
  66      function getPathSeparator() {
  67          return ';';
  68      }
  69  
  70      /**
  71       * A normal Win32 pathname contains no duplicate slashes, except possibly
  72       * for a UNC prefix, and does not end with a slash.  It may be the empty
  73       * string.  Normalized Win32 pathnames have the convenient property that
  74       * the length of the prefix almost uniquely identifies the type of the path
  75       * and whether it is absolute or relative:
  76       *
  77       *    0  relative to both drive and directory
  78       *    1  drive-relative (begins with '\\')
  79       *    2  absolute UNC (if first char is '\\'), else directory-relative (has form "z:foo")
  80       *    3  absolute local pathname (begins with "z:\\")
  81       */
  82      function normalizePrefix($strPath, $len, $sb) {
  83          $src = 0;
  84          while (($src < $len) && $this->isSlash($strPath{$src})) {
  85              $src++;
  86          }
  87          $c = "";
  88          if (($len - $src >= 2)
  89                  && $this->isLetter($c = $strPath{$src})
  90                  && $strPath{$src + 1} === ':') {
  91              /* Remove leading slashes if followed by drive specifier.
  92               * This hack is necessary to support file URLs containing drive
  93               * specifiers (e.g., "file://c:/path").  As a side effect,
  94               * "/c:/path" can be used as an alternative to "c:/path". */
  95              $sb .= $c;
  96              $sb .= ':';
  97              $src += 2;
  98          }
  99          else {
 100              $src = 0;
 101              if (($len >= 2)
 102                      && $this->isSlash($strPath{0})
 103                      && $this->isSlash($strPath{1})) {
 104                  /* UNC pathname: Retain first slash; leave src pointed at
 105                   * second slash so that further slashes will be collapsed
 106                   * into the second slash.  The result will be a pathname
 107                   * beginning with "\\\\" followed (most likely) by a host
 108                   * name. */
 109                  $src = 1;
 110                  $sb.=$this->slash;
 111              }
 112          }
 113          return $src;
 114      }
 115  
 116      /** Normalize the given pathname, whose length is len, starting at the given
 117         offset; everything before this offset is already normal. */
 118      protected function normalizer($strPath, $len, $offset) {
 119          if ($len == 0) {
 120              return $strPath;
 121          }
 122          if ($offset < 3) {
 123              $offset = 0;    //Avoid fencepost cases with UNC pathnames
 124          }
 125          $src = 0;
 126          $slash = $this->slash;
 127          $sb = "";
 128  
 129          if ($offset == 0) {
 130              // Complete normalization, including prefix
 131              $src = $this->normalizePrefix($strPath, $len, $sb);
 132          } else {
 133              // Partial normalization
 134              $src = $offset;
 135              $sb .= substr($strPath, 0, $offset);
 136          }
 137  
 138          // Remove redundant slashes from the remainder of the path, forcing all
 139          // slashes into the preferred slash
 140          while ($src < $len) {
 141              $c = $strPath{$src++};
 142              if ($this->isSlash($c)) {
 143                  while (($src < $len) && $this->isSlash($strPath{$src})) {
 144                      $src++;
 145                  }
 146                  if ($src === $len) {
 147                      /* Check for trailing separator */
 148                      $sn = (int) strlen($sb);
 149                      if (($sn == 2) && ($sb{1} === ':')) {
 150                          // "z:\\"
 151                          $sb .= $slash;
 152                          break;
 153                      }
 154                      if ($sn === 0) {
 155                          // "\\"
 156                          $sb .= $slash;
 157                          break;
 158                      }
 159                      if (($sn === 1) && ($this->isSlash($sb{0}))) {
 160                          /* "\\\\" is not collapsed to "\\" because "\\\\" marks
 161                          the beginning of a UNC pathname.  Even though it is
 162                          not, by itself, a valid UNC pathname, we leave it as
 163                          is in order to be consistent with the win32 APIs,
 164                          which treat this case as an invalid UNC pathname
 165                          rather than as an alias for the root directory of
 166                          the current drive. */
 167                          $sb .= $slash;
 168                          break;
 169                      }
 170                      // Path does not denote a root directory, so do not append
 171                      // trailing slash
 172                      break;
 173                  } else {
 174                      $sb .= $slash;
 175                  }
 176              } else {
 177                  $sb.=$c;
 178              }
 179          }
 180          $rv = (string) $sb;
 181          return $rv;
 182      }
 183  
 184      /**
 185       * Check that the given pathname is normal.  If not, invoke the real
 186       * normalizer on the part of the pathname that requires normalization.
 187       * This way we iterate through the whole pathname string only once.
 188       * @param string $strPath
 189       * @return string
 190       */
 191      function normalize($strPath) {
 192          $n = strlen($strPath);
 193          $slash    = $this->slash;
 194          $altSlash = $this->altSlash;
 195          $prev = 0;
 196          for ($i = 0; $i < $n; $i++) {
 197              $c = $strPath{$i};
 198              if ($c === $altSlash) {
 199                  return $this->normalizer($strPath, $n, ($prev === $slash) ? $i - 1 : $i);
 200              }
 201              if (($c === $slash) && ($prev === $slash) && ($i > 1)) {
 202                  return $this->normalizer($strPath, $n, $i - 1);
 203              }
 204              if (($c === ':') && ($i > 1)) {
 205                  return $this->normalizer($strPath, $n, 0);
 206              }
 207              $prev = $c;
 208          }
 209          if ($prev === $slash) {
 210              return $this->normalizer($strPath, $n, $n - 1);
 211          }
 212          return $strPath;
 213      }
 214  
 215      function prefixLength($strPath) {
 216          $path  = (string) $strPath;
 217          $slash = (string) $this->slash;
 218          $n = (int) strlen($path);
 219          if ($n === 0) {
 220              return 0;
 221          }
 222          $c0 = $path{0};
 223          $c1 = ($n > 1) ? $path{1} :
 224                0;
 225          if ($c0 === $slash) {
 226              if ($c1 === $slash) {
 227                  return 2;            // absolute UNC pathname "\\\\foo"
 228              }
 229              return 1;                // drive-relative "\\foo"
 230          }
 231  
 232          if ($this->isLetter($c0) && ($c1 === ':')) {
 233              if (($n > 2) && ($path{2}) === $slash) {
 234                  return 3;            // Absolute local pathname "z:\\foo" */
 235              }
 236              return 2;                // Directory-relative "z:foo"
 237          }
 238          return 0;                    // Completely relative
 239      }
 240  
 241      function resolve($parent, $child) {
 242          $parent = (string) $parent;
 243          $child  = (string) $child;
 244          $slash  = (string) $this->slash;
 245  
 246          $pn = (int) strlen($parent);
 247          if ($pn === 0) {
 248              return $child;
 249          }
 250          $cn = (int) strlen($child);
 251          if ($cn === 0) {
 252              return $parent;
 253          }
 254  
 255          $c = $child;
 256          if (($cn > 1) && ($c{0} === $slash)) {
 257              if ($c{1} === $slash) {
 258                  // drop prefix when child is a UNC pathname
 259                  $c = substr($c, 2);
 260              }
 261              else {
 262                  //Drop prefix when child is drive-relative */
 263                  $c = substr($c, 1);
 264              }
 265          }
 266  
 267          $p = $parent;
 268          if ($p{$pn - 1} === $slash) {
 269              $p = substr($p, 0, $pn - 1);
 270          }
 271          return $p.$this->slashify($c);
 272      }
 273  
 274      function getDefaultParent() {
 275          return (string) ("".$this->slash);
 276      }
 277  
 278      function fromURIPath($strPath) {
 279          $p = (string) $strPath;
 280          if ((strlen($p) > 2) && ($p{2} === ':')) {
 281  
 282              // "/c:/foo" --> "c:/foo"
 283              $p = substr($p,1);
 284  
 285              // "c:/foo/" --> "c:/foo", but "c:/" --> "c:/"
 286              if ((strlen($p) > 3) && StringHelper::endsWith('/', $p)) {
 287                  $p = substr($p, 0, strlen($p) - 1);
 288              }
 289          } elseif ((strlen($p) > 1) && StringHelper::endsWith('/', $p)) {
 290              // "/foo/" --> "/foo"
 291              $p = substr($p, 0, strlen($p) - 1);
 292          }
 293          return (string) $p;
 294      }
 295  
 296  
 297      /* -- Path operations -- */
 298  
 299      function isAbsolute(PhingFile $f) {
 300          $pl = (int) $f->getPrefixLength();
 301          $p  = (string) $f->getPath();
 302          return ((($pl === 2) && ($p{0} === $this->slash)) || ($pl === 3) || ($pl === 1 && $p{0} === $this->slash));
 303      }
 304  
 305      /** private */
 306      function _driveIndex($d) {
 307          $d = (string) $d{0};
 308          if ((ord($d) >= ord('a')) && (ord($d) <= ord('z'))) {
 309              return ord($d) - ord('a');
 310          }
 311          if ((ord($d) >= ord('A')) && (ord($d) <= ord('Z'))) {
 312              return ord($d) - ord('A');
 313          }
 314          return -1;
 315      }
 316  
 317      /** private */
 318      function _getDriveDirectory($drive) {
 319          $drive = (string) $drive{0};
 320          $i = (int) $this->_driveIndex($drive);
 321          if ($i < 0) {
 322              return null;
 323          }
 324  
 325          $s = (isset(self::$driveDirCache[$i]) ? self::$driveDirCache[$i] : null);
 326  
 327          if ($s !== null) {
 328              return $s;
 329          }
 330  
 331          $s = $this->_getDriveDirectory($i + 1);
 332          self::$driveDirCache[$i] = $s;
 333          return $s;
 334      }
 335  
 336      function _getUserPath() {
 337          //For both compatibility and security, we must look this up every time
 338          return (string) $this->normalize(Phing::getProperty("user.dir"));
 339      }
 340  
 341      function _getDrive($path) {
 342          $path = (string) $path;
 343          $pl   = $this->prefixLength($path);
 344          return ($pl === 3) ? substr($path, 0, 2) : null;
 345      }
 346  
 347      function resolveFile(PhingFile $f) {
 348          $path = $f->getPath();
 349          $pl   = (int) $f->getPrefixLength();
 350  
 351          if (($pl === 2) && ($path{0} === $this->slash)) {
 352              return path;            // UNC
 353          }
 354  
 355          if ($pl === 3) {
 356              return $path;            // Absolute local
 357          }
 358  
 359          if ($pl === 0) {
 360              return (string) ($this->_getUserPath().$this->slashify($path)); //Completely relative
 361          }
 362  
 363          if ($pl === 1) {            // Drive-relative
 364              $up = (string) $this->_getUserPath();
 365              $ud = (string) $this->_getDrive($up);
 366              if ($ud !== null) {
 367                  return (string) $ud.$path;
 368              }
 369              return (string) $up.$path;            //User dir is a UNC path
 370          }
 371  
 372          if ($pl === 2) {                // Directory-relative
 373              $up = (string) $this->_getUserPath();
 374              $ud = (string) $this->_getDrive($up);
 375              if (($ud !== null) && StringHelper::startsWith($ud, $path)) {
 376                  return (string) ($up . $this->slashify(substr($path,2)));
 377              }
 378              $drive = (string) $path{0};
 379              $dir   = (string) $this->_getDriveDirectory($drive);
 380  
 381              $np = (string) "";
 382              if ($dir !== null) {
 383                  /* When resolving a directory-relative path that refers to a
 384                  drive other than the current drive, insist that the caller
 385                  have read permission on the result */
 386                  $p = (string) $drive . (':'.$dir.$this->slashify(substr($path,2)));
 387  
 388                  if (!$this->checkAccess($p, false)) {
 389                      // FIXME
 390                      // throw security error
 391                      die("Can't resolve path $p");
 392                  }
 393                  return $p;
 394              }
 395              return (string) $drive.':'.$this->slashify(substr($path,2)); //fake it
 396          }
 397          
 398          throw new Exception("Unresolvable path: " . $path);
 399      }
 400  
 401      /* -- most of the following is mapped to the functions mapped th php natives in FileSystem */
 402  
 403      /* -- Attribute accessors -- */
 404  
 405      function setReadOnly($f) {
 406          // dunno how to do this on win
 407          throw new Exception("WIN32FileSystem doesn't support read-only yet.");
 408      }
 409  
 410      /* -- Filesystem interface -- */
 411  
 412      protected function _access($path) {
 413          if (!$this->checkAccess($path, false)) {
 414              throw new Exception("Can't resolve path $p");
 415          }
 416          return true;
 417      }
 418  
 419      function _nativeListRoots() {
 420          // FIXME
 421      }
 422  
 423      function listRoots() {
 424          $ds = _nativeListRoots();
 425          $n = 0;
 426          for ($i = 0; $i < 26; $i++) {
 427              if ((($ds >> $i) & 1) !== 0) {
 428                  if (!$this->access((string)( chr(ord('A') + $i) . ':' . $this->slash))) {
 429                      $ds &= ~(1 << $i);
 430                  } else {
 431                      $n++;
 432                  }
 433              }
 434          }
 435          $fs = array();
 436          $j = (int) 0;
 437          $slash = (string) $this->slash;
 438          for ($i = 0; $i < 26; $i++) {
 439              if ((($ds >> $i) & 1) !== 0) {
 440                  $fs[$j++] = new PhingFile(chr(ord('A') + $i) . ':' . $this->slash);
 441              }
 442          }
 443          return $fs;
 444      }
 445  
 446      /* -- Basic infrastructure -- */
 447  
 448      /** compares file paths lexicographically */
 449      function compare(PhingFile $f1, PhingFile $f2) {
 450          $f1Path = $f1->getPath();
 451          $f2Path = $f2->getPath();
 452          return (boolean) strcasecmp((string) $f1Path, (string) $f2Path);        
 453      }
 454  
 455  
 456      /**
 457       * returns the contents of a directory in an array
 458       */
 459      function lister($f) {
 460          $dir = @opendir($f->getAbsolutePath());
 461          if (!$dir) {
 462              throw new Exception("Can't open directory " . $f->__toString());
 463          }
 464          $vv = array();
 465          while (($file = @readdir($dir)) !== false) {
 466              if ($file == "." || $file == "..") {
 467                  continue;
 468              }
 469              $vv[] = (string) $file;
 470          }
 471          @closedir($dir);
 472          return $vv;
 473      }
 474  
 475  }
 476  
 477  ?>


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7