[ Index ]

PHP Cross Reference of phpBB-3.3.0-deutsch

title

Body

[close]

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

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


Generated: Tue Apr 7 19:44:41 2020 Cross-referenced by PHPXref 0.7.1