PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / vendor / php-http / message / src / Stream / BufferedStream.php
ameliabooking / vendor / php-http / message / src / Stream Last commit date
BufferedStream.php 6 months ago
BufferedStream.php
271 lines
1 <?php
2
3 namespace AmeliaHttp\Message\Stream;
4
5 use AmeliaVendor\Psr\Http\Message\StreamInterface;
6
7 /**
8 * Decorator to make any stream seekable.
9 *
10 * Internally it buffers an existing StreamInterface into a php://temp resource (or memory). By default it will use
11 * 2 megabytes of memory before writing to a temporary disk file.
12 *
13 * Due to this, very large stream can suffer performance issue (i/o slowdown).
14 */
15 class BufferedStream implements StreamInterface
16 {
17 /** @var resource The buffered resource used to seek previous data */
18 private $resource;
19
20 /** @var int size of the stream if available */
21 private $size;
22
23 /** @var StreamInterface The underlying stream decorated by this class */
24 private $stream;
25
26 /** @var int How many bytes were written */
27 private $written = 0;
28
29 /**
30 * @param StreamInterface $stream Decorated stream
31 * @param bool $useFileBuffer Whether to use a file buffer (write to a file, if data exceed a certain size)
32 * by default, set this to false to only use memory
33 * @param int $memoryBuffer In conjunction with using file buffer, limit (in bytes) from which it begins to buffer
34 * the data in a file
35 */
36 public function __construct(StreamInterface $stream, $useFileBuffer = true, $memoryBuffer = 2097152)
37 {
38 $this->stream = $stream;
39 $this->size = $stream->getSize();
40
41 if ($useFileBuffer) {
42 $this->resource = fopen('php://temp/maxmemory:'.$memoryBuffer, 'rw+');
43 } else {
44 $this->resource = fopen('php://memory', 'rw+');
45 }
46
47 if (false === $this->resource) {
48 throw new \RuntimeException('Cannot create a resource over temp or memory implementation');
49 }
50 }
51
52 /**
53 * {@inheritdoc}
54 */
55 public function __toString()
56 {
57 try {
58 $this->rewind();
59
60 return $this->getContents();
61 } catch (\Throwable $throwable) {
62 return '';
63 } catch (\Exception $exception) { // Layer to be BC with PHP 5, remove this when we only support PHP 7+
64 return '';
65 }
66 }
67
68 /**
69 * {@inheritdoc}
70 */
71 public function close()
72 {
73 if (null === $this->resource) {
74 throw new \RuntimeException('Cannot close on a detached stream');
75 }
76
77 $this->stream->close();
78 fclose($this->resource);
79 }
80
81 /**
82 * {@inheritdoc}
83 */
84 public function detach()
85 {
86 if (null === $this->resource) {
87 return;
88 }
89
90 // Force reading the remaining data of the stream
91 $this->getContents();
92
93 $resource = $this->resource;
94 $this->stream->close();
95 $this->stream = null;
96 $this->resource = null;
97
98 return $resource;
99 }
100
101 /**
102 * {@inheritdoc}
103 */
104 public function getSize()
105 {
106 if (null === $this->resource) {
107 return;
108 }
109
110 if (null === $this->size && $this->stream->eof()) {
111 return $this->written;
112 }
113
114 return $this->size;
115 }
116
117 /**
118 * {@inheritdoc}
119 */
120 public function tell()
121 {
122 if (null === $this->resource) {
123 throw new \RuntimeException('Cannot tell on a detached stream');
124 }
125
126 return ftell($this->resource);
127 }
128
129 /**
130 * {@inheritdoc}
131 */
132 public function eof()
133 {
134 if (null === $this->resource) {
135 throw new \RuntimeException('Cannot call eof on a detached stream');
136 }
137
138 // We are at the end only when both our resource and underlying stream are at eof
139 return $this->stream->eof() && (ftell($this->resource) === $this->written);
140 }
141
142 /**
143 * {@inheritdoc}
144 */
145 public function isSeekable()
146 {
147 return null !== $this->resource;
148 }
149
150 /**
151 * {@inheritdoc}
152 */
153 public function seek($offset, $whence = SEEK_SET)
154 {
155 if (null === $this->resource) {
156 throw new \RuntimeException('Cannot seek on a detached stream');
157 }
158
159 fseek($this->resource, $offset, $whence);
160 }
161
162 /**
163 * {@inheritdoc}
164 */
165 public function rewind()
166 {
167 if (null === $this->resource) {
168 throw new \RuntimeException('Cannot rewind on a detached stream');
169 }
170
171 rewind($this->resource);
172 }
173
174 /**
175 * {@inheritdoc}
176 */
177 public function isWritable()
178 {
179 return false;
180 }
181
182 /**
183 * {@inheritdoc}
184 */
185 public function write($string)
186 {
187 throw new \RuntimeException('Cannot write on this stream');
188 }
189
190 /**
191 * {@inheritdoc}
192 */
193 public function isReadable()
194 {
195 return null !== $this->resource;
196 }
197
198 /**
199 * {@inheritdoc}
200 */
201 public function read($length)
202 {
203 if (null === $this->resource) {
204 throw new \RuntimeException('Cannot read on a detached stream');
205 }
206
207 $read = '';
208
209 // First read from the resource
210 if (ftell($this->resource) !== $this->written) {
211 $read = fread($this->resource, $length);
212 }
213
214 $bytesRead = strlen($read);
215
216 if ($bytesRead < $length) {
217 $streamRead = $this->stream->read($length - $bytesRead);
218
219 // Write on the underlying stream what we read
220 $this->written += fwrite($this->resource, $streamRead);
221 $read .= $streamRead;
222 }
223
224 return $read;
225 }
226
227 /**
228 * {@inheritdoc}
229 */
230 public function getContents()
231 {
232 if (null === $this->resource) {
233 throw new \RuntimeException('Cannot read on a detached stream');
234 }
235
236 $read = '';
237
238 while (!$this->eof()) {
239 $read .= $this->read(8192);
240 }
241
242 return $read;
243 }
244
245 /**
246 * {@inheritdoc}
247 */
248 public function getMetadata($key = null)
249 {
250 if (null === $this->resource) {
251 if (null === $key) {
252 return [];
253 }
254
255 return;
256 }
257
258 $metadata = stream_get_meta_data($this->resource);
259
260 if (null === $key) {
261 return $metadata;
262 }
263
264 if (!array_key_exists($key, $metadata)) {
265 return;
266 }
267
268 return $metadata[$key];
269 }
270 }
271