comparison vendor/guzzlehttp/psr7/src/FnStream.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 129ea1e6d783
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2 namespace GuzzleHttp\Psr7;
3
4 use 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 */
12 class 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 * Adds custom functionality to an underlying stream by intercepting
57 * specific method calls.
58 *
59 * @param StreamInterface $stream Stream to decorate
60 * @param array $methods Hash of method name to a closure
61 *
62 * @return FnStream
63 */
64 public static function decorate(StreamInterface $stream, array $methods)
65 {
66 // If any of the required methods were not provided, then simply
67 // proxy to the decorated stream.
68 foreach (array_diff(self::$slots, array_keys($methods)) as $diff) {
69 $methods[$diff] = [$stream, $diff];
70 }
71
72 return new self($methods);
73 }
74
75 public function __toString()
76 {
77 return call_user_func($this->_fn___toString);
78 }
79
80 public function close()
81 {
82 return call_user_func($this->_fn_close);
83 }
84
85 public function detach()
86 {
87 return call_user_func($this->_fn_detach);
88 }
89
90 public function getSize()
91 {
92 return call_user_func($this->_fn_getSize);
93 }
94
95 public function tell()
96 {
97 return call_user_func($this->_fn_tell);
98 }
99
100 public function eof()
101 {
102 return call_user_func($this->_fn_eof);
103 }
104
105 public function isSeekable()
106 {
107 return call_user_func($this->_fn_isSeekable);
108 }
109
110 public function rewind()
111 {
112 call_user_func($this->_fn_rewind);
113 }
114
115 public function seek($offset, $whence = SEEK_SET)
116 {
117 call_user_func($this->_fn_seek, $offset, $whence);
118 }
119
120 public function isWritable()
121 {
122 return call_user_func($this->_fn_isWritable);
123 }
124
125 public function write($string)
126 {
127 return call_user_func($this->_fn_write, $string);
128 }
129
130 public function isReadable()
131 {
132 return call_user_func($this->_fn_isReadable);
133 }
134
135 public function read($length)
136 {
137 return call_user_func($this->_fn_read, $length);
138 }
139
140 public function getContents()
141 {
142 return call_user_func($this->_fn_getContents);
143 }
144
145 public function getMetadata($key = null)
146 {
147 return call_user_func($this->_fn_getMetadata, $key);
148 }
149 }