2 namespace GuzzleHttp\Psr7;
4 use Psr\Http\Message\StreamInterface;
7 * Provides a read only stream that pumps data from a PHP callable.
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.
16 class PumpStream implements StreamInterface
30 /** @var BufferStream */
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
39 * @param array $options Stream options:
40 * - metadata: Hash of metadata to use with stream.
41 * - size: Size of the stream, if known.
43 public function __construct(callable $source, array $options = [])
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();
51 public function __toString()
54 return copy_to_string($this);
55 } catch (\Exception $e) {
60 public function close()
65 public function detach()
67 $this->tellPos = false;
71 public function getSize()
76 public function tell()
78 return $this->tellPos;
83 return !$this->source;
86 public function isSeekable()
91 public function rewind()
96 public function seek($offset, $whence = SEEK_SET)
98 throw new \RuntimeException('Cannot seek a PumpStream');
101 public function isWritable()
106 public function write($string)
108 throw new \RuntimeException('Cannot write to a PumpStream');
111 public function isReadable()
116 public function read($length)
118 $data = $this->buffer->read($length);
119 $readLen = strlen($data);
120 $this->tellPos += $readLen;
121 $remaining = $length - $readLen;
124 $this->pump($remaining);
125 $data .= $this->buffer->read($remaining);
126 $this->tellPos += strlen($data) - $readLen;
132 public function getContents()
135 while (!$this->eof()) {
136 $result .= $this->read(1000000);
142 public function getMetadata($key = null)
145 return $this->metadata;
148 return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
151 private function pump($length)
155 $data = call_user_func($this->source, $length);
156 if ($data === false || $data === null) {
157 $this->source = null;
160 $this->buffer->write($data);
161 $length -= strlen($data);
162 } while ($length > 0);