1 | <?php |
||
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 | 13 | public function __construct(StreamInterface $stream, $useFileBuffer = true, $memoryBuffer = 2097152) |
|
37 | { |
||
38 | 13 | $this->stream = $stream; |
|
39 | 13 | $this->size = $stream->getSize(); |
|
40 | |||
41 | 13 | if ($useFileBuffer) { |
|
42 | 13 | $this->resource = fopen('php://temp/maxmemory:'.$memoryBuffer, 'rw+'); |
|
43 | } else { |
||
44 | $this->resource = fopen('php://memory', 'rw+'); |
||
45 | } |
||
46 | |||
47 | 13 | if (false === $this->resource) { |
|
48 | throw new \RuntimeException('Cannot create a resource over temp or memory implementation'); |
||
49 | } |
||
50 | 13 | } |
|
51 | |||
52 | /** |
||
53 | * {@inheritdoc} |
||
54 | */ |
||
55 | 1 | public function __toString() |
|
67 | |||
68 | /** |
||
69 | * {@inheritdoc} |
||
70 | */ |
||
71 | public function close() |
||
80 | |||
81 | /** |
||
82 | * {@inheritdoc} |
||
83 | */ |
||
84 | 1 | public function detach() |
|
100 | |||
101 | /** |
||
102 | * {@inheritdoc} |
||
103 | */ |
||
104 | 1 | public function getSize() |
|
116 | |||
117 | /** |
||
118 | * {@inheritdoc} |
||
119 | */ |
||
120 | 3 | public function tell() |
|
128 | |||
129 | /** |
||
130 | * {@inheritdoc} |
||
131 | */ |
||
132 | 8 | public function eof() |
|
141 | |||
142 | /** |
||
143 | * {@inheritdoc} |
||
144 | */ |
||
145 | 1 | public function isSeekable() |
|
149 | |||
150 | /** |
||
151 | * {@inheritdoc} |
||
152 | */ |
||
153 | 2 | public function seek($offset, $whence = SEEK_SET) |
|
161 | |||
162 | /** |
||
163 | * {@inheritdoc} |
||
164 | */ |
||
165 | 3 | public function rewind() |
|
173 | |||
174 | /** |
||
175 | * {@inheritdoc} |
||
176 | */ |
||
177 | 1 | public function isWritable() |
|
181 | |||
182 | /** |
||
183 | * {@inheritdoc} |
||
184 | */ |
||
185 | 1 | public function write($string) |
|
189 | |||
190 | /** |
||
191 | * {@inheritdoc} |
||
192 | */ |
||
193 | 1 | public function isReadable() |
|
197 | |||
198 | /** |
||
199 | * {@inheritdoc} |
||
200 | */ |
||
201 | 8 | public function read($length) |
|
202 | { |
||
203 | 8 | if (null === $this->resource) { |
|
204 | throw new \RuntimeException('Cannot read on a detached stream'); |
||
205 | } |
||
206 | |||
207 | 8 | $read = ''; |
|
208 | |||
209 | // First read from the resource |
||
210 | 8 | if (ftell($this->resource) !== $this->written) { |
|
211 | 1 | $read = fread($this->resource, $length); |
|
212 | } |
||
213 | |||
214 | 8 | $bytesRead = strlen($read); |
|
215 | |||
216 | 8 | if ($bytesRead < $length) { |
|
217 | 8 | $streamRead = $this->stream->read($length - $bytesRead); |
|
218 | |||
219 | // Write on the underlying stream what we read |
||
220 | 8 | $this->written += fwrite($this->resource, $streamRead); |
|
221 | 8 | $read .= $streamRead; |
|
222 | } |
||
223 | |||
224 | 8 | return $read; |
|
225 | } |
||
226 | |||
227 | /** |
||
228 | * {@inheritdoc} |
||
229 | */ |
||
230 | 8 | public function getContents() |
|
231 | { |
||
232 | 8 | if (null === $this->resource) { |
|
233 | throw new \RuntimeException('Cannot read on a detached stream'); |
||
234 | } |
||
235 | |||
236 | 8 | $read = ''; |
|
237 | |||
238 | 8 | while (!$this->eof()) { |
|
239 | 7 | $read .= $this->read(8192); |
|
240 | } |
||
241 | |||
242 | 8 | return $read; |
|
243 | } |
||
244 | |||
245 | /** |
||
246 | * {@inheritdoc} |
||
247 | */ |
||
248 | 1 | public function getMetadata($key = null) |
|
270 | } |
||
271 |