[ Index ]

MailPress 7.2

[ Index ]     [ Classes ]     [ Functions ]     [ Variables ]     [ Constants ]     [ Statistics ]    

title

Body

[close]

/mp-includes/composer/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/ -> FileByteStream.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of SwiftMailer.
   5   * (c) 2004-2009 Chris Corbyn
   6   *
   7   * For the full copyright and license information, please view the LICENSE
   8   * file that was distributed with this source code.
   9   */
  10  
  11  /**
  12   * Allows reading and writing of bytes to and from a file.
  13   *
  14   * @author     Chris Corbyn
  15   */
  16  class Swift_ByteStream_FileByteStream extends Swift_ByteStream_AbstractFilterableInputStream implements Swift_FileStream
  17  {
  18      /** The internal pointer offset */
  19      private $offset = 0;
  20  
  21      /** The path to the file */
  22      private $path;
  23  
  24      /** The mode this file is opened in for writing */
  25      private $mode;
  26  
  27      /** A lazy-loaded resource handle for reading the file */
  28      private $reader;
  29  
  30      /** A lazy-loaded resource handle for writing the file */
  31      private $writer;
  32  
  33      /** If stream is seekable true/false, or null if not known */
  34      private $seekable = null;
  35  
  36      /**
  37       * Create a new FileByteStream for $path.
  38       *
  39       * @param string $path
  40       * @param bool   $writable if true
  41       */
  42      public function __construct($path, $writable = false)
  43      {
  44          if (empty($path)) {
  45              throw new Swift_IoException('The path cannot be empty');
  46          }
  47          $this->path = $path;
  48          $this->mode = $writable ? 'w+b' : 'rb';
  49      }
  50  
  51      /**
  52       * Get the complete path to the file.
  53       *
  54       * @return string
  55       */
  56      public function getPath()
  57      {
  58          return $this->path;
  59      }
  60  
  61      /**
  62       * Reads $length bytes from the stream into a string and moves the pointer
  63       * through the stream by $length.
  64       *
  65       * If less bytes exist than are requested the
  66       * remaining bytes are given instead. If no bytes are remaining at all, boolean
  67       * false is returned.
  68       *
  69       * @param int $length
  70       *
  71       * @return string|bool
  72       *
  73       * @throws Swift_IoException
  74       */
  75      public function read($length)
  76      {
  77          $fp = $this->getReadHandle();
  78          if (!feof($fp)) {
  79              $bytes = fread($fp, $length);
  80              $this->offset = ftell($fp);
  81  
  82              // If we read one byte after reaching the end of the file
  83              // feof() will return false and an empty string is returned
  84              if ('' === $bytes && feof($fp)) {
  85                  $this->resetReadHandle();
  86  
  87                  return false;
  88              }
  89  
  90              return $bytes;
  91          }
  92  
  93          $this->resetReadHandle();
  94  
  95          return false;
  96      }
  97  
  98      /**
  99       * Move the internal read pointer to $byteOffset in the stream.
 100       *
 101       * @param int $byteOffset
 102       *
 103       * @return bool
 104       */
 105      public function setReadPointer($byteOffset)
 106      {
 107          if (isset($this->reader)) {
 108              $this->seekReadStreamToPosition($byteOffset);
 109          }
 110          $this->offset = $byteOffset;
 111      }
 112  
 113      /** Just write the bytes to the file */
 114      protected function doCommit($bytes)
 115      {
 116          fwrite($this->getWriteHandle(), $bytes);
 117          $this->resetReadHandle();
 118      }
 119  
 120      /** Not used */
 121      protected function flush()
 122      {
 123      }
 124  
 125      /** Get the resource for reading */
 126      private function getReadHandle()
 127      {
 128          if (!isset($this->reader)) {
 129              $pointer = @fopen($this->path, 'rb');
 130              if (!$pointer) {
 131                  throw new Swift_IoException('Unable to open file for reading ['.$this->path.']');
 132              }
 133              $this->reader = $pointer;
 134              if (0 != $this->offset) {
 135                  $this->getReadStreamSeekableStatus();
 136                  $this->seekReadStreamToPosition($this->offset);
 137              }
 138          }
 139  
 140          return $this->reader;
 141      }
 142  
 143      /** Get the resource for writing */
 144      private function getWriteHandle()
 145      {
 146          if (!isset($this->writer)) {
 147              if (!$this->writer = fopen($this->path, $this->mode)) {
 148                  throw new Swift_IoException('Unable to open file for writing ['.$this->path.']');
 149              }
 150          }
 151  
 152          return $this->writer;
 153      }
 154  
 155      /** Force a reload of the resource for reading */
 156      private function resetReadHandle()
 157      {
 158          if (isset($this->reader)) {
 159              fclose($this->reader);
 160              $this->reader = null;
 161          }
 162      }
 163  
 164      /** Check if ReadOnly Stream is seekable */
 165      private function getReadStreamSeekableStatus()
 166      {
 167          $metas = stream_get_meta_data($this->reader);
 168          $this->seekable = $metas['seekable'];
 169      }
 170  
 171      /** Streams in a readOnly stream ensuring copy if needed */
 172      private function seekReadStreamToPosition($offset)
 173      {
 174          if (null === $this->seekable) {
 175              $this->getReadStreamSeekableStatus();
 176          }
 177          if (false === $this->seekable) {
 178              $currentPos = ftell($this->reader);
 179              if ($currentPos < $offset) {
 180                  $toDiscard = $offset - $currentPos;
 181                  fread($this->reader, $toDiscard);
 182  
 183                  return;
 184              }
 185              $this->copyReadStream();
 186          }
 187          fseek($this->reader, $offset, SEEK_SET);
 188      }
 189  
 190      /** Copy a readOnly Stream to ensure seekability */
 191      private function copyReadStream()
 192      {
 193          if ($tmpFile = fopen('php://temp/maxmemory:4096', 'w+b')) {
 194              /* We have opened a php:// Stream Should work without problem */
 195          } elseif (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()) && ($tmpFile = tmpfile())) {
 196              /* We have opened a tmpfile */
 197          } else {
 198              throw new Swift_IoException('Unable to copy the file to make it seekable, sys_temp_dir is not writable, php://memory not available');
 199          }
 200          $currentPos = ftell($this->reader);
 201          fclose($this->reader);
 202          $source = fopen($this->path, 'rb');
 203          if (!$source) {
 204              throw new Swift_IoException('Unable to open file for copying ['.$this->path.']');
 205          }
 206          fseek($tmpFile, 0, SEEK_SET);
 207          while (!feof($source)) {
 208              fwrite($tmpFile, fread($source, 4096));
 209          }
 210          fseek($tmpFile, $currentPos, SEEK_SET);
 211          fclose($source);
 212          $this->reader = $tmpFile;
 213      }
 214  }


Generated: Tue May 19 15:55:14 2020 Cross-referenced by PHPXref 0.7.1