PluginProbe ʕ •ᴥ•ʔ
ShareThis Dashboard for Google Analytics / 3.3.0
ShareThis Dashboard for Google Analytics v3.3.0
3.3.2 trunk 1.0.7 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2.5 2.3.5 2.3.6 2.3.7 2.3.8 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.0.0 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.3.0 3.3.1
googleanalytics / lib / analytics-admin / vendor / guzzlehttp / psr7 / src / CachingStream.php
googleanalytics / lib / analytics-admin / vendor / guzzlehttp / psr7 / src Last commit date
Exception 3 years ago AppendStream.php 3 years ago BufferStream.php 3 years ago CachingStream.php 3 years ago DroppingStream.php 3 years ago FnStream.php 3 years ago Header.php 3 years ago HttpFactory.php 3 years ago InflateStream.php 3 years ago LazyOpenStream.php 3 years ago LimitStream.php 3 years ago Message.php 3 years ago MessageTrait.php 3 years ago MimeType.php 3 years ago MultipartStream.php 3 years ago NoSeekStream.php 3 years ago PumpStream.php 3 years ago Query.php 3 years ago Request.php 3 years ago Response.php 3 years ago Rfc7230.php 3 years ago ServerRequest.php 3 years ago Stream.php 3 years ago StreamDecoratorTrait.php 3 years ago StreamWrapper.php 3 years ago UploadedFile.php 3 years ago Uri.php 3 years ago UriComparator.php 3 years ago UriNormalizer.php 3 years ago UriResolver.php 3 years ago Utils.php 3 years ago
CachingStream.php
154 lines
1 <?php
2
3 declare(strict_types=1);
4
5 namespace GuzzleHttp\Psr7;
6
7 use Psr\Http\Message\StreamInterface;
8
9 /**
10 * Stream decorator that can cache previously read bytes from a sequentially
11 * read stream.
12 */
13 final class CachingStream implements StreamInterface
14 {
15 use StreamDecoratorTrait;
16
17 /** @var StreamInterface Stream being wrapped */
18 private $remoteStream;
19
20 /** @var int Number of bytes to skip reading due to a write on the buffer */
21 private $skipReadBytes = 0;
22
23 /**
24 * @var StreamInterface
25 */
26 private $stream;
27
28 /**
29 * We will treat the buffer object as the body of the stream
30 *
31 * @param StreamInterface $stream Stream to cache. The cursor is assumed to be at the beginning of the stream.
32 * @param StreamInterface $target Optionally specify where data is cached
33 */
34 public function __construct(
35 StreamInterface $stream,
36 StreamInterface $target = null
37 ) {
38 $this->remoteStream = $stream;
39 $this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+'));
40 }
41
42 public function getSize(): ?int
43 {
44 $remoteSize = $this->remoteStream->getSize();
45
46 if (null === $remoteSize) {
47 return null;
48 }
49
50 return max($this->stream->getSize(), $remoteSize);
51 }
52
53 public function rewind(): void
54 {
55 $this->seek(0);
56 }
57
58 public function seek($offset, $whence = SEEK_SET): void
59 {
60 if ($whence === SEEK_SET) {
61 $byte = $offset;
62 } elseif ($whence === SEEK_CUR) {
63 $byte = $offset + $this->tell();
64 } elseif ($whence === SEEK_END) {
65 $size = $this->remoteStream->getSize();
66 if ($size === null) {
67 $size = $this->cacheEntireStream();
68 }
69 $byte = $size + $offset;
70 } else {
71 throw new \InvalidArgumentException('Invalid whence');
72 }
73
74 $diff = $byte - $this->stream->getSize();
75
76 if ($diff > 0) {
77 // Read the remoteStream until we have read in at least the amount
78 // of bytes requested, or we reach the end of the file.
79 while ($diff > 0 && !$this->remoteStream->eof()) {
80 $this->read($diff);
81 $diff = $byte - $this->stream->getSize();
82 }
83 } else {
84 // We can just do a normal seek since we've already seen this byte.
85 $this->stream->seek($byte);
86 }
87 }
88
89 public function read($length): string
90 {
91 // Perform a regular read on any previously read data from the buffer
92 $data = $this->stream->read($length);
93 $remaining = $length - strlen($data);
94
95 // More data was requested so read from the remote stream
96 if ($remaining) {
97 // If data was written to the buffer in a position that would have
98 // been filled from the remote stream, then we must skip bytes on
99 // the remote stream to emulate overwriting bytes from that
100 // position. This mimics the behavior of other PHP stream wrappers.
101 $remoteData = $this->remoteStream->read(
102 $remaining + $this->skipReadBytes
103 );
104
105 if ($this->skipReadBytes) {
106 $len = strlen($remoteData);
107 $remoteData = substr($remoteData, $this->skipReadBytes);
108 $this->skipReadBytes = max(0, $this->skipReadBytes - $len);
109 }
110
111 $data .= $remoteData;
112 $this->stream->write($remoteData);
113 }
114
115 return $data;
116 }
117
118 public function write($string): int
119 {
120 // When appending to the end of the currently read stream, you'll want
121 // to skip bytes from being read from the remote stream to emulate
122 // other stream wrappers. Basically replacing bytes of data of a fixed
123 // length.
124 $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell();
125 if ($overflow > 0) {
126 $this->skipReadBytes += $overflow;
127 }
128
129 return $this->stream->write($string);
130 }
131
132 public function eof(): bool
133 {
134 return $this->stream->eof() && $this->remoteStream->eof();
135 }
136
137 /**
138 * Close both the remote stream and buffer stream
139 */
140 public function close(): void
141 {
142 $this->remoteStream->close();
143 $this->stream->close();
144 }
145
146 private function cacheEntireStream(): int
147 {
148 $target = new FnStream(['write' => 'strlen']);
149 Utils::copyToStream($this, $target);
150
151 return $this->tell();
152 }
153 }
154