Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

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