annotate vendor/zendframework/zend-diactoros/src/Stream.php @ 0:c75dbcec494b

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