ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
AppendStream.php
Go to the documentation of this file.
1 <?php
2 namespace GuzzleHttp\Psr7;
3 
5 
11 class AppendStream implements StreamInterface
12 {
14  private $streams = [];
15 
16  private $seekable = true;
17  private $current = 0;
18  private $pos = 0;
19  private $detached = false;
20 
25  public function __construct(array $streams = [])
26  {
27  foreach ($streams as $stream) {
28  $this->addStream($stream);
29  }
30  }
31 
32  public function __toString()
33  {
34  try {
35  $this->rewind();
36  return $this->getContents();
37  } catch (\Exception $e) {
38  return '';
39  }
40  }
41 
50  {
51  if (!$stream->isReadable()) {
52  throw new \InvalidArgumentException('Each stream must be readable');
53  }
54 
55  // The stream is only seekable if all streams are seekable
56  if (!$stream->isSeekable()) {
57  $this->seekable = false;
58  }
59 
60  $this->streams[] = $stream;
61  }
62 
63  public function getContents()
64  {
65  return copy_to_string($this);
66  }
67 
73  public function close()
74  {
75  $this->pos = $this->current = 0;
76 
77  foreach ($this->streams as $stream) {
78  $stream->close();
79  }
80 
81  $this->streams = [];
82  }
83 
89  public function detach()
90  {
91  $this->close();
92  $this->detached = true;
93  }
94 
95  public function tell()
96  {
97  return $this->pos;
98  }
99 
108  public function getSize()
109  {
110  $size = 0;
111 
112  foreach ($this->streams as $stream) {
113  $s = $stream->getSize();
114  if ($s === null) {
115  return null;
116  }
117  $size += $s;
118  }
119 
120  return $size;
121  }
122 
123  public function eof()
124  {
125  return !$this->streams ||
126  ($this->current >= count($this->streams) - 1 &&
127  $this->streams[$this->current]->eof());
128  }
129 
130  public function rewind()
131  {
132  $this->seek(0);
133  }
134 
140  public function seek($offset, $whence = SEEK_SET)
141  {
142  if (!$this->seekable) {
143  throw new \RuntimeException('This AppendStream is not seekable');
144  } elseif ($whence !== SEEK_SET) {
145  throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
146  }
147 
148  $this->pos = $this->current = 0;
149 
150  // Rewind each stream
151  foreach ($this->streams as $i => $stream) {
152  try {
153  $stream->rewind();
154  } catch (\Exception $e) {
155  throw new \RuntimeException('Unable to seek stream '
156  . $i . ' of the AppendStream', 0, $e);
157  }
158  }
159 
160  // Seek to the actual position by reading from each stream
161  while ($this->pos < $offset && !$this->eof()) {
162  $result = $this->read(min(8096, $offset - $this->pos));
163  if ($result === '') {
164  break;
165  }
166  }
167  }
168 
174  public function read($length)
175  {
176  $buffer = '';
177  $total = count($this->streams) - 1;
178  $remaining = $length;
179  $progressToNext = false;
180 
181  while ($remaining > 0) {
182 
183  // Progress to the next stream if needed.
184  if ($progressToNext || $this->streams[$this->current]->eof()) {
185  $progressToNext = false;
186  if ($this->current === $total) {
187  break;
188  }
189  $this->current++;
190  }
191 
192  $result = $this->streams[$this->current]->read($remaining);
193 
194  // Using a loose comparison here to match on '', false, and null
195  if ($result == null) {
196  $progressToNext = true;
197  continue;
198  }
199 
200  $buffer .= $result;
201  $remaining = $length - strlen($buffer);
202  }
203 
204  $this->pos += strlen($buffer);
205 
206  return $buffer;
207  }
208 
209  public function isReadable()
210  {
211  return true;
212  }
213 
214  public function isWritable()
215  {
216  return false;
217  }
218 
219  public function isSeekable()
220  {
221  return $this->seekable;
222  }
223 
224  public function write($string)
225  {
226  throw new \RuntimeException('Cannot write to an AppendStream');
227  }
228 
229  public function getMetadata($key = null)
230  {
231  return $key ? null : [];
232  }
233 }
getSize()
Tries to calculate the size by adding the size of each stream.
$size
Definition: RandomTest.php:84
__toString()
Reads all data from the stream into a string, from the beginning to end.
$result
rewind()
Seek to the beginning of the stream.
$s
Definition: pwgen.php:45
if($state['core:TerminatedAssocId'] !==null) $remaining
write($string)
Write data to the stream.
$stream
PHP stream implementation.
$total
Definition: Utf8Test.php:87
isReadable()
Returns whether or not the stream is readable.
getContents()
Returns the remaining contents in a string.
eof()
Returns true if the stream is at the end of the stream.
addStream(StreamInterface $stream)
Add a stream to the AppendStream.
isSeekable()
Returns whether or not the stream is seekable.
read($length)
Reads from all of the appended streams until the length is met or EOF.
__construct(array $streams=[])
close()
Closes each attached stream.
detach()
Detaches each attached stream.
$i
Definition: disco.tpl.php:19
isWritable()
Returns whether or not the stream is writable.
copy_to_string(StreamInterface $stream, $maxLen=-1)
Copy the contents of a stream into a string until the given number of bytes have been read...
Definition: functions.php:328
isReadable()
Returns whether or not the stream is readable.
Reads from multiple streams, one after the other.
$key
Definition: croninfo.php:18
getMetadata($key=null)
Get stream metadata as an associative array or retrieve a specific key.
isSeekable()
Returns whether or not the stream is seekable.
seek($offset, $whence=SEEK_SET)
Attempts to seek to the given position.
Describes a data stream.
tell()
Returns the current position of the file read/write pointer.