ffb5440da16585076adb6aea04c281eb9fd492fc
[yaffs-website] / vendor / guzzlehttp / psr7 / src / PumpStream.php
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 }