[ Index ]

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


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1