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