Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

CachingStream.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 4.35 KiB


001  <?php
002   
003  namespace GuzzleHttp\Psr7;
004   
005  use Psr\Http\Message\StreamInterface;
006   
007  /**
008   * Stream decorator that can cache previously read bytes from a sequentially
009   * read stream.
010   *
011   * @final
012   */
013  class CachingStream implements StreamInterface
014  {
015      use StreamDecoratorTrait;
016   
017      /** @var StreamInterface Stream being wrapped */
018      private $remoteStream;
019   
020      /** @var int Number of bytes to skip reading due to a write on the buffer */
021      private $skipReadBytes = 0;
022   
023      /**
024       * We will treat the buffer object as the body of the stream
025       *
026       * @param StreamInterface $stream Stream to cache. The cursor is assumed to be at the beginning of the stream.
027       * @param StreamInterface $target Optionally specify where data is cached
028       */
029      public function __construct(
030          StreamInterface $stream,
031          StreamInterface $target = null
032      ) {
033          $this->remoteStream = $stream;
034          $this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+'));
035      }
036   
037      public function getSize()
038      {
039          $remoteSize = $this->remoteStream->getSize();
040   
041          if (null === $remoteSize) {
042              return null;
043          }
044   
045          return max($this->stream->getSize(), $remoteSize);
046      }
047   
048      public function rewind()
049      {
050          $this->seek(0);
051      }
052   
053      public function seek($offset, $whence = SEEK_SET)
054      {
055          if ($whence == SEEK_SET) {
056              $byte = $offset;
057          } elseif ($whence == SEEK_CUR) {
058              $byte = $offset + $this->tell();
059          } elseif ($whence == SEEK_END) {
060              $size = $this->remoteStream->getSize();
061              if ($size === null) {
062                  $size = $this->cacheEntireStream();
063              }
064              $byte = $size + $offset;
065          } else {
066              throw new \InvalidArgumentException('Invalid whence');
067          }
068   
069          $diff = $byte - $this->stream->getSize();
070   
071          if ($diff > 0) {
072              // Read the remoteStream until we have read in at least the amount
073              // of bytes requested, or we reach the end of the file.
074              while ($diff > 0 && !$this->remoteStream->eof()) {
075                  $this->read($diff);
076                  $diff = $byte - $this->stream->getSize();
077              }
078          } else {
079              // We can just do a normal seek since we've already seen this byte.
080              $this->stream->seek($byte);
081          }
082      }
083   
084      public function read($length)
085      {
086          // Perform a regular read on any previously read data from the buffer
087          $data = $this->stream->read($length);
088          $remaining = $length - strlen($data);
089   
090          // More data was requested so read from the remote stream
091          if ($remaining) {
092              // If data was written to the buffer in a position that would have
093              // been filled from the remote stream, then we must skip bytes on
094              // the remote stream to emulate overwriting bytes from that
095              // position. This mimics the behavior of other PHP stream wrappers.
096              $remoteData = $this->remoteStream->read(
097                  $remaining + $this->skipReadBytes
098              );
099   
100              if ($this->skipReadBytes) {
101                  $len = strlen($remoteData);
102                  $remoteData = substr($remoteData, $this->skipReadBytes);
103                  $this->skipReadBytes = max(0, $this->skipReadBytes - $len);
104              }
105   
106              $data .= $remoteData;
107              $this->stream->write($remoteData);
108          }
109   
110          return $data;
111      }
112   
113      public function write($string)
114      {
115          // When appending to the end of the currently read stream, you'll want
116          // to skip bytes from being read from the remote stream to emulate
117          // other stream wrappers. Basically replacing bytes of data of a fixed
118          // length.
119          $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell();
120          if ($overflow > 0) {
121              $this->skipReadBytes += $overflow;
122          }
123   
124          return $this->stream->write($string);
125      }
126   
127      public function eof()
128      {
129          return $this->stream->eof() && $this->remoteStream->eof();
130      }
131   
132      /**
133       * Close both the remote stream and buffer stream
134       */
135      public function close()
136      {
137          $this->remoteStream->close() && $this->stream->close();
138      }
139   
140      private function cacheEntireStream()
141      {
142          $target = new FnStream(['write' => 'strlen']);
143          Utils::copyToStream($this, $target);
144   
145          return $this->tell();
146      }
147  }
148