12 use StreamDecoratorTrait;
15 private $remoteStream;
18 private $skipReadBytes = 0;
30 $this->remoteStream = $stream;
31 $this->stream = $target ?:
new Stream(fopen(
'php://temp',
'r+'));
36 return max($this->stream->getSize(), $this->remoteStream->getSize());
44 public function seek($offset, $whence = SEEK_SET)
46 if ($whence == SEEK_SET) {
48 } elseif ($whence == SEEK_CUR) {
49 $byte = $offset + $this->
tell();
50 } elseif ($whence == SEEK_END) {
51 $size = $this->remoteStream->getSize();
53 $size = $this->cacheEntireStream();
55 $byte = $size + $offset;
57 throw new \InvalidArgumentException(
'Invalid whence');
60 $diff = $byte - $this->stream->getSize();
65 while ($diff > 0 && !$this->remoteStream->eof()) {
67 $diff = $byte - $this->stream->getSize();
71 $this->stream->seek($byte);
75 public function read($length)
78 $data = $this->stream->read($length);
79 $remaining = $length - strlen($data);
87 $remoteData = $this->remoteStream->read(
88 $remaining + $this->skipReadBytes
91 if ($this->skipReadBytes) {
92 $len = strlen($remoteData);
93 $remoteData = substr($remoteData, $this->skipReadBytes);
94 $this->skipReadBytes = max(0, $this->skipReadBytes - $len);
98 $this->stream->write($remoteData);
104 public function write($string)
110 $overflow = (strlen($string) + $this->
tell()) - $this->remoteStream->tell();
112 $this->skipReadBytes += $overflow;
115 return $this->stream->write($string);
118 public function eof()
120 return $this->stream->eof() && $this->remoteStream->eof();
126 public function close()
128 $this->remoteStream->close() && $this->stream->close();
131 private function cacheEntireStream()
133 $target =
new FnStream([
'write' =>
'strlen']);
136 return $this->
tell();