PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.4
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.4
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 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 All 129 releases
wordpress-seo / vendor_prefixed / guzzlehttp / psr7 / src / AppendStream.php

AppendStream.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 18.4, at vendor_prefixed/guzzlehttp/psr7/src/AppendStream.php

206 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace YoastSEO_Vendor\GuzzleHttp\Psr7;
4
5 use YoastSEO_Vendor\Psr\Http\Message\StreamInterface;
6 /**
7 * Reads from multiple streams, one after the other.
8 *
9 * This is a read-only stream decorator.
10 *
11 * @final
12 */
13 class AppendStream implements \YoastSEO_Vendor\Psr\Http\Message\StreamInterface
14 {
15 /** @var StreamInterface[] Streams being decorated */
16 private $streams = [];
17 private $seekable = \true;
18 private $current = 0;
19 private $pos = 0;
20 /**
21 * @param StreamInterface[] $streams Streams to decorate. Each stream must
22 * be readable.
23 */
24 public function __construct(array $streams = [])
25 {
26 foreach ($streams as $stream) {
27 $this->addStream($stream);
28 }
29 }
30 public function __toString()
31 {
32 try {
33 $this->rewind();
34 return $this->getContents();
35 } catch (\Exception $e) {
36 return '';
37 }
38 }
39 /**
40 * Add a stream to the AppendStream
41 *
42 * @param StreamInterface $stream Stream to append. Must be readable.
43 *
44 * @throws \InvalidArgumentException if the stream is not readable
45 */
46 public function addStream(\YoastSEO_Vendor\Psr\Http\Message\StreamInterface $stream)
47 {
48 if (!$stream->isReadable()) {
49 throw new \InvalidArgumentException('Each stream must be readable');
50 }
51 // The stream is only seekable if all streams are seekable
52 if (!$stream->isSeekable()) {
53 $this->seekable = \false;
54 }
55 $this->streams[] = $stream;
56 }
57 public function getContents()
58 {
59 return \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::copyToString($this);
60 }
61 /**
62 * Closes each attached stream.
63 *
64 * {@inheritdoc}
65 */
66 public function close()
67 {
68 $this->pos = $this->current = 0;
69 $this->seekable = \true;
70 foreach ($this->streams as $stream) {
71 $stream->close();
72 }
73 $this->streams = [];
74 }
75 /**
76 * Detaches each attached stream.
77 *
78 * Returns null as it's not clear which underlying stream resource to return.
79 *
80 * {@inheritdoc}
81 */
82 public function detach()
83 {
84 $this->pos = $this->current = 0;
85 $this->seekable = \true;
86 foreach ($this->streams as $stream) {
87 $stream->detach();
88 }
89 $this->streams = [];
90 return null;
91 }
92 public function tell()
93 {
94 return $this->pos;
95 }
96 /**
97 * Tries to calculate the size by adding the size of each stream.
98 *
99 * If any of the streams do not return a valid number, then the size of the
100 * append stream cannot be determined and null is returned.
101 *
102 * {@inheritdoc}
103 */
104 public function getSize()
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()
117 {
118 return !$this->streams || $this->current >= \count($this->streams) - 1 && $this->streams[$this->current]->eof();
119 }
120 public function rewind()
121 {
122 $this->seek(0);
123 }
124 /**
125 * Attempts to seek to the given position. Only supports SEEK_SET.
126 *
127 * {@inheritdoc}
128 */
129 public function seek($offset, $whence = \SEEK_SET)
130 {
131 if (!$this->seekable) {
132 throw new \RuntimeException('This AppendStream is not seekable');
133 } elseif ($whence !== \SEEK_SET) {
134 throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
135 }
136 $this->pos = $this->current = 0;
137 // Rewind each stream
138 foreach ($this->streams as $i => $stream) {
139 try {
140 $stream->rewind();
141 } catch (\Exception $e) {
142 throw new \RuntimeException('Unable to seek stream ' . $i . ' of the AppendStream', 0, $e);
143 }
144 }
145 // Seek to the actual position by reading from each stream
146 while ($this->pos < $offset && !$this->eof()) {
147 $result = $this->read(\min(8096, $offset - $this->pos));
148 if ($result === '') {
149 break;
150 }
151 }
152 }
153 /**
154 * Reads from all of the appended streams until the length is met or EOF.
155 *
156 * {@inheritdoc}
157 */
158 public function read($length)
159 {
160 $buffer = '';
161 $total = \count($this->streams) - 1;
162 $remaining = $length;
163 $progressToNext = \false;
164 while ($remaining > 0) {
165 // Progress to the next stream if needed.
166 if ($progressToNext || $this->streams[$this->current]->eof()) {
167 $progressToNext = \false;
168 if ($this->current === $total) {
169 break;
170 }
171 $this->current++;
172 }
173 $result = $this->streams[$this->current]->read($remaining);
174 // Using a loose comparison here to match on '', false, and null
175 if ($result == null) {
176 $progressToNext = \true;
177 continue;
178 }
179 $buffer .= $result;
180 $remaining = $length - \strlen($buffer);
181 }
182 $this->pos += \strlen($buffer);
183 return $buffer;
184 }
185 public function isReadable()
186 {
187 return \true;
188 }
189 public function isWritable()
190 {
191 return \false;
192 }
193 public function isSeekable()
194 {
195 return $this->seekable;
196 }
197 public function write($string)
198 {
199 throw new \RuntimeException('Cannot write to an AppendStream');
200 }
201 public function getMetadata($key = null)
202 {
203 return $key ? null : [];
204 }
205 }
206