Open Journal Systems  3.3.0
vendor/guzzlehttp/psr7/src/Stream.php
1 <?php
2 namespace GuzzleHttp\Psr7;
3 
5 
11 class Stream implements StreamInterface
12 {
21  const READABLE_MODES = '/r|a\+|ab\+|w\+|wb\+|x\+|xb\+|c\+|cb\+/';
22  const WRITABLE_MODES = '/a|w|r\+|rb\+|rw|x|c/';
23 
24  private $stream;
25  private $size;
26  private $seekable;
27  private $readable;
28  private $writable;
29  private $uri;
30  private $customMetadata;
31 
46  public function __construct($stream, $options = [])
47  {
48  if (!is_resource($stream)) {
49  throw new \InvalidArgumentException('Stream must be a resource');
50  }
51 
52  if (isset($options['size'])) {
53  $this->size = $options['size'];
54  }
55 
56  $this->customMetadata = isset($options['metadata'])
57  ? $options['metadata']
58  : [];
59 
60  $this->stream = $stream;
61  $meta = stream_get_meta_data($this->stream);
62  $this->seekable = $meta['seekable'];
63  $this->readable = (bool)preg_match(self::READABLE_MODES, $meta['mode']);
64  $this->writable = (bool)preg_match(self::WRITABLE_MODES, $meta['mode']);
65  $this->uri = $this->getMetadata('uri');
66  }
67 
71  public function __destruct()
72  {
73  $this->close();
74  }
75 
76  public function __toString()
77  {
78  try {
79  $this->seek(0);
80  return (string) stream_get_contents($this->stream);
81  } catch (\Exception $e) {
82  return '';
83  }
84  }
85 
86  public function getContents()
87  {
88  if (!isset($this->stream)) {
89  throw new \RuntimeException('Stream is detached');
90  }
91 
92  $contents = stream_get_contents($this->stream);
93 
94  if ($contents === false) {
95  throw new \RuntimeException('Unable to read stream contents');
96  }
97 
98  return $contents;
99  }
100 
101  public function close()
102  {
103  if (isset($this->stream)) {
104  if (is_resource($this->stream)) {
105  fclose($this->stream);
106  }
107  $this->detach();
108  }
109  }
110 
111  public function detach()
112  {
113  if (!isset($this->stream)) {
114  return null;
115  }
116 
117  $result = $this->stream;
118  unset($this->stream);
119  $this->size = $this->uri = null;
120  $this->readable = $this->writable = $this->seekable = false;
121 
122  return $result;
123  }
124 
125  public function getSize()
126  {
127  if ($this->size !== null) {
128  return $this->size;
129  }
130 
131  if (!isset($this->stream)) {
132  return null;
133  }
134 
135  // Clear the stat cache if the stream has a URI
136  if ($this->uri) {
137  clearstatcache(true, $this->uri);
138  }
139 
140  $stats = fstat($this->stream);
141  if (isset($stats['size'])) {
142  $this->size = $stats['size'];
143  return $this->size;
144  }
145 
146  return null;
147  }
148 
149  public function isReadable()
150  {
151  return $this->readable;
152  }
153 
154  public function isWritable()
155  {
156  return $this->writable;
157  }
158 
159  public function isSeekable()
160  {
161  return $this->seekable;
162  }
163 
164  public function eof()
165  {
166  if (!isset($this->stream)) {
167  throw new \RuntimeException('Stream is detached');
168  }
169 
170  return feof($this->stream);
171  }
172 
173  public function tell()
174  {
175  if (!isset($this->stream)) {
176  throw new \RuntimeException('Stream is detached');
177  }
178 
179  $result = ftell($this->stream);
180 
181  if ($result === false) {
182  throw new \RuntimeException('Unable to determine stream position');
183  }
184 
185  return $result;
186  }
187 
188  public function rewind()
189  {
190  $this->seek(0);
191  }
192 
193  public function seek($offset, $whence = SEEK_SET)
194  {
195  $whence = (int) $whence;
196 
197  if (!isset($this->stream)) {
198  throw new \RuntimeException('Stream is detached');
199  }
200  if (!$this->seekable) {
201  throw new \RuntimeException('Stream is not seekable');
202  }
203  if (fseek($this->stream, $offset, $whence) === -1) {
204  throw new \RuntimeException('Unable to seek to stream position '
205  . $offset . ' with whence ' . var_export($whence, true));
206  }
207  }
208 
209  public function read($length)
210  {
211  if (!isset($this->stream)) {
212  throw new \RuntimeException('Stream is detached');
213  }
214  if (!$this->readable) {
215  throw new \RuntimeException('Cannot read from non-readable stream');
216  }
217  if ($length < 0) {
218  throw new \RuntimeException('Length parameter cannot be negative');
219  }
220 
221  if (0 === $length) {
222  return '';
223  }
224 
225  $string = fread($this->stream, $length);
226  if (false === $string) {
227  throw new \RuntimeException('Unable to read from stream');
228  }
229 
230  return $string;
231  }
232 
233  public function write($string)
234  {
235  if (!isset($this->stream)) {
236  throw new \RuntimeException('Stream is detached');
237  }
238  if (!$this->writable) {
239  throw new \RuntimeException('Cannot write to a non-writable stream');
240  }
241 
242  // We can't know the size after writing anything
243  $this->size = null;
244  $result = fwrite($this->stream, $string);
245 
246  if ($result === false) {
247  throw new \RuntimeException('Unable to write to stream');
248  }
249 
250  return $result;
251  }
252 
253  public function getMetadata($key = null)
254  {
255  if (!isset($this->stream)) {
256  return $key ? null : [];
257  } elseif (!$key) {
258  return $this->customMetadata + stream_get_meta_data($this->stream);
259  } elseif (isset($this->customMetadata[$key])) {
260  return $this->customMetadata[$key];
261  }
262 
263  $meta = stream_get_meta_data($this->stream);
264 
265  return isset($meta[$key]) ? $meta[$key] : null;
266  }
267 }
GuzzleHttp\Psr7\Stream\tell
tell()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:173
GuzzleHttp\Psr7\Stream\getSize
getSize()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:125
Psr\Http\Message\StreamInterface
Definition: vendor/psr/http-message/src/StreamInterface.php:12
GuzzleHttp\Psr7\Stream\rewind
rewind()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:188
GuzzleHttp\Psr7\Stream\seek
seek($offset, $whence=SEEK_SET)
Definition: vendor/guzzlehttp/psr7/src/Stream.php:193
GuzzleHttp\Psr7\Stream\getContents
getContents()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:86
GuzzleHttp\Psr7\Stream\WRITABLE_MODES
const WRITABLE_MODES
Definition: vendor/guzzlehttp/psr7/src/Stream.php:22
GuzzleHttp\Psr7\Stream\eof
eof()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:164
GuzzleHttp\Psr7\Stream\detach
detach()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:111
GuzzleHttp\Psr7\Stream\getMetadata
getMetadata($key=null)
Definition: vendor/guzzlehttp/psr7/src/Stream.php:253
GuzzleHttp\Psr7\Stream\__construct
__construct($stream, $options=[])
Definition: vendor/guzzlehttp/psr7/src/Stream.php:46
GuzzleHttp\Psr7\Stream\read
read($length)
Definition: vendor/guzzlehttp/psr7/src/Stream.php:209
GuzzleHttp\Psr7
Definition: AppendStream.php:2
GuzzleHttp\Psr7\Stream\close
close()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:101
GuzzleHttp\Psr7\Stream\__toString
__toString()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:76
GuzzleHttp\Psr7\Stream\READABLE_MODES
const READABLE_MODES
Definition: vendor/guzzlehttp/psr7/src/Stream.php:21
GuzzleHttp\Psr7\Stream\__destruct
__destruct()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:71
GuzzleHttp\Psr7\Stream\isReadable
isReadable()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:149
GuzzleHttp\Psr7\Stream\isWritable
isWritable()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:154
GuzzleHttp\Psr7\Stream\write
write($string)
Definition: vendor/guzzlehttp/psr7/src/Stream.php:233
GuzzleHttp\Psr7\Stream
Definition: vendor/guzzlehttp/psr7/src/Stream.php:11
GuzzleHttp\Psr7\Stream\isSeekable
isSeekable()
Definition: vendor/guzzlehttp/psr7/src/Stream.php:159