PluginProbe
Media Cloud Sync / 1.2.13
Media Cloud Sync v1.2.13
1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 All 35 releases
media-cloud-sync / includes / sdk / s3 / GuzzleHttp / Psr7 / AppendStream.php

AppendStream.php in Media Cloud Sync 1.2.13, at includes/sdk/s3/GuzzleHttp/Psr7/AppendStream.php

204 lines 5.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare (strict_types=1);
4 namespace Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7;
5
6 use Dudlewebs\WPMCS\s3\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 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(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 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