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 ( 95c197...564e5e )
by Joni
04:32
created

Flags   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 45
dl 0
loc 146
ccs 49
cts 49
cp 1
rs 10
c 0
b 0
f 0
wmc 14

7 Methods

Rating   Name   Duplication   Size   Complexity  
A fromBitString() 0 9 2
A __construct() 0 26 4
A test() 0 13 2
A intNumber() 0 4 1
A string() 0 3 1
A number() 0 7 2
A bitString() 0 5 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Sop\ASN1\Util;
6
7
use Sop\ASN1\Type\Primitive\BitString;
8
9
/**
10
 * Class to handle a bit string as a field of flags.
11
 */
12
class Flags
13
{
14
    /**
15
     * Flag octets.
16
     *
17
     * @var string
18
     */
19
    protected $_flags;
20
21
    /**
22
     * Number of flags.
23
     *
24
     * @var int
25
     */
26
    protected $_width;
27
28
    /**
29
     * Constructor.
30
     *
31
     * @param int|string $flags Flags
32
     * @param int        $width The number of flags. If width is larger than
33
     *                          number of bits in $flags, zeroes are prepended
34
     *                          to flag field.
35
     */
36 62
    public function __construct($flags, int $width)
37
    {
38 62
        if (!$width) {
39 2
            $this->_flags = '';
40
        } else {
41
            // calculate number of unused bits in last octet
42 60
            $last_octet_bits = $width % 8;
43 60
            $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0;
44 60
            $num = gmp_init($flags);
45
            // mask bits outside bitfield width
46 60
            $mask = gmp_sub(gmp_init(1) << $width, 1);
47 60
            $num &= $mask;
48
            // shift towards MSB if needed
49 60
            $data = gmp_export($num << $unused_bits, 1,
50 60
                GMP_MSW_FIRST | GMP_BIG_ENDIAN);
51 60
            $octets = unpack('C*', $data);
52 60
            assert(is_array($octets), new \RuntimeException('unpack() failed'));
53 60
            $bits = count($octets) * 8;
54
            // pad with zeroes
55 60
            while ($bits < $width) {
56 20
                array_unshift($octets, 0);
57 20
                $bits += 8;
58
            }
59 60
            $this->_flags = pack('C*', ...$octets);
60
        }
61 62
        $this->_width = $width;
62 62
    }
63
64
    /**
65
     * Initialize from BitString.
66
     *
67
     * @param BitString $bs
68
     * @param int       $width
69
     *
70
     * @return self
71
     */
72 8
    public static function fromBitString(BitString $bs, int $width): self
73
    {
74 8
        $num_bits = $bs->numBits();
75 8
        $num = gmp_import($bs->string(), 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN);
76 8
        $num >>= $bs->unusedBits();
77 8
        if ($num_bits < $width) {
78 5
            $num <<= ($width - $num_bits);
79
        }
80 8
        return new self(gmp_strval($num, 10), $width);
81
    }
82
83
    /**
84
     * Check whether a bit at given index is set.
85
     *
86
     * Index 0 is the leftmost bit.
87
     *
88
     * @param int $idx
89
     *
90
     * @throws \OutOfBoundsException
91
     *
92
     * @return bool
93
     */
94 15
    public function test(int $idx): bool
95
    {
96 15
        if ($idx >= $this->_width) {
97 1
            throw new \OutOfBoundsException('Index is out of bounds.');
98
        }
99
        // octet index
100 14
        $oi = (int) floor($idx / 8);
101 14
        $byte = $this->_flags[$oi];
102
        // bit index
103 14
        $bi = $idx % 8;
104
        // index 0 is the most significant bit in byte
105 14
        $mask = 0x01 << (7 - $bi);
106 14
        return (ord($byte) & $mask) > 0;
107
    }
108
109
    /**
110
     * Get flags as an octet string.
111
     *
112
     * Zeroes are appended to the last octet if width is not divisible by 8.
113
     *
114
     * @return string
115
     */
116 23
    public function string(): string
117
    {
118 23
        return $this->_flags;
119
    }
120
121
    /**
122
     * Get flags as a base 10 integer.
123
     *
124
     * @return string Integer as a string
125
     */
126 15
    public function number(): string
127
    {
128 15
        $num = gmp_import($this->_flags, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN);
129 15
        $last_octet_bits = $this->_width % 8;
130 15
        $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0;
131 15
        $num >>= $unused_bits;
132 15
        return gmp_strval($num, 10);
133
    }
134
135
    /**
136
     * Get flags as an integer.
137
     *
138
     * @return int
139
     */
140 1
    public function intNumber(): int
141
    {
142 1
        $num = new BigInt($this->number());
143 1
        return $num->intVal();
144
    }
145
146
    /**
147
     * Get flags as a BitString.
148
     *
149
     * Unused bits are set accordingly. Trailing zeroes are not stripped.
150
     *
151
     * @return BitString
152
     */
153 9
    public function bitString(): BitString
154
    {
155 9
        $last_octet_bits = $this->_width % 8;
156 9
        $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0;
157 9
        return new BitString($this->_flags, $unused_bits);
158
    }
159
}
160