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 |
AppendStream.php
001 <?php
002
003 namespace GuzzleHttp\Psr7;
004
005 use Psr\Http\Message\StreamInterface;
006
007 /**
008 * Reads from multiple streams, one after the other.
009 *
010 * This is a read-only stream decorator.
011 *
012 * @final
013 */
014 class AppendStream implements StreamInterface
015 {
016 /** @var StreamInterface[] Streams being decorated */
017 private $streams = [];
018
019 private $seekable = true;
020 private $current = 0;
021 private $pos = 0;
022
023 /**
024 * @param StreamInterface[] $streams Streams to decorate. Each stream must
025 * be readable.
026 */
027 public function __construct(array $streams = [])
028 {
029 foreach ($streams as $stream) {
030 $this->addStream($stream);
031 }
032 }
033
034 public function __toString()
035 {
036 try {
037 $this->rewind();
038 return $this->getContents();
039 } catch (\Exception $e) {
040 return '';
041 }
042 }
043
044 /**
045 * Add a stream to the AppendStream
046 *
047 * @param StreamInterface $stream Stream to append. Must be readable.
048 *
049 * @throws \InvalidArgumentException if the stream is not readable
050 */
051 public function addStream(StreamInterface $stream)
052 {
053 if (!$stream->isReadable()) {
054 throw new \InvalidArgumentException('Each stream must be readable');
055 }
056
057 // The stream is only seekable if all streams are seekable
058 if (!$stream->isSeekable()) {
059 $this->seekable = false;
060 }
061
062 $this->streams[] = $stream;
063 }
064
065 public function getContents()
066 {
067 return Utils::copyToString($this);
068 }
069
070 /**
071 * Closes each attached stream.
072 *
073 * {@inheritdoc}
074 */
075 public function close()
076 {
077 $this->pos = $this->current = 0;
078 $this->seekable = true;
079
080 foreach ($this->streams as $stream) {
081 $stream->close();
082 }
083
084 $this->streams = [];
085 }
086
087 /**
088 * Detaches each attached stream.
089 *
090 * Returns null as it's not clear which underlying stream resource to return.
091 *
092 * {@inheritdoc}
093 */
094 public function detach()
095 {
096 $this->pos = $this->current = 0;
097 $this->seekable = true;
098
099 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 }
247