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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
CachingStream.php
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