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

AppendStream   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 221
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 75
c 1
b 0
f 0
dl 0
loc 221
rs 9.28
wmc 39

17 Methods

Rating   Name   Duplication   Size   Complexity  
A read() 0 33 6
B seek() 0 25 8
A addStream() 0 12 3
A write() 0 3 1
A tell() 0 3 1
A getContents() 0 3 1
A detach() 0 4 1
A __toString() 0 7 2
A isReadable() 0 3 1
A isSeekable() 0 3 1
A eof() 0 5 3
A getSize() 0 13 3
A __construct() 0 4 2
A getMetadata() 0 3 2
A isWritable() 0 3 1
A close() 0 9 2
A rewind() 0 3 1
1
<?php
2
namespace RingCentral\Psr7;
3
4
use Psr\Http\Message\StreamInterface;
5
6
/**
7
 * Reads from multiple streams, one after the other.
8
 *
9
 * This is a read-only stream decorator.
10
 */
11
class AppendStream implements StreamInterface
12
{
13
    /** @var StreamInterface[] Streams being decorated */
14
    private $streams = array();
15
16
    private $seekable = true;
17
    private $current = 0;
18
    private $pos = 0;
19
    private $detached = false;
20
21
    /**
22
     * @param StreamInterface[] $streams Streams to decorate. Each stream must
23
     *                                   be readable.
24
     */
25
    public function __construct(array $streams = array())
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
42
    /**
43
     * Add a stream to the AppendStream
44
     *
45
     * @param StreamInterface $stream Stream to append. Must be readable.
46
     *
47
     * @throws \InvalidArgumentException if the stream is not readable
48
     */
49
    public function addStream(StreamInterface $stream)
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
68
    /**
69
     * Closes each attached stream.
70
     *
71
     * {@inheritdoc}
72
     */
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 = array();
82
    }
83
84
    /**
85
     * Detaches each attached stream
86
     *
87
     * {@inheritdoc}
88
     */
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
100
    /**
101
     * Tries to calculate the size by adding the size of each stream.
102
     *
103
     * If any of the streams do not return a valid number, then the size of the
104
     * append stream cannot be determined and null is returned.
105
     *
106
     * {@inheritdoc}
107
     */
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 ||
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->streams of type Psr\Http\Message\StreamInterface[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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
135
    /**
136
     * Attempts to seek to the given position. Only supports SEEK_SET.
137
     *
138
     * {@inheritdoc}
139
     */
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
169
    /**
170
     * Reads from all of the appended streams until the length is met or EOF.
171
     *
172
     * {@inheritdoc}
173
     */
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 : array();
232
    }
233
}
234