PluginProbe ʕ •ᴥ•ʔ
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 25.9
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v25.9
27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 19.1 19.10 19.11 19.12 19.13 19.14 19.2 19.3 19.4 19.5 19.5.1 19.6 19.6.1 19.7 19.7.1 19.7.2 19.8 19.9 20.0 20.1 20.10 20.11 20.12 20.13 20.2 20.2.1 20.3 20.4 20.5 20.6 20.7 20.8 20.9 21.0 21.1 21.2 21.3 21.4 21.5 21.6 21.7 21.8 21.8.1 21.9 21.9.1 22.0 22.1 22.2 22.3 22.4 22.5 22.6 22.7 22.8 22.9 23.0 23.1 23.2 23.3 23.4 23.5 23.6 23.7 23.8 23.9 24.0 24.1 24.2 24.3 24.4 24.5 24.6 24.7 24.8 24.8.1 24.9 25.0 25.1 25.2 25.3 25.3.1 25.4 25.5 25.6 25.7 25.8 25.9 26.0 26.1 26.1.1 26.2 26.3 26.4 26.5 26.6 26.7 26.8 26.9 27.0 27.1 27.1.1 27.2 27.3 27.4
wordpress-seo / vendor_prefixed / guzzlehttp / psr7 / src / AppendStream.php
wordpress-seo / vendor_prefixed / guzzlehttp / psr7 / src Last commit date
Exception 2 years ago AppendStream.php 2 years ago BufferStream.php 2 years ago CachingStream.php 2 years ago DroppingStream.php 2 years ago FnStream.php 2 years ago Header.php 2 years ago HttpFactory.php 2 years ago InflateStream.php 2 years ago LazyOpenStream.php 2 years ago LimitStream.php 2 years ago Message.php 2 years ago MessageTrait.php 2 years ago MimeType.php 2 years ago MultipartStream.php 2 years ago NoSeekStream.php 2 years ago PumpStream.php 2 years ago Query.php 2 years ago Request.php 2 years ago Response.php 2 years ago Rfc7230.php 2 years ago ServerRequest.php 2 years ago Stream.php 2 years ago StreamDecoratorTrait.php 2 years ago StreamWrapper.php 2 years ago UploadedFile.php 2 years ago Uri.php 2 years ago UriComparator.php 2 years ago UriNormalizer.php 2 years ago UriResolver.php 2 years ago Utils.php 2 years ago
AppendStream.php
204 lines
1 <?php
2
3 declare (strict_types=1);
4 namespace YoastSEO_Vendor\GuzzleHttp\Psr7;
5
6 use YoastSEO_Vendor\Psr\Http\Message\StreamInterface;
7 /**
8 * Reads from multiple streams, one after the other.
9 *
10 * This is a read-only stream decorator.
11 */
12 final class AppendStream implements \YoastSEO_Vendor\Psr\Http\Message\StreamInterface
13 {
14 /** @var StreamInterface[] Streams being decorated */
15 private $streams = [];
16 /** @var bool */
17 private $seekable = \true;
18 /** @var int */
19 private $current = 0;
20 /** @var int */
21 private $pos = 0;
22 /**
23 * @param StreamInterface[] $streams Streams to decorate. Each stream must
24 * be readable.
25 */
26 public function __construct(array $streams = [])
27 {
28 foreach ($streams as $stream) {
29 $this->addStream($stream);
30 }
31 }
32 public function __toString() : string
33 {
34 try {
35 $this->rewind();
36 return $this->getContents();
37 } catch (\Throwable $e) {
38 if (\PHP_VERSION_ID >= 70400) {
39 throw $e;
40 }
41 \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
42 return '';
43 }
44 }
45 /**
46 * Add a stream to the AppendStream
47 *
48 * @param StreamInterface $stream Stream to append. Must be readable.
49 *
50 * @throws \InvalidArgumentException if the stream is not readable
51 */
52 public function addStream(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream) : void
53 {
54 if (!$stream->isReadable()) {
55 throw new \InvalidArgumentException('Each stream must be readable');
56 }
57 // The stream is only seekable if all streams are seekable
58 if (!$stream->isSeekable()) {
59 $this->seekable = \false;
60 }
61 $this->streams[] = $stream;
62 }
63 public function getContents() : string
64 {
65 return \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::copyToString($this);
66 }
67 /**
68 * Closes each attached stream.
69 */
70 public function close() : void
71 {
72 $this->pos = $this->current = 0;
73 $this->seekable = \true;
74 foreach ($this->streams as $stream) {
75 $stream->close();
76 }
77 $this->streams = [];
78 }
79 /**
80 * Detaches each attached stream.
81 *
82 * Returns null as it's not clear which underlying stream resource to return.
83 */
84 public function detach()
85 {
86 $this->pos = $this->current = 0;
87 $this->seekable = \true;
88 foreach ($this->streams as $stream) {
89 $stream->detach();
90 }
91 $this->streams = [];
92 return null;
93 }
94 public function tell() : int
95 {
96 return $this->pos;
97 }
98 /**
99 * Tries to calculate the size by adding the size of each stream.
100 *
101 * If any of the streams do not return a valid number, then the size of the
102 * append stream cannot be determined and null is returned.
103 */
104 public function getSize() : ?int
105 {
106 $size = 0;
107 foreach ($this->streams as $stream) {
108 $s = $stream->getSize();
109 if ($s === null) {
110 return null;
111 }
112 $size += $s;
113 }
114 return $size;
115 }
116 public function eof() : bool
117 {
118 return !$this->streams || $this->current >= \count($this->streams) - 1 && $this->streams[$this->current]->eof();
119 }
120 public function rewind() : void
121 {
122 $this->seek(0);
123 }
124 /**
125 * Attempts to seek to the given position. Only supports SEEK_SET.
126 */
127 public function seek($offset, $whence = \SEEK_SET) : void
128 {
129 if (!$this->seekable) {
130 throw new \RuntimeException('This AppendStream is not seekable');
131 } elseif ($whence !== \SEEK_SET) {
132 throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
133 }
134 $this->pos = $this->current = 0;
135 // Rewind each stream
136 foreach ($this->streams as $i => $stream) {
137 try {
138 $stream->rewind();
139 } catch (\Exception $e) {
140 throw new \RuntimeException('Unable to seek stream ' . $i . ' of the AppendStream', 0, $e);
141 }
142 }
143 // Seek to the actual position by reading from each stream
144 while ($this->pos < $offset && !$this->eof()) {
145 $result = $this->read(\min(8096, $offset - $this->pos));
146 if ($result === '') {
147 break;
148 }
149 }
150 }
151 /**
152 * Reads from all of the appended streams until the length is met or EOF.
153 */
154 public function read($length) : string
155 {
156 $buffer = '';
157 $total = \count($this->streams) - 1;
158 $remaining = $length;
159 $progressToNext = \false;
160 while ($remaining > 0) {
161 // Progress to the next stream if needed.
162 if ($progressToNext || $this->streams[$this->current]->eof()) {
163 $progressToNext = \false;
164 if ($this->current === $total) {
165 break;
166 }
167 ++$this->current;
168 }
169 $result = $this->streams[$this->current]->read($remaining);
170 if ($result === '') {
171 $progressToNext = \true;
172 continue;
173 }
174 $buffer .= $result;
175 $remaining = $length - \strlen($buffer);
176 }
177 $this->pos += \strlen($buffer);
178 return $buffer;
179 }
180 public function isReadable() : bool
181 {
182 return \true;
183 }
184 public function isWritable() : bool
185 {
186 return \false;
187 }
188 public function isSeekable() : bool
189 {
190 return $this->seekable;
191 }
192 public function write($string) : int
193 {
194 throw new \RuntimeException('Cannot write to an AppendStream');
195 }
196 /**
197 * @return mixed
198 */
199 public function getMetadata($key = null)
200 {
201 return $key ? null : [];
202 }
203 }
204