Version 1
[yaffs-website] / vendor / zendframework / zend-diactoros / src / Stream.php
diff --git a/vendor/zendframework/zend-diactoros/src/Stream.php b/vendor/zendframework/zend-diactoros/src/Stream.php
new file mode 100644 (file)
index 0000000..6a04e2b
--- /dev/null
@@ -0,0 +1,328 @@
+<?php
+/**
+ * Zend Framework (http://framework.zend.com/)
+ *
+ * @see       http://github.com/zendframework/zend-diactoros for the canonical source repository
+ * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license   https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
+ */
+
+namespace Zend\Diactoros;
+
+use InvalidArgumentException;
+use RuntimeException;
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Implementation of PSR HTTP streams
+ */
+class Stream implements StreamInterface
+{
+    /**
+     * @var resource|null
+     */
+    protected $resource;
+
+    /**
+     * @var string|resource
+     */
+    protected $stream;
+
+    /**
+     * @param string|resource $stream
+     * @param string $mode Mode with which to open stream
+     * @throws InvalidArgumentException
+     */
+    public function __construct($stream, $mode = 'r')
+    {
+        $this->setStream($stream, $mode);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function __toString()
+    {
+        if (! $this->isReadable()) {
+            return '';
+        }
+
+        try {
+            $this->rewind();
+            return $this->getContents();
+        } catch (RuntimeException $e) {
+            return '';
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function close()
+    {
+        if (! $this->resource) {
+            return;
+        }
+
+        $resource = $this->detach();
+        fclose($resource);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function detach()
+    {
+        $resource = $this->resource;
+        $this->resource = null;
+        return $resource;
+    }
+
+    /**
+     * Attach a new stream/resource to the instance.
+     *
+     * @param string|resource $resource
+     * @param string $mode
+     * @throws InvalidArgumentException for stream identifier that cannot be
+     *     cast to a resource
+     * @throws InvalidArgumentException for non-resource stream
+     */
+    public function attach($resource, $mode = 'r')
+    {
+        $this->setStream($resource, $mode);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSize()
+    {
+        if (null === $this->resource) {
+            return null;
+        }
+
+        $stats = fstat($this->resource);
+        return $stats['size'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function tell()
+    {
+        if (! $this->resource) {
+            throw new RuntimeException('No resource available; cannot tell position');
+        }
+
+        $result = ftell($this->resource);
+        if (! is_int($result)) {
+            throw new RuntimeException('Error occurred during tell operation');
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function eof()
+    {
+        if (! $this->resource) {
+            return true;
+        }
+
+        return feof($this->resource);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isSeekable()
+    {
+        if (! $this->resource) {
+            return false;
+        }
+
+        $meta = stream_get_meta_data($this->resource);
+        return $meta['seekable'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function seek($offset, $whence = SEEK_SET)
+    {
+        if (! $this->resource) {
+            throw new RuntimeException('No resource available; cannot seek position');
+        }
+
+        if (! $this->isSeekable()) {
+            throw new RuntimeException('Stream is not seekable');
+        }
+
+        $result = fseek($this->resource, $offset, $whence);
+
+        if (0 !== $result) {
+            throw new RuntimeException('Error seeking within stream');
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rewind()
+    {
+        return $this->seek(0);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isWritable()
+    {
+        if (! $this->resource) {
+            return false;
+        }
+
+        $meta = stream_get_meta_data($this->resource);
+        $mode = $meta['mode'];
+
+        return (
+            strstr($mode, 'x')
+            || strstr($mode, 'w')
+            || strstr($mode, 'c')
+            || strstr($mode, 'a')
+            || strstr($mode, '+')
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function write($string)
+    {
+        if (! $this->resource) {
+            throw new RuntimeException('No resource available; cannot write');
+        }
+
+        if (! $this->isWritable()) {
+            throw new RuntimeException('Stream is not writable');
+        }
+
+        $result = fwrite($this->resource, $string);
+
+        if (false === $result) {
+            throw new RuntimeException('Error writing to stream');
+        }
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isReadable()
+    {
+        if (! $this->resource) {
+            return false;
+        }
+
+        $meta = stream_get_meta_data($this->resource);
+        $mode = $meta['mode'];
+
+        return (strstr($mode, 'r') || strstr($mode, '+'));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function read($length)
+    {
+        if (! $this->resource) {
+            throw new RuntimeException('No resource available; cannot read');
+        }
+
+        if (! $this->isReadable()) {
+            throw new RuntimeException('Stream is not readable');
+        }
+
+        $result = fread($this->resource, $length);
+
+        if (false === $result) {
+            throw new RuntimeException('Error reading stream');
+        }
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getContents()
+    {
+        if (! $this->isReadable()) {
+            throw new RuntimeException('Stream is not readable');
+        }
+
+        $result = stream_get_contents($this->resource);
+        if (false === $result) {
+            throw new RuntimeException('Error reading from stream');
+        }
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadata($key = null)
+    {
+        if (null === $key) {
+            return stream_get_meta_data($this->resource);
+        }
+
+        $metadata = stream_get_meta_data($this->resource);
+        if (! array_key_exists($key, $metadata)) {
+            return null;
+        }
+
+        return $metadata[$key];
+    }
+
+    /**
+     * Set the internal stream resource.
+     *
+     * @param string|resource $stream String stream target or stream resource.
+     * @param string $mode Resource mode for stream target.
+     * @throws InvalidArgumentException for invalid streams or resources.
+     */
+    private function setStream($stream, $mode = 'r')
+    {
+        $error    = null;
+        $resource = $stream;
+
+        if (is_string($stream)) {
+            set_error_handler(function ($e) use (&$error) {
+                $error = $e;
+            }, E_WARNING);
+            $resource = fopen($stream, $mode);
+            restore_error_handler();
+        }
+
+        if ($error) {
+            throw new InvalidArgumentException('Invalid stream reference provided');
+        }
+
+        if (! is_resource($resource) || 'stream' !== get_resource_type($resource)) {
+            throw new InvalidArgumentException(
+                'Invalid stream provided; must be a string stream identifier or stream resource'
+            );
+        }
+
+        if ($stream !== $resource) {
+            $this->stream = $stream;
+        }
+
+        $this->resource = $resource;
+    }
+}