PluginProbe ʕ •ᴥ•ʔ
ShareThis Dashboard for Google Analytics / 3.3.0
ShareThis Dashboard for Google Analytics v3.3.0
3.3.2 trunk 1.0.7 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2.5 2.3.5 2.3.6 2.3.7 2.3.8 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.0.0 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.3.0 3.3.1
googleanalytics / lib / analytics-admin / vendor / guzzlehttp / psr7 / src / AppendStream.php
googleanalytics / lib / analytics-admin / vendor / guzzlehttp / psr7 / src Last commit date
Exception 3 years ago AppendStream.php 3 years ago BufferStream.php 3 years ago CachingStream.php 3 years ago DroppingStream.php 3 years ago FnStream.php 3 years ago Header.php 3 years ago HttpFactory.php 3 years ago InflateStream.php 3 years ago LazyOpenStream.php 3 years ago LimitStream.php 3 years ago Message.php 3 years ago MessageTrait.php 3 years ago MimeType.php 3 years ago MultipartStream.php 3 years ago NoSeekStream.php 3 years ago PumpStream.php 3 years ago Query.php 3 years ago Request.php 3 years ago Response.php 3 years ago Rfc7230.php 3 years ago ServerRequest.php 3 years ago Stream.php 3 years ago StreamDecoratorTrait.php 3 years ago StreamWrapper.php 3 years ago UploadedFile.php 3 years ago Uri.php 3 years ago UriComparator.php 3 years ago UriNormalizer.php 3 years ago UriResolver.php 3 years ago Utils.php 3 years ago
AppendStream.php
250 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 return $this->getContents();
44 } catch (\Throwable $e) {
45 if (\PHP_VERSION_ID >= 70400) {
46 throw $e;
47 }
48 trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR);
49 return '';
50 }
51 }
52
53 /**
54 * Add a stream to the AppendStream
55 *
56 * @param StreamInterface $stream Stream to append. Must be readable.
57 *
58 * @throws \InvalidArgumentException if the stream is not readable
59 */
60 public function addStream(StreamInterface $stream): void
61 {
62 if (!$stream->isReadable()) {
63 throw new \InvalidArgumentException('Each stream must be readable');
64 }
65
66 // The stream is only seekable if all streams are seekable
67 if (!$stream->isSeekable()) {
68 $this->seekable = false;
69 }
70
71 $this->streams[] = $stream;
72 }
73
74 public function getContents(): string
75 {
76 return Utils::copyToString($this);
77 }
78
79 /**
80 * Closes each attached stream.
81 */
82 public function close(): void
83 {
84 $this->pos = $this->current = 0;
85 $this->seekable = true;
86
87 foreach ($this->streams as $stream) {
88 $stream->close();
89 }
90
91 $this->streams = [];
92 }
93
94 /**
95 * Detaches each attached stream.
96 *
97 * Returns null as it's not clear which underlying stream resource to return.
98 */
99 public function detach()
100 {
101 $this->pos = $this->current = 0;
102 $this->seekable = true;
103
104 foreach ($this->streams as $stream) {
105 $stream->detach();
106 }
107
108 $this->streams = [];
109
110 return null;
111 }
112
113 public function tell(): int
114 {
115 return $this->pos;
116 }
117
118 /**
119 * Tries to calculate the size by adding the size of each stream.
120 *
121 * If any of the streams do not return a valid number, then the size of the
122 * append stream cannot be determined and null is returned.
123 */
124 public function getSize(): ?int
125 {
126 $size = 0;
127
128 foreach ($this->streams as $stream) {
129 $s = $stream->getSize();
130 if ($s === null) {
131 return null;
132 }
133 $size += $s;
134 }
135
136 return $size;
137 }
138
139 public function eof(): bool
140 {
141 return !$this->streams ||
142 ($this->current >= count($this->streams) - 1 &&
143 $this->streams[$this->current]->eof());
144 }
145
146 public function rewind(): void
147 {
148 $this->seek(0);
149 }
150
151 /**
152 * Attempts to seek to the given position. Only supports SEEK_SET.
153 */
154 public function seek($offset, $whence = SEEK_SET): void
155 {
156 if (!$this->seekable) {
157 throw new \RuntimeException('This AppendStream is not seekable');
158 } elseif ($whence !== SEEK_SET) {
159 throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
160 }
161
162 $this->pos = $this->current = 0;
163
164 // Rewind each stream
165 foreach ($this->streams as $i => $stream) {
166 try {
167 $stream->rewind();
168 } catch (\Exception $e) {
169 throw new \RuntimeException('Unable to seek stream '
170 . $i . ' of the AppendStream', 0, $e);
171 }
172 }
173
174 // Seek to the actual position by reading from each stream
175 while ($this->pos < $offset && !$this->eof()) {
176 $result = $this->read(min(8096, $offset - $this->pos));
177 if ($result === '') {
178 break;
179 }
180 }
181 }
182
183 /**
184 * Reads from all of the appended streams until the length is met or EOF.
185 */
186 public function read($length): string
187 {
188 $buffer = '';
189 $total = count($this->streams) - 1;
190 $remaining = $length;
191 $progressToNext = false;
192
193 while ($remaining > 0) {
194
195 // Progress to the next stream if needed.
196 if ($progressToNext || $this->streams[$this->current]->eof()) {
197 $progressToNext = false;
198 if ($this->current === $total) {
199 break;
200 }
201 $this->current++;
202 }
203
204 $result = $this->streams[$this->current]->read($remaining);
205
206 if ($result === '') {
207 $progressToNext = true;
208 continue;
209 }
210
211 $buffer .= $result;
212 $remaining = $length - strlen($buffer);
213 }
214
215 $this->pos += strlen($buffer);
216
217 return $buffer;
218 }
219
220 public function isReadable(): bool
221 {
222 return true;
223 }
224
225 public function isWritable(): bool
226 {
227 return false;
228 }
229
230 public function isSeekable(): bool
231 {
232 return $this->seekable;
233 }
234
235 public function write($string): int
236 {
237 throw new \RuntimeException('Cannot write to an AppendStream');
238 }
239
240 /**
241 * {@inheritdoc}
242 *
243 * @return mixed
244 */
245 public function getMetadata($key = null)
246 {
247 return $key ? null : [];
248 }
249 }
250