Buffer::stream_set_option()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 3
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace FakeSocket\Stream;
5
6
use FakeSocket\StreamWrapper;
7
8
final class Buffer implements StreamWrapper
9
{
10
    /** @var string */
11
    private $stream = '';
12
13
    /** @var int */
14
    private $position = 0;
15
16
    /** @var int */
17
    private $readCount = 0;
18
19
    /** @var int */
20
    private $writeCount = 0;
21
22
    /** @var array */
23
    private $limits = [
24
        'read'        => -1,
25
        'read_after'  => 0,
26
        'read_every'  => 1,
27
        'write'       => -1,
28
        'write_after' => 0,
29
        'write_every' => 1,
30
    ];
31
32 11
    public function stream_open($path, $mode, $options, &$opened_path)
0 ignored issues
show
Unused Code introduced by
The parameter $mode is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $opened_path is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
Method name "Buffer::stream_open" is not in camel caps format
Loading history...
33
    {
34 11
        $components = parse_url($path);
35
36 11
        static $query = [];
37
38 11
        if (isset($components['query'])) {
39 4
            parse_str($components['query'], $query);
40
        }
41
42 11
        $this->configureLimits($query);
0 ignored issues
show
Bug introduced by
It seems like $query can also be of type null; however, FakeSocket\Stream\Buffer::configureLimits() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
43
44 11
        return true;
45
    }
46
47 7
    public function stream_eof()
0 ignored issues
show
Coding Style introduced by
Method name "Buffer::stream_eof" is not in camel caps format
Loading history...
48
    {
49 7
        return $this->position >= strlen($this->stream);
50
    }
51
52 3
    public function stream_tell()
0 ignored issues
show
Coding Style introduced by
Method name "Buffer::stream_tell" is not in camel caps format
Loading history...
53
    {
54 3
        return $this->position;
55
    }
56
57 8
    public function stream_write($data)
0 ignored issues
show
Coding Style introduced by
Method name "Buffer::stream_write" is not in camel caps format
Loading history...
58
    {
59 8
        ++$this->writeCount;
60
61 8
        if (!$this->canWrite()) {
62 2
            return false;
63
        }
64
65 8
        $left = substr($this->stream, 0, $this->position);
66
67 8
        $this->stream = "{$left}{$data}";
68 8
        $this->position += $bytesWritten = strlen($data);
69
70 8
        return $bytesWritten;
71
    }
72
73 3
    public function stream_read($count)
0 ignored issues
show
Coding Style introduced by
Method name "Buffer::stream_read" is not in camel caps format
Loading history...
74
    {
75 3
        ++$this->readCount;
76
77 3
        if (!$this->canRead()) {
78 1
            return false;
79
        }
80
81 3
        $data = substr($this->stream, $this->position, $count);
82
83 3
        if ($data) {
84 2
            $this->position += strlen($data);
85
        }
86
87 3
        return $data;
88
    }
89
90 3
    public function stream_seek($offset, $whence)
0 ignored issues
show
Coding Style introduced by
Method name "Buffer::stream_seek" is not in camel caps format
Loading history...
91
    {
92 3
        static $values = [SEEK_SET, SEEK_CUR, SEEK_END];
93
94 3
        if (in_array($whence, $values)) {
95 3
            if (SEEK_END === $whence) {
96 1
                $offset = strlen($this->stream) + $offset;
97
            }
98
99 3
            if ($offset >= 0) {
100 3
                $this->position = $offset;
101 3
                return true;
102
            }
103
        }
104
105
        return false;
106
    }
107
108 2
    public function stream_stat()
0 ignored issues
show
Coding Style introduced by
Method name "Buffer::stream_stat" is not in camel caps format
Loading history...
109
    {
110 2
        return [];
111
    }
112
113 2
    public function stream_truncate($new_size)
0 ignored issues
show
Coding Style introduced by
Method name "Buffer::stream_truncate" is not in camel caps format
Loading history...
114
    {
115 2
        $currentLength = strlen($this->stream);
116
117 2
        if ($new_size > $currentLength) {
118 1
            $multiplier = $new_size - $currentLength;
119 1
            $this->stream .= str_repeat(chr(0), $multiplier);
120
121 1
            return true;
122
        }
123
124 1
        $this->stream = substr($this->stream, 0, $new_size);
125
126 1
        return true;
127
    }
128
129 1
    public function stream_set_option($option, $arg1, $arg2)
0 ignored issues
show
Coding Style introduced by
Method name "Buffer::stream_set_option" is not in camel caps format
Loading history...
130
    {
131 1
        return true;
132
    }
133
134 11
    private function configureLimits(array $query): void
135
    {
136 11
        foreach (array_keys($this->limits) as $limit) {
137 11
            if (!isset($query[$limit])) {
138 11
                continue;
139
            }
140
141 10
            if (false !== strrpos($limit, 'every')) {
142 2
                $query[$limit] = max(1, (int) $query[$limit]);
143
            }
144
145 10
            $this->limits[$limit] = (int) $query[$limit];
146
        }
147 11
    }
148
149 3
    private function canRead(): bool
150
    {
151 3
        $noLimit = $this->readCount !== $this->limits['read'] + 1;
152
153 3
        return $noLimit
154 3
            && $this->readCount > $this->limits['read_after']
155 3
            && $this->readCount % $this->limits['read_every'] === 0;
156
    }
157
158 8
    private function canWrite(): bool
159
    {
160 8
        $noLimit = $this->writeCount !== $this->limits['write'] + 1;
161
162 8
        return $noLimit
163 8
            && $this->writeCount > $this->limits['write_after']
164 8
            && $this->writeCount % $this->limits['write_every'] === 0;
165
    }
166
}
167