PluginProbe
Media Cloud Sync / 1.2.13
Media Cloud Sync v1.2.13
1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 All 35 releases
media-cloud-sync / includes / sdk / s3 / GuzzleHttp / Psr7 / CachingStream.php

CachingStream.php in Media Cloud Sync 1.2.13, at includes/sdk/s3/GuzzleHttp/Psr7/CachingStream.php

126 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare (strict_types=1);
4 namespace Dudlewebs\WPMCS\s3\GuzzleHttp\Psr7;
5
6 use Dudlewebs\WPMCS\s3\Psr\Http\Message\StreamInterface;
7 /**
8 * Stream decorator that can cache previously read bytes from a sequentially
9 * read stream.
10 */
11 final class CachingStream implements StreamInterface
12 {
13 use StreamDecoratorTrait;
14 /** @var StreamInterface Stream being wrapped */
15 private $remoteStream;
16 /** @var int Number of bytes to skip reading due to a write on the buffer */
17 private $skipReadBytes = 0;
18 /**
19 * @var StreamInterface
20 */
21 private $stream;
22 /**
23 * We will treat the buffer object as the body of the stream
24 *
25 * @param StreamInterface $stream Stream to cache. The cursor is assumed to be at the beginning of the stream.
26 * @param StreamInterface $target Optionally specify where data is cached
27 */
28 public function __construct(StreamInterface $stream, ?StreamInterface $target = null)
29 {
30 $this->remoteStream = $stream;
31 $this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+'));
32 }
33 public function getSize() : ?int
34 {
35 $remoteSize = $this->remoteStream->getSize();
36 if (null === $remoteSize) {
37 return null;
38 }
39 return \max($this->stream->getSize(), $remoteSize);
40 }
41 public function rewind() : void
42 {
43 $this->seek(0);
44 }
45 public function seek($offset, $whence = \SEEK_SET) : void
46 {
47 if ($whence === \SEEK_SET) {
48 $byte = $offset;
49 } elseif ($whence === \SEEK_CUR) {
50 $byte = $offset + $this->tell();
51 } elseif ($whence === \SEEK_END) {
52 $size = $this->remoteStream->getSize();
53 if ($size === null) {
54 $size = $this->cacheEntireStream();
55 }
56 $byte = $size + $offset;
57 } else {
58 throw new \InvalidArgumentException('Invalid whence');
59 }
60 $diff = $byte - $this->stream->getSize();
61 if ($diff > 0) {
62 // Read the remoteStream until we have read in at least the amount
63 // of bytes requested, or we reach the end of the file.
64 while ($diff > 0 && !$this->remoteStream->eof()) {
65 $this->read($diff);
66 $diff = $byte - $this->stream->getSize();
67 }
68 } else {
69 // We can just do a normal seek since we've already seen this byte.
70 $this->stream->seek($byte);
71 }
72 }
73 public function read($length) : string
74 {
75 // Perform a regular read on any previously read data from the buffer
76 $data = $this->stream->read($length);
77 $remaining = $length - \strlen($data);
78 // More data was requested so read from the remote stream
79 if ($remaining) {
80 // If data was written to the buffer in a position that would have
81 // been filled from the remote stream, then we must skip bytes on
82 // the remote stream to emulate overwriting bytes from that
83 // position. This mimics the behavior of other PHP stream wrappers.
84 $remoteData = $this->remoteStream->read($remaining + $this->skipReadBytes);
85 if ($this->skipReadBytes) {
86 $len = \strlen($remoteData);
87 $remoteData = \substr($remoteData, $this->skipReadBytes);
88 $this->skipReadBytes = \max(0, $this->skipReadBytes - $len);
89 }
90 $data .= $remoteData;
91 $this->stream->write($remoteData);
92 }
93 return $data;
94 }
95 public function write($string) : int
96 {
97 // When appending to the end of the currently read stream, you'll want
98 // to skip bytes from being read from the remote stream to emulate
99 // other stream wrappers. Basically replacing bytes of data of a fixed
100 // length.
101 $overflow = \strlen($string) + $this->tell() - $this->remoteStream->tell();
102 if ($overflow > 0) {
103 $this->skipReadBytes += $overflow;
104 }
105 return $this->stream->write($string);
106 }
107 public function eof() : bool
108 {
109 return $this->stream->eof() && $this->remoteStream->eof();
110 }
111 /**
112 * Close both the remote stream and buffer stream
113 */
114 public function close() : void
115 {
116 $this->remoteStream->close();
117 $this->stream->close();
118 }
119 private function cacheEntireStream() : int
120 {
121 $target = new FnStream(['write' => 'strlen']);
122 Utils::copyToStream($this, $target);
123 return $this->tell();
124 }
125 }
126