annotate vendor/zendframework/zend-diactoros/src/Stream.php @ 12:7a779792577d

Update Drupal core to v8.4.5 (via Composer)
author Chris Cannam
date Fri, 23 Feb 2018 15:52:07 +0000
parents 4c8ae668cc8c
children 5fb285c0d0e3
rev   line source
Chris@0 1 <?php
Chris@0 2 /**
Chris@12 3 * @see https://github.com/zendframework/zend-diactoros for the canonical source repository
Chris@12 4 * @copyright Copyright (c) 2015-2017 Zend Technologies USA Inc. (http://www.zend.com)
Chris@0 5 * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
Chris@0 6 */
Chris@0 7
Chris@0 8 namespace Zend\Diactoros;
Chris@0 9
Chris@0 10 use InvalidArgumentException;
Chris@0 11 use RuntimeException;
Chris@0 12 use Psr\Http\Message\StreamInterface;
Chris@0 13
Chris@0 14 /**
Chris@0 15 * Implementation of PSR HTTP streams
Chris@0 16 */
Chris@0 17 class Stream implements StreamInterface
Chris@0 18 {
Chris@0 19 /**
Chris@0 20 * @var resource|null
Chris@0 21 */
Chris@0 22 protected $resource;
Chris@0 23
Chris@0 24 /**
Chris@0 25 * @var string|resource
Chris@0 26 */
Chris@0 27 protected $stream;
Chris@0 28
Chris@0 29 /**
Chris@0 30 * @param string|resource $stream
Chris@0 31 * @param string $mode Mode with which to open stream
Chris@0 32 * @throws InvalidArgumentException
Chris@0 33 */
Chris@0 34 public function __construct($stream, $mode = 'r')
Chris@0 35 {
Chris@0 36 $this->setStream($stream, $mode);
Chris@0 37 }
Chris@0 38
Chris@0 39 /**
Chris@0 40 * {@inheritdoc}
Chris@0 41 */
Chris@0 42 public function __toString()
Chris@0 43 {
Chris@0 44 if (! $this->isReadable()) {
Chris@0 45 return '';
Chris@0 46 }
Chris@0 47
Chris@0 48 try {
Chris@0 49 if ($this->isSeekable()) {
Chris@0 50 $this->rewind();
Chris@0 51 }
Chris@0 52
Chris@0 53 return $this->getContents();
Chris@0 54 } catch (RuntimeException $e) {
Chris@0 55 return '';
Chris@0 56 }
Chris@0 57 }
Chris@0 58
Chris@0 59 /**
Chris@0 60 * {@inheritdoc}
Chris@0 61 */
Chris@0 62 public function close()
Chris@0 63 {
Chris@0 64 if (! $this->resource) {
Chris@0 65 return;
Chris@0 66 }
Chris@0 67
Chris@0 68 $resource = $this->detach();
Chris@0 69 fclose($resource);
Chris@0 70 }
Chris@0 71
Chris@0 72 /**
Chris@0 73 * {@inheritdoc}
Chris@0 74 */
Chris@0 75 public function detach()
Chris@0 76 {
Chris@0 77 $resource = $this->resource;
Chris@0 78 $this->resource = null;
Chris@0 79 return $resource;
Chris@0 80 }
Chris@0 81
Chris@0 82 /**
Chris@0 83 * Attach a new stream/resource to the instance.
Chris@0 84 *
Chris@0 85 * @param string|resource $resource
Chris@0 86 * @param string $mode
Chris@0 87 * @throws InvalidArgumentException for stream identifier that cannot be
Chris@0 88 * cast to a resource
Chris@0 89 * @throws InvalidArgumentException for non-resource stream
Chris@0 90 */
Chris@0 91 public function attach($resource, $mode = 'r')
Chris@0 92 {
Chris@0 93 $this->setStream($resource, $mode);
Chris@0 94 }
Chris@0 95
Chris@0 96 /**
Chris@0 97 * {@inheritdoc}
Chris@0 98 */
Chris@0 99 public function getSize()
Chris@0 100 {
Chris@0 101 if (null === $this->resource) {
Chris@0 102 return null;
Chris@0 103 }
Chris@0 104
Chris@0 105 $stats = fstat($this->resource);
Chris@0 106 return $stats['size'];
Chris@0 107 }
Chris@0 108
Chris@0 109 /**
Chris@0 110 * {@inheritdoc}
Chris@0 111 */
Chris@0 112 public function tell()
Chris@0 113 {
Chris@0 114 if (! $this->resource) {
Chris@0 115 throw new RuntimeException('No resource available; cannot tell position');
Chris@0 116 }
Chris@0 117
Chris@0 118 $result = ftell($this->resource);
Chris@0 119 if (! is_int($result)) {
Chris@0 120 throw new RuntimeException('Error occurred during tell operation');
Chris@0 121 }
Chris@0 122
Chris@0 123 return $result;
Chris@0 124 }
Chris@0 125
Chris@0 126 /**
Chris@0 127 * {@inheritdoc}
Chris@0 128 */
Chris@0 129 public function eof()
Chris@0 130 {
Chris@0 131 if (! $this->resource) {
Chris@0 132 return true;
Chris@0 133 }
Chris@0 134
Chris@0 135 return feof($this->resource);
Chris@0 136 }
Chris@0 137
Chris@0 138 /**
Chris@0 139 * {@inheritdoc}
Chris@0 140 */
Chris@0 141 public function isSeekable()
Chris@0 142 {
Chris@0 143 if (! $this->resource) {
Chris@0 144 return false;
Chris@0 145 }
Chris@0 146
Chris@0 147 $meta = stream_get_meta_data($this->resource);
Chris@0 148 return $meta['seekable'];
Chris@0 149 }
Chris@0 150
Chris@0 151 /**
Chris@0 152 * {@inheritdoc}
Chris@0 153 */
Chris@0 154 public function seek($offset, $whence = SEEK_SET)
Chris@0 155 {
Chris@0 156 if (! $this->resource) {
Chris@0 157 throw new RuntimeException('No resource available; cannot seek position');
Chris@0 158 }
Chris@0 159
Chris@0 160 if (! $this->isSeekable()) {
Chris@0 161 throw new RuntimeException('Stream is not seekable');
Chris@0 162 }
Chris@0 163
Chris@0 164 $result = fseek($this->resource, $offset, $whence);
Chris@0 165
Chris@0 166 if (0 !== $result) {
Chris@0 167 throw new RuntimeException('Error seeking within stream');
Chris@0 168 }
Chris@0 169
Chris@0 170 return true;
Chris@0 171 }
Chris@0 172
Chris@0 173 /**
Chris@0 174 * {@inheritdoc}
Chris@0 175 */
Chris@0 176 public function rewind()
Chris@0 177 {
Chris@0 178 return $this->seek(0);
Chris@0 179 }
Chris@0 180
Chris@0 181 /**
Chris@0 182 * {@inheritdoc}
Chris@0 183 */
Chris@0 184 public function isWritable()
Chris@0 185 {
Chris@0 186 if (! $this->resource) {
Chris@0 187 return false;
Chris@0 188 }
Chris@0 189
Chris@0 190 $meta = stream_get_meta_data($this->resource);
Chris@0 191 $mode = $meta['mode'];
Chris@0 192
Chris@0 193 return (
Chris@0 194 strstr($mode, 'x')
Chris@0 195 || strstr($mode, 'w')
Chris@0 196 || strstr($mode, 'c')
Chris@0 197 || strstr($mode, 'a')
Chris@0 198 || strstr($mode, '+')
Chris@0 199 );
Chris@0 200 }
Chris@0 201
Chris@0 202 /**
Chris@0 203 * {@inheritdoc}
Chris@0 204 */
Chris@0 205 public function write($string)
Chris@0 206 {
Chris@0 207 if (! $this->resource) {
Chris@0 208 throw new RuntimeException('No resource available; cannot write');
Chris@0 209 }
Chris@0 210
Chris@0 211 if (! $this->isWritable()) {
Chris@0 212 throw new RuntimeException('Stream is not writable');
Chris@0 213 }
Chris@0 214
Chris@0 215 $result = fwrite($this->resource, $string);
Chris@0 216
Chris@0 217 if (false === $result) {
Chris@0 218 throw new RuntimeException('Error writing to stream');
Chris@0 219 }
Chris@0 220 return $result;
Chris@0 221 }
Chris@0 222
Chris@0 223 /**
Chris@0 224 * {@inheritdoc}
Chris@0 225 */
Chris@0 226 public function isReadable()
Chris@0 227 {
Chris@0 228 if (! $this->resource) {
Chris@0 229 return false;
Chris@0 230 }
Chris@0 231
Chris@0 232 $meta = stream_get_meta_data($this->resource);
Chris@0 233 $mode = $meta['mode'];
Chris@0 234
Chris@0 235 return (strstr($mode, 'r') || strstr($mode, '+'));
Chris@0 236 }
Chris@0 237
Chris@0 238 /**
Chris@0 239 * {@inheritdoc}
Chris@0 240 */
Chris@0 241 public function read($length)
Chris@0 242 {
Chris@0 243 if (! $this->resource) {
Chris@0 244 throw new RuntimeException('No resource available; cannot read');
Chris@0 245 }
Chris@0 246
Chris@0 247 if (! $this->isReadable()) {
Chris@0 248 throw new RuntimeException('Stream is not readable');
Chris@0 249 }
Chris@0 250
Chris@0 251 $result = fread($this->resource, $length);
Chris@0 252
Chris@0 253 if (false === $result) {
Chris@0 254 throw new RuntimeException('Error reading stream');
Chris@0 255 }
Chris@0 256
Chris@0 257 return $result;
Chris@0 258 }
Chris@0 259
Chris@0 260 /**
Chris@0 261 * {@inheritdoc}
Chris@0 262 */
Chris@0 263 public function getContents()
Chris@0 264 {
Chris@0 265 if (! $this->isReadable()) {
Chris@0 266 throw new RuntimeException('Stream is not readable');
Chris@0 267 }
Chris@0 268
Chris@0 269 $result = stream_get_contents($this->resource);
Chris@0 270 if (false === $result) {
Chris@0 271 throw new RuntimeException('Error reading from stream');
Chris@0 272 }
Chris@0 273 return $result;
Chris@0 274 }
Chris@0 275
Chris@0 276 /**
Chris@0 277 * {@inheritdoc}
Chris@0 278 */
Chris@0 279 public function getMetadata($key = null)
Chris@0 280 {
Chris@0 281 if (null === $key) {
Chris@0 282 return stream_get_meta_data($this->resource);
Chris@0 283 }
Chris@0 284
Chris@0 285 $metadata = stream_get_meta_data($this->resource);
Chris@0 286 if (! array_key_exists($key, $metadata)) {
Chris@0 287 return null;
Chris@0 288 }
Chris@0 289
Chris@0 290 return $metadata[$key];
Chris@0 291 }
Chris@0 292
Chris@0 293 /**
Chris@0 294 * Set the internal stream resource.
Chris@0 295 *
Chris@0 296 * @param string|resource $stream String stream target or stream resource.
Chris@0 297 * @param string $mode Resource mode for stream target.
Chris@0 298 * @throws InvalidArgumentException for invalid streams or resources.
Chris@0 299 */
Chris@0 300 private function setStream($stream, $mode = 'r')
Chris@0 301 {
Chris@0 302 $error = null;
Chris@0 303 $resource = $stream;
Chris@0 304
Chris@0 305 if (is_string($stream)) {
Chris@0 306 set_error_handler(function ($e) use (&$error) {
Chris@0 307 $error = $e;
Chris@0 308 }, E_WARNING);
Chris@0 309 $resource = fopen($stream, $mode);
Chris@0 310 restore_error_handler();
Chris@0 311 }
Chris@0 312
Chris@0 313 if ($error) {
Chris@0 314 throw new InvalidArgumentException('Invalid stream reference provided');
Chris@0 315 }
Chris@0 316
Chris@0 317 if (! is_resource($resource) || 'stream' !== get_resource_type($resource)) {
Chris@0 318 throw new InvalidArgumentException(
Chris@0 319 'Invalid stream provided; must be a string stream identifier or stream resource'
Chris@0 320 );
Chris@0 321 }
Chris@0 322
Chris@0 323 if ($stream !== $resource) {
Chris@0 324 $this->stream = $stream;
Chris@0 325 }
Chris@0 326
Chris@0 327 $this->resource = $resource;
Chris@0 328 }
Chris@0 329 }