Subversion Repositories cheapmusic

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
103 - 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
}