krz/vox-populi

A Tumblr web client.

clone: git clone https://gitbay.org/krz/vox-populi.git

main: vendor/guzzlehttp/psr7/src/FnStream.php · raw

  1<?php
  2namespace GuzzleHttp\Psr7;
  3
  4use Psr\Http\Message\StreamInterface;
  5
  6/**
  7 * Compose stream implementations based on a hash of functions.
  8 *
  9 * Allows for easy testing and extension of a provided stream without needing
 10 * to create a concrete class for a simple extension point.
 11 */
 12class FnStream implements StreamInterface
 13{
 14    /** @var array */
 15    private $methods;
 16
 17    /** @var array Methods that must be implemented in the given array */
 18    private static $slots = ['__toString', 'close', 'detach', 'rewind',
 19        'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
 20        'isReadable', 'read', 'getContents', 'getMetadata'];
 21
 22    /**
 23     * @param array $methods Hash of method name to a callable.
 24     */
 25    public function __construct(array $methods)
 26    {
 27        $this->methods = $methods;
 28
 29        // Create the functions on the class
 30        foreach ($methods as $name => $fn) {
 31            $this->{'_fn_' . $name} = $fn;
 32        }
 33    }
 34
 35    /**
 36     * Lazily determine which methods are not implemented.
 37     * @throws \BadMethodCallException
 38     */
 39    public function __get($name)
 40    {
 41        throw new \BadMethodCallException(str_replace('_fn_', '', $name)
 42            . '() is not implemented in the FnStream');
 43    }
 44
 45    /**
 46     * The close method is called on the underlying stream only if possible.
 47     */
 48    public function __destruct()
 49    {
 50        if (isset($this->_fn_close)) {
 51            call_user_func($this->_fn_close);
 52        }
 53    }
 54
 55    /**
 56     * An unserialize would allow the __destruct to run when the unserialized value goes out of scope.
 57     * @throws \LogicException
 58     */
 59    public function __wakeup()
 60    {
 61        throw new \LogicException('FnStream should never be unserialized');
 62    }
 63
 64    /**
 65     * Adds custom functionality to an underlying stream by intercepting
 66     * specific method calls.
 67     *
 68     * @param StreamInterface $stream  Stream to decorate
 69     * @param array           $methods Hash of method name to a closure
 70     *
 71     * @return FnStream
 72     */
 73    public static function decorate(StreamInterface $stream, array $methods)
 74    {
 75        // If any of the required methods were not provided, then simply
 76        // proxy to the decorated stream.
 77        foreach (array_diff(self::$slots, array_keys($methods)) as $diff) {
 78            $methods[$diff] = [$stream, $diff];
 79        }
 80
 81        return new self($methods);
 82    }
 83
 84    public function __toString()
 85    {
 86        return call_user_func($this->_fn___toString);
 87    }
 88
 89    public function close()
 90    {
 91        return call_user_func($this->_fn_close);
 92    }
 93
 94    public function detach()
 95    {
 96        return call_user_func($this->_fn_detach);
 97    }
 98
 99    public function getSize()
100    {
101        return call_user_func($this->_fn_getSize);
102    }
103
104    public function tell()
105    {
106        return call_user_func($this->_fn_tell);
107    }
108
109    public function eof()
110    {
111        return call_user_func($this->_fn_eof);
112    }
113
114    public function isSeekable()
115    {
116        return call_user_func($this->_fn_isSeekable);
117    }
118
119    public function rewind()
120    {
121        call_user_func($this->_fn_rewind);
122    }
123
124    public function seek($offset, $whence = SEEK_SET)
125    {
126        call_user_func($this->_fn_seek, $offset, $whence);
127    }
128
129    public function isWritable()
130    {
131        return call_user_func($this->_fn_isWritable);
132    }
133
134    public function write($string)
135    {
136        return call_user_func($this->_fn_write, $string);
137    }
138
139    public function isReadable()
140    {
141        return call_user_func($this->_fn_isReadable);
142    }
143
144    public function read($length)
145    {
146        return call_user_func($this->_fn_read, $length);
147    }
148
149    public function getContents()
150    {
151        return call_user_func($this->_fn_getContents);
152    }
153
154    public function getMetadata($key = null)
155    {
156        return call_user_func($this->_fn_getMetadata, $key);
157    }
158}