PluginProbe ʕ •ᴥ•ʔ
Check & Log Email – Easy Email Testing & Mail logging / 2.0.15
Check & Log Email – Easy Email Testing & Mail logging v2.0.15
2.0.15 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 2.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.13.1 2.0.13.2 2.0.14 2.0.2 2.0.3 2.0.4 2.0.5 2.0.5.1 2.0.6 2.0.7 2.0.8 2.0.9 trunk 0.5.7 0.6.0 0.6.1 0.6.2 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.12.1 1.0.13 1.0.13.1 1.0.2 1.0.3
check-email / vendor / guzzlehttp / psr7 / src / AppendStream.php
check-email / vendor / guzzlehttp / psr7 / src Last commit date
Exception 1 week ago AppendStream.php 1 week ago BufferStream.php 1 week ago CachingStream.php 1 week ago DroppingStream.php 1 week ago FnStream.php 1 week ago Header.php 1 week ago HttpFactory.php 1 week ago InflateStream.php 1 week ago LazyOpenStream.php 1 week ago LimitStream.php 1 week ago Message.php 1 week ago MessageTrait.php 1 week ago MimeType.php 1 week ago MultipartStream.php 1 week ago NoSeekStream.php 1 week ago PumpStream.php 1 week ago Query.php 1 week ago Request.php 1 week ago Response.php 1 week ago Rfc7230.php 1 week ago ServerRequest.php 1 week ago Stream.php 1 week ago StreamDecoratorTrait.php 1 week ago StreamWrapper.php 1 week ago UploadedFile.php 1 week ago Uri.php 1 week ago UriComparator.php 1 week ago UriNormalizer.php 1 week ago UriResolver.php 1 week ago Utils.php 1 week ago
AppendStream.php
249 lines
1 <?php
2
3 declare(strict_types=1);
4
5 namespace GuzzleHttp\Psr7;
6
7 use Psr\Http\Message\StreamInterface;
8
9 /**
10 * Reads from multiple streams, one after the other.
11 *
12 * This is a read-only stream decorator.
13 */
14 final class AppendStream implements StreamInterface
15 {
16 /** @var StreamInterface[] Streams being decorated */
17 private $streams = [];
18
19 /** @var bool */
20 private $seekable = true;
21
22 /** @var int */
23 private $current = 0;
24
25 /** @var int */
26 private $pos = 0;
27
28 /**
29 * @param StreamInterface[] $streams Streams to decorate. Each stream must
30 * be readable.
31 */
32 public function __construct(array $streams = [])
33 {
34 foreach ($streams as $stream) {
35 $this->addStream($stream);
36 }
37 }
38
39 public function __toString(): string
40 {
41 try {
42 $this->rewind();
43
44 return $this->getContents();
45 } catch (\Throwable $e) {
46 if (\PHP_VERSION_ID >= 70400) {
47 throw $e;
48 }
49 trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
50
51 return '';
52 }
53 }
54
55 /**
56 * Add a stream to the AppendStream
57 *
58 * @param StreamInterface $stream Stream to append. Must be readable.
59 *
60 * @throws \InvalidArgumentException if the stream is not readable
61 */
62 public function addStream(StreamInterface $stream): void
63 {
64 if (!$stream->isReadable()) {
65 throw new \InvalidArgumentException('Each stream must be readable');
66 }
67
68 // The stream is only seekable if all streams are seekable
69 if (!$stream->isSeekable()) {
70 $this->seekable = false;
71 }
72
73 $this->streams[] = $stream;
74 }
75
76 public function getContents(): string
77 {
78 return Utils::copyToString($this);
79 }
80
81 /**
82 * Closes each attached stream.
83 */
84 public function close(): void
85 {
86 $this->pos = $this->current = 0;
87 $this->seekable = true;
88
89 foreach ($this->streams as $stream) {
90 $stream->close();
91 }
92
93 $this->streams = [];
94 }
95
96 /**
97 * Detaches each attached stream.
98 *
99 * Returns null as it's not clear which underlying stream resource to return.
100 */
101 public function detach()
102 {
103 $this->pos = $this->current = 0;
104 $this->seekable = true;
105
106 foreach ($this->streams as $stream) {
107 $stream->detach();
108 }
109
110 $this->streams = [];
111
112 return null;
113 }
114
115 public function tell(): int
116 {
117 return $this->pos;
118 }
119
120 /**
121 * Tries to calculate the size by adding the size of each stream.
122 *
123 * If any of the streams do not return a valid number, then the size of the
124 * append stream cannot be determined and null is returned.
125 */
126 public function getSize(): ?int
127 {
128 $size = 0;
129
130 foreach ($this->streams as $stream) {
131 $s = $stream->getSize();
132 if ($s === null) {
133 return null;
134 }
135 $size += $s;
136 }
137
138 return $size;
139 }
140
141 public function eof(): bool
142 {
143 return !$this->streams
144 || ($this->current >= count($this->streams) - 1
145 && $this->streams[$this->current]->eof());
146 }
147
148 public function rewind(): void
149 {
150 $this->seek(0);
151 }
152
153 /**
154 * Attempts to seek to the given position. Only supports SEEK_SET.
155 */
156 public function seek($offset, $whence = SEEK_SET): void
157 {
158 if (!$this->seekable) {
159 throw new \RuntimeException('This AppendStream is not seekable');
160 } elseif ($whence !== SEEK_SET) {
161 throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
162 }
163
164 $this->pos = $this->current = 0;
165
166 // Rewind each stream
167 foreach ($this->streams as $i => $stream) {
168 try {
169 $stream->rewind();
170 } catch (\Exception $e) {
171 throw new \RuntimeException('Unable to seek stream '
172 .$i.' of the AppendStream', 0, $e);
173 }
174 }
175
176 // Seek to the actual position by reading from each stream
177 while ($this->pos < $offset && !$this->eof()) {
178 $result = $this->read(min(8096, $offset - $this->pos));
179 if ($result === '') {
180 break;
181 }
182 }
183 }
184
185 /**
186 * Reads from all of the appended streams until the length is met or EOF.
187 */
188 public function read($length): string
189 {
190 $buffer = '';
191 $total = count($this->streams) - 1;
192 $remaining = $length;
193 $progressToNext = false;
194
195 while ($remaining > 0) {
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 if ($result === '') {
208 $progressToNext = true;
209 continue;
210 }
211
212 $buffer .= $result;
213 $remaining = $length - strlen($buffer);
214 }
215
216 $this->pos += strlen($buffer);
217
218 return $buffer;
219 }
220
221 public function isReadable(): bool
222 {
223 return true;
224 }
225
226 public function isWritable(): bool
227 {
228 return false;
229 }
230
231 public function isSeekable(): bool
232 {
233 return $this->seekable;
234 }
235
236 public function write($string): int
237 {
238 throw new \RuntimeException('Cannot write to an AppendStream');
239 }
240
241 /**
242 * @return mixed
243 */
244 public function getMetadata($key = null)
245 {
246 return $key ? null : [];
247 }
248 }
249