Mercurial > hg > isophonics-drupal-site
comparison vendor/guzzlehttp/psr7/src/LimitStream.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 namespace GuzzleHttp\Psr7; | |
3 | |
4 use Psr\Http\Message\StreamInterface; | |
5 | |
6 | |
7 /** | |
8 * Decorator used to return only a subset of a stream | |
9 */ | |
10 class LimitStream implements StreamInterface | |
11 { | |
12 use StreamDecoratorTrait; | |
13 | |
14 /** @var int Offset to start reading from */ | |
15 private $offset; | |
16 | |
17 /** @var int Limit the number of bytes that can be read */ | |
18 private $limit; | |
19 | |
20 /** | |
21 * @param StreamInterface $stream Stream to wrap | |
22 * @param int $limit Total number of bytes to allow to be read | |
23 * from the stream. Pass -1 for no limit. | |
24 * @param int $offset Position to seek to before reading (only | |
25 * works on seekable streams). | |
26 */ | |
27 public function __construct( | |
28 StreamInterface $stream, | |
29 $limit = -1, | |
30 $offset = 0 | |
31 ) { | |
32 $this->stream = $stream; | |
33 $this->setLimit($limit); | |
34 $this->setOffset($offset); | |
35 } | |
36 | |
37 public function eof() | |
38 { | |
39 // Always return true if the underlying stream is EOF | |
40 if ($this->stream->eof()) { | |
41 return true; | |
42 } | |
43 | |
44 // No limit and the underlying stream is not at EOF | |
45 if ($this->limit == -1) { | |
46 return false; | |
47 } | |
48 | |
49 return $this->stream->tell() >= $this->offset + $this->limit; | |
50 } | |
51 | |
52 /** | |
53 * Returns the size of the limited subset of data | |
54 * {@inheritdoc} | |
55 */ | |
56 public function getSize() | |
57 { | |
58 if (null === ($length = $this->stream->getSize())) { | |
59 return null; | |
60 } elseif ($this->limit == -1) { | |
61 return $length - $this->offset; | |
62 } else { | |
63 return min($this->limit, $length - $this->offset); | |
64 } | |
65 } | |
66 | |
67 /** | |
68 * Allow for a bounded seek on the read limited stream | |
69 * {@inheritdoc} | |
70 */ | |
71 public function seek($offset, $whence = SEEK_SET) | |
72 { | |
73 if ($whence !== SEEK_SET || $offset < 0) { | |
74 throw new \RuntimeException(sprintf( | |
75 'Cannot seek to offset % with whence %s', | |
76 $offset, | |
77 $whence | |
78 )); | |
79 } | |
80 | |
81 $offset += $this->offset; | |
82 | |
83 if ($this->limit !== -1) { | |
84 if ($offset > $this->offset + $this->limit) { | |
85 $offset = $this->offset + $this->limit; | |
86 } | |
87 } | |
88 | |
89 $this->stream->seek($offset); | |
90 } | |
91 | |
92 /** | |
93 * Give a relative tell() | |
94 * {@inheritdoc} | |
95 */ | |
96 public function tell() | |
97 { | |
98 return $this->stream->tell() - $this->offset; | |
99 } | |
100 | |
101 /** | |
102 * Set the offset to start limiting from | |
103 * | |
104 * @param int $offset Offset to seek to and begin byte limiting from | |
105 * | |
106 * @throws \RuntimeException if the stream cannot be seeked. | |
107 */ | |
108 public function setOffset($offset) | |
109 { | |
110 $current = $this->stream->tell(); | |
111 | |
112 if ($current !== $offset) { | |
113 // If the stream cannot seek to the offset position, then read to it | |
114 if ($this->stream->isSeekable()) { | |
115 $this->stream->seek($offset); | |
116 } elseif ($current > $offset) { | |
117 throw new \RuntimeException("Could not seek to stream offset $offset"); | |
118 } else { | |
119 $this->stream->read($offset - $current); | |
120 } | |
121 } | |
122 | |
123 $this->offset = $offset; | |
124 } | |
125 | |
126 /** | |
127 * Set the limit of bytes that the decorator allows to be read from the | |
128 * stream. | |
129 * | |
130 * @param int $limit Number of bytes to allow to be read from the stream. | |
131 * Use -1 for no limit. | |
132 */ | |
133 public function setLimit($limit) | |
134 { | |
135 $this->limit = $limit; | |
136 } | |
137 | |
138 public function read($length) | |
139 { | |
140 if ($this->limit == -1) { | |
141 return $this->stream->read($length); | |
142 } | |
143 | |
144 // Check if the current position is less than the total allowed | |
145 // bytes + original offset | |
146 $remaining = ($this->offset + $this->limit) - $this->stream->tell(); | |
147 if ($remaining > 0) { | |
148 // Only return the amount of requested data, ensuring that the byte | |
149 // limit is not exceeded | |
150 return $this->stream->read(min($remaining, $length)); | |
151 } | |
152 | |
153 return ''; | |
154 } | |
155 } |