[ Index ]

PHP Cross Reference of phpBB-3.3.2-deutsch

title

Body

[close]

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

   1  <?php
   2  
   3  namespace GuzzleHttp\Psr7;
   4  
   5  use Psr\Http\Message\StreamInterface;
   6  
   7  /**
   8   * Reads from multiple streams, one after the other.
   9   *
  10   * This is a read-only stream decorator.
  11   */
  12  class AppendStream implements StreamInterface
  13  {
  14      /** @var StreamInterface[] Streams being decorated */
  15      private $streams = [];
  16  
  17      private $seekable = true;
  18      private $current = 0;
  19      private $pos = 0;
  20  
  21      /**
  22       * @param StreamInterface[] $streams Streams to decorate. Each stream must
  23       *                                   be readable.
  24       */
  25      public function __construct(array $streams = [])
  26      {
  27          foreach ($streams as $stream) {
  28              $this->addStream($stream);
  29          }
  30      }
  31  
  32      public function __toString()
  33      {
  34          try {
  35              $this->rewind();
  36              return $this->getContents();
  37          } catch (\Exception $e) {
  38              return '';
  39          }
  40      }
  41  
  42      /**
  43       * Add a stream to the AppendStream
  44       *
  45       * @param StreamInterface $stream Stream to append. Must be readable.
  46       *
  47       * @throws \InvalidArgumentException if the stream is not readable
  48       */
  49      public function addStream(StreamInterface $stream)
  50      {
  51          if (!$stream->isReadable()) {
  52              throw new \InvalidArgumentException('Each stream must be readable');
  53          }
  54  
  55          // The stream is only seekable if all streams are seekable
  56          if (!$stream->isSeekable()) {
  57              $this->seekable = false;
  58          }
  59  
  60          $this->streams[] = $stream;
  61      }
  62  
  63      public function getContents()
  64      {
  65          return Utils::copyToString($this);
  66      }
  67  
  68      /**
  69       * Closes each attached stream.
  70       *
  71       * {@inheritdoc}
  72       */
  73      public function close()
  74      {
  75          $this->pos = $this->current = 0;
  76          $this->seekable = true;
  77  
  78          foreach ($this->streams as $stream) {
  79              $stream->close();
  80          }
  81  
  82          $this->streams = [];
  83      }
  84  
  85      /**
  86       * Detaches each attached stream.
  87       *
  88       * Returns null as it's not clear which underlying stream resource to return.
  89       *
  90       * {@inheritdoc}
  91       */
  92      public function detach()
  93      {
  94          $this->pos = $this->current = 0;
  95          $this->seekable = true;
  96  
  97          foreach ($this->streams as $stream) {
  98              $stream->detach();
  99          }
 100  
 101          $this->streams = [];
 102  
 103          return null;
 104      }
 105  
 106      public function tell()
 107      {
 108          return $this->pos;
 109      }
 110  
 111      /**
 112       * Tries to calculate the size by adding the size of each stream.
 113       *
 114       * If any of the streams do not return a valid number, then the size of the
 115       * append stream cannot be determined and null is returned.
 116       *
 117       * {@inheritdoc}
 118       */
 119      public function getSize()
 120      {
 121          $size = 0;
 122  
 123          foreach ($this->streams as $stream) {
 124              $s = $stream->getSize();
 125              if ($s === null) {
 126                  return null;
 127              }
 128              $size += $s;
 129          }
 130  
 131          return $size;
 132      }
 133  
 134      public function eof()
 135      {
 136          return !$this->streams ||
 137              ($this->current >= count($this->streams) - 1 &&
 138               $this->streams[$this->current]->eof());
 139      }
 140  
 141      public function rewind()
 142      {
 143          $this->seek(0);
 144      }
 145  
 146      /**
 147       * Attempts to seek to the given position. Only supports SEEK_SET.
 148       *
 149       * {@inheritdoc}
 150       */
 151      public function seek($offset, $whence = SEEK_SET)
 152      {
 153          if (!$this->seekable) {
 154              throw new \RuntimeException('This AppendStream is not seekable');
 155          } elseif ($whence !== SEEK_SET) {
 156              throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
 157          }
 158  
 159          $this->pos = $this->current = 0;
 160  
 161          // Rewind each stream
 162          foreach ($this->streams as $i => $stream) {
 163              try {
 164                  $stream->rewind();
 165              } catch (\Exception $e) {
 166                  throw new \RuntimeException('Unable to seek stream '
 167                      . $i . ' of the AppendStream', 0, $e);
 168              }
 169          }
 170  
 171          // Seek to the actual position by reading from each stream
 172          while ($this->pos < $offset && !$this->eof()) {
 173              $result = $this->read(min(8096, $offset - $this->pos));
 174              if ($result === '') {
 175                  break;
 176              }
 177          }
 178      }
 179  
 180      /**
 181       * Reads from all of the appended streams until the length is met or EOF.
 182       *
 183       * {@inheritdoc}
 184       */
 185      public function read($length)
 186      {
 187          $buffer = '';
 188          $total = count($this->streams) - 1;
 189          $remaining = $length;
 190          $progressToNext = false;
 191  
 192          while ($remaining > 0) {
 193  
 194              // Progress to the next stream if needed.
 195              if ($progressToNext || $this->streams[$this->current]->eof()) {
 196                  $progressToNext = false;
 197                  if ($this->current === $total) {
 198                      break;
 199                  }
 200                  $this->current++;
 201              }
 202  
 203              $result = $this->streams[$this->current]->read($remaining);
 204  
 205              // Using a loose comparison here to match on '', false, and null
 206              if ($result == null) {
 207                  $progressToNext = true;
 208                  continue;
 209              }
 210  
 211              $buffer .= $result;
 212              $remaining = $length - strlen($buffer);
 213          }
 214  
 215          $this->pos += strlen($buffer);
 216  
 217          return $buffer;
 218      }
 219  
 220      public function isReadable()
 221      {
 222          return true;
 223      }
 224  
 225      public function isWritable()
 226      {
 227          return false;
 228      }
 229  
 230      public function isSeekable()
 231      {
 232          return $this->seekable;
 233      }
 234  
 235      public function write($string)
 236      {
 237          throw new \RuntimeException('Cannot write to an AppendStream');
 238      }
 239  
 240      public function getMetadata($key = null)
 241      {
 242          return $key ? null : [];
 243      }
 244  }


Generated: Wed Nov 11 20:28:18 2020 Cross-referenced by PHPXref 0.7.1