GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 5cefd1...492078 )
by Anton
04:08
created

CachingStream   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 44
c 1
b 0
f 0
dl 0
loc 124
rs 10
wmc 20

9 Methods

Rating   Name   Duplication   Size   Complexity  
A eof() 0 3 2
A read() 0 27 3
A getSize() 0 3 1
A write() 0 12 2
A __construct() 0 6 2
A seek() 0 26 6
A rewind() 0 3 1
A cacheEntireStream() 0 6 1
A close() 0 3 2
1
<?php
2
namespace RingCentral\Psr7;
3
4
use Psr\Http\Message\StreamInterface;
5
6
/**
7
 * Stream decorator that can cache previously read bytes from a sequentially
8
 * read stream.
9
 */
10
class CachingStream extends StreamDecoratorTrait implements StreamInterface
11
{
12
13
    /** @var StreamInterface Stream being wrapped */
14
    private $remoteStream;
15
16
    /** @var int Number of bytes to skip reading due to a write on the buffer */
17
    private $skipReadBytes = 0;
18
19
    /**
20
     * We will treat the buffer object as the body of the stream
21
     *
22
     * @param StreamInterface $stream Stream to cache
23
     * @param StreamInterface $target Optionally specify where data is cached
24
     */
25
    public function __construct(
26
        StreamInterface $stream,
27
        StreamInterface $target = null
28
    ) {
29
        $this->remoteStream = $stream;
30
        parent::__construct($target ?: new Stream(fopen('php://temp', 'r+')));
31
    }
32
33
    public function getSize()
34
    {
35
        return max($this->stream->getSize(), $this->remoteStream->getSize());
36
    }
37
38
    public function rewind()
39
    {
40
        $this->seek(0);
41
    }
42
43
    public function seek($offset, $whence = SEEK_SET)
44
    {
45
        if ($whence == SEEK_SET) {
46
            $byte = $offset;
47
        } elseif ($whence == SEEK_CUR) {
48
            $byte = $offset + $this->tell();
49
        } elseif ($whence == SEEK_END) {
50
            $size = $this->remoteStream->getSize();
51
            if ($size === null) {
52
                $size = $this->cacheEntireStream();
53
            }
54
            // Because 0 is the first byte, we seek to size - 1.
55
            $byte = $size - 1 - $offset;
56
        } else {
57
            throw new \InvalidArgumentException('Invalid whence');
58
        }
59
60
        $diff = $byte - $this->stream->getSize();
61
62
        if ($diff > 0) {
63
            // If the seek byte is greater the number of read bytes, then read
64
            // the difference of bytes to cache the bytes and inherently seek.
65
            $this->read($diff);
66
        } else {
67
            // We can just do a normal seek since we've already seen this byte.
68
            $this->stream->seek($byte);
69
        }
70
    }
71
72
    public function read($length)
73
    {
74
        // Perform a regular read on any previously read data from the buffer
75
        $data = $this->stream->read($length);
76
        $remaining = $length - strlen($data);
77
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(
85
                $remaining + $this->skipReadBytes
86
            );
87
88
            if ($this->skipReadBytes) {
89
                $len = strlen($remoteData);
90
                $remoteData = substr($remoteData, $this->skipReadBytes);
91
                $this->skipReadBytes = max(0, $this->skipReadBytes - $len);
92
            }
93
94
            $data .= $remoteData;
95
            $this->stream->write($remoteData);
96
        }
97
98
        return $data;
99
    }
100
101
    public function write($string)
102
    {
103
        // When appending to the end of the currently read stream, you'll want
104
        // to skip bytes from being read from the remote stream to emulate
105
        // other stream wrappers. Basically replacing bytes of data of a fixed
106
        // length.
107
        $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell();
108
        if ($overflow > 0) {
109
            $this->skipReadBytes += $overflow;
110
        }
111
112
        return $this->stream->write($string);
113
    }
114
115
    public function eof()
116
    {
117
        return $this->stream->eof() && $this->remoteStream->eof();
118
    }
119
120
    /**
121
     * Close both the remote stream and buffer stream
122
     */
123
    public function close()
124
    {
125
        $this->remoteStream->close() && $this->stream->close();
126
    }
127
128
    private function cacheEntireStream()
129
    {
130
        $target = new FnStream(array('write' => 'strlen'));
131
        copy_to_stream($this, $target);
132
133
        return $this->tell();
134
    }
135
}
136