PluginProbe
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI / 6.0.4
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI v6.0.4
6.0.4 6.0.3 6.0.2 6.0.1 6.0.0 5.8.6 5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 5.7.9.2 5.7.9.1 5.7.8 5.7.9 5.7.6 5.7.7 5.7.5 5.7.4 5.7.3 5.7.2 5.7.1 trunk 5.6.0 All 35 releases
← All changes | integrations/mailchimp/vendor/guzzlehttp/psr7/src/AppendStream.php +248 -0 5.8.2 → 6.0.4 View file →
@@ -1,0 +1,248 @@
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 +}