[ Index ]

PHP Cross Reference of phpBB-3.3.3-deutsch

title

Body

[close]

/vendor/guzzlehttp/psr7/src/ -> CachingStream.php (source)

   1  <?php
   2  
   3  namespace GuzzleHttp\Psr7;
   4  
   5  use Psr\Http\Message\StreamInterface;
   6  
   7  /**
   8   * Stream decorator that can cache previously read bytes from a sequentially
   9   * read stream.
  10   */
  11  class CachingStream implements StreamInterface
  12  {
  13      use StreamDecoratorTrait;
  14  
  15      /** @var StreamInterface Stream being wrapped */
  16      private $remoteStream;
  17  
  18      /** @var int Number of bytes to skip reading due to a write on the buffer */
  19      private $skipReadBytes = 0;
  20  
  21      /**
  22       * We will treat the buffer object as the body of the stream
  23       *
  24       * @param StreamInterface $stream Stream to cache
  25       * @param StreamInterface $target Optionally specify where data is cached
  26       */
  27      public function __construct(
  28          StreamInterface $stream,
  29          StreamInterface $target = null
  30      ) {
  31          $this->remoteStream = $stream;
  32          $this->stream = $target ?: new Stream(fopen('php://temp', 'r+'));
  33      }
  34  
  35      public function getSize()
  36      {
  37          return max($this->stream->getSize(), $this->remoteStream->getSize());
  38      }
  39  
  40      public function rewind()
  41      {
  42          $this->seek(0);
  43      }
  44  
  45      public function seek($offset, $whence = SEEK_SET)
  46      {
  47          if ($whence == SEEK_SET) {
  48              $byte = $offset;
  49          } elseif ($whence == SEEK_CUR) {
  50              $byte = $offset + $this->tell();
  51          } elseif ($whence == SEEK_END) {
  52              $size = $this->remoteStream->getSize();
  53              if ($size === null) {
  54                  $size = $this->cacheEntireStream();
  55              }
  56              $byte = $size + $offset;
  57          } else {
  58              throw new \InvalidArgumentException('Invalid whence');
  59          }
  60  
  61          $diff = $byte - $this->stream->getSize();
  62  
  63          if ($diff > 0) {
  64              // Read the remoteStream until we have read in at least the amount
  65              // of bytes requested, or we reach the end of the file.
  66              while ($diff > 0 && !$this->remoteStream->eof()) {
  67                  $this->read($diff);
  68                  $diff = $byte - $this->stream->getSize();
  69              }
  70          } else {
  71              // We can just do a normal seek since we've already seen this byte.
  72              $this->stream->seek($byte);
  73          }
  74      }
  75  
  76      public function read($length)
  77      {
  78          // Perform a regular read on any previously read data from the buffer
  79          $data = $this->stream->read($length);
  80          $remaining = $length - strlen($data);
  81  
  82          // More data was requested so read from the remote stream
  83          if ($remaining) {
  84              // If data was written to the buffer in a position that would have
  85              // been filled from the remote stream, then we must skip bytes on
  86              // the remote stream to emulate overwriting bytes from that
  87              // position. This mimics the behavior of other PHP stream wrappers.
  88              $remoteData = $this->remoteStream->read(
  89                  $remaining + $this->skipReadBytes
  90              );
  91  
  92              if ($this->skipReadBytes) {
  93                  $len = strlen($remoteData);
  94                  $remoteData = substr($remoteData, $this->skipReadBytes);
  95                  $this->skipReadBytes = max(0, $this->skipReadBytes - $len);
  96              }
  97  
  98              $data .= $remoteData;
  99              $this->stream->write($remoteData);
 100          }
 101  
 102          return $data;
 103      }
 104  
 105      public function write($string)
 106      {
 107          // When appending to the end of the currently read stream, you'll want
 108          // to skip bytes from being read from the remote stream to emulate
 109          // other stream wrappers. Basically replacing bytes of data of a fixed
 110          // length.
 111          $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell();
 112          if ($overflow > 0) {
 113              $this->skipReadBytes += $overflow;
 114          }
 115  
 116          return $this->stream->write($string);
 117      }
 118  
 119      public function eof()
 120      {
 121          return $this->stream->eof() && $this->remoteStream->eof();
 122      }
 123  
 124      /**
 125       * Close both the remote stream and buffer stream
 126       */
 127      public function close()
 128      {
 129          $this->remoteStream->close() && $this->stream->close();
 130      }
 131  
 132      private function cacheEntireStream()
 133      {
 134          $target = new FnStream(['write' => 'strlen']);
 135          Utils::copyToStream($this, $target);
 136  
 137          return $this->tell();
 138      }
 139  }


Generated: Sun Feb 14 20:08:31 2021 Cross-referenced by PHPXref 0.7.1