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
 * Provides a read only stream that pumps data from a PHP callable.
8
 *
9
 * When invoking the provided callable, the PumpStream will pass the amount of
10
 * data requested to read to the callable. The callable can choose to ignore
11
 * this value and return fewer or more bytes than requested. Any extra data
12
 * returned by the provided callable is buffered internally until drained using
13
 * the read() function of the PumpStream. The provided callable MUST return
14
 * false when there is no more data to read.
15
 */
16
class PumpStream implements StreamInterface
17
{
18
    /** @var callable */
19
    private $source;
20
 
21
    /** @var int */
22
    private $size;
23
 
24
    /** @var int */
25
    private $tellPos = 0;
26
 
27
    /** @var array */
28
    private $metadata;
29
 
30
    /** @var BufferStream */
31
    private $buffer;
32
 
33
    /**
34
     * @param callable $source Source of the stream data. The callable MAY
35
     *                         accept an integer argument used to control the
36
     *                         amount of data to return. The callable MUST
37
     *                         return a string when called, or false on error
38
     *                         or EOF.
39
     * @param array $options   Stream options:
40
     *                         - metadata: Hash of metadata to use with stream.
41
     *                         - size: Size of the stream, if known.
42
     */
43
    public function __construct(callable $source, array $options = [])
44
    {
45
        $this->source = $source;
46
        $this->size = isset($options['size']) ? $options['size'] : null;
47
        $this->metadata = isset($options['metadata']) ? $options['metadata'] : [];
48
        $this->buffer = new BufferStream();
49
    }
50
 
51
    public function __toString()
52
    {
53
        try {
54
            return copy_to_string($this);
55
        } catch (\Exception $e) {
56
            return '';
57
        }
58
    }
59
 
60
    public function close()
61
    {
62
        $this->detach();
63
    }
64
 
65
    public function detach()
66
    {
67
        $this->tellPos = false;
68
        $this->source = null;
69
    }
70
 
71
    public function getSize()
72
    {
73
        return $this->size;
74
    }
75
 
76
    public function tell()
77
    {
78
        return $this->tellPos;
79
    }
80
 
81
    public function eof()
82
    {
83
        return !$this->source;
84
    }
85
 
86
    public function isSeekable()
87
    {
88
        return false;
89
    }
90
 
91
    public function rewind()
92
    {
93
        $this->seek(0);
94
    }
95
 
96
    public function seek($offset, $whence = SEEK_SET)
97
    {
98
        throw new \RuntimeException('Cannot seek a PumpStream');
99
    }
100
 
101
    public function isWritable()
102
    {
103
        return false;
104
    }
105
 
106
    public function write($string)
107
    {
108
        throw new \RuntimeException('Cannot write to a PumpStream');
109
    }
110
 
111
    public function isReadable()
112
    {
113
        return true;
114
    }
115
 
116
    public function read($length)
117
    {
118
        $data = $this->buffer->read($length);
119
        $readLen = strlen($data);
120
        $this->tellPos += $readLen;
121
        $remaining = $length - $readLen;
122
 
123
        if ($remaining) {
124
            $this->pump($remaining);
125
            $data .= $this->buffer->read($remaining);
126
            $this->tellPos += strlen($data) - $readLen;
127
        }
128
 
129
        return $data;
130
    }
131
 
132
    public function getContents()
133
    {
134
        $result = '';
135
        while (!$this->eof()) {
136
            $result .= $this->read(1000000);
137
        }
138
 
139
        return $result;
140
    }
141
 
142
    public function getMetadata($key = null)
143
    {
144
        if (!$key) {
145
            return $this->metadata;
146
        }
147
 
148
        return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
149
    }
150
 
151
    private function pump($length)
152
    {
153
        if ($this->source) {
154
            do {
155
                $data = call_user_func($this->source, $length);
156
                if ($data === false || $data === null) {
157
                    $this->source = null;
158
                    return;
159
                }
160
                $this->buffer->write($data);
161
                $length -= strlen($data);
162
            } while ($length > 0);
163
        }
164
    }
165
}