ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
AppendStream.php
Go to the documentation of this file.
1<?php
3
5
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}
$result
$size
Definition: RandomTest.php:84
$total
Definition: Utf8Test.php:87
An exception for terminatinating execution or to throw for unit testing.
Reads from multiple streams, one after the other.
tell()
Returns the current position of the file read/write pointer.
seek($offset, $whence=SEEK_SET)
Attempts to seek to the given position.
__toString()
Reads all data from the stream into a string, from the beginning to end.
rewind()
Seek to the beginning of the stream.
read($length)
Reads from all of the appended streams until the length is met or EOF.
write($string)
Write data to the stream.
getSize()
Tries to calculate the size by adding the size of each stream.
addStream(StreamInterface $stream)
Add a stream to the AppendStream.
eof()
Returns true if the stream is at the end of the stream.
detach()
Detaches each attached stream.
isSeekable()
Returns whether or not the stream is seekable.
isReadable()
Returns whether or not the stream is readable.
close()
Closes each attached stream.
__construct(array $streams=[])
getContents()
Returns the remaining contents in a string.
isWritable()
Returns whether or not the stream is writable.
getMetadata($key=null)
Get stream metadata as an associative array or retrieve a specific key.
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
Describes a data stream.
$stream
PHP stream implementation.
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
$s
Definition: pwgen.php:45
if($state['core:TerminatedAssocId'] !==null) $remaining