krz/vox-populi

A Tumblr web client.

clone: git clone https://gitbay.org/krz/vox-populi.git

main: vendor/guzzlehttp/psr7/src/PumpStream.php · raw

  1<?php
  2namespace GuzzleHttp\Psr7;
  3
  4use 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 */
 16class 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}