AbstractSignedInt::write()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 9
cts 9
cp 1
rs 9.7333
c 0
b 0
f 0
cc 3
nc 4
nop 1
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Buffertools\Types;
6
7
use BitWasp\Buffertools\Buffer;
8
use BitWasp\Buffertools\ByteOrder;
9
use BitWasp\Buffertools\Parser;
10
11
abstract class AbstractSignedInt extends AbstractType implements SignedIntInterface
12
{
13
    /**
14
     * @param int $byteOrder
15
     */
16 72
    public function __construct(int $byteOrder = ByteOrder::BE)
17
    {
18 72
        parent::__construct($byteOrder);
19 72
    }
20
21
    /**
22
     * @param int|string $integer
23
     * @return string
24
     */
25
    public function writeBits($integer): string
26
    {
27
        return str_pad(
28
            gmp_strval(gmp_init($integer, 10), 2),
29
            $this->getBitSize(),
30
            '0',
31
            STR_PAD_LEFT
32
        );
33
    }
34
35
    /**
36
     * @param Parser $parser
37
     * @return int|string
38
     * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange
39
     * @throws \Exception
40
     */
41 12
    public function readBits(Parser $parser)
42
    {
43 12
        $bitSize = $this->getBitSize();
44 12
        $byteSize = $bitSize / 8;
45
46 12
        $bytes = $parser->readBytes($byteSize);
47 12
        $bytes = $this->isBigEndian() ? $bytes : $bytes->flip();
48 12
        $chars = $bytes->getBinary();
49
50 12
        $offsetIndex = 0;
51 12
        $isNegative = (ord($chars[$offsetIndex]) & 0x80) != 0x00;
52 12
        $number = gmp_init(ord($chars[$offsetIndex++]) & 0x7F, 10);
53
54 12
        for ($i = 0; $i < $byteSize-1; $i++) {
55 12
            $number = gmp_or(gmp_mul($number, 0x100), ord($chars[$offsetIndex++]));
56
        }
57
58 12
        if ($isNegative) {
59 4
            $number = gmp_sub($number, gmp_pow(2, $bitSize - 1));
60
        }
61
62 12
        return gmp_strval($number, 10);
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     * @see \BitWasp\Buffertools\Types\TypeInterface::write()
68
     */
69 12
    public function write($integer): string
70
    {
71 12
        $bitSize = $this->getBitSize();
72 12
        if (gmp_sign($integer) < 0) {
73 4
            $integer = gmp_add($integer, (gmp_sub(gmp_pow(2, $bitSize), 1)));
74 4
            $integer = gmp_add($integer, 1);
75
        }
76
77 12
        $binary = Buffer::hex(str_pad(gmp_strval($integer, 16), $bitSize/4, '0', STR_PAD_LEFT), $bitSize/8);
78
79 12
        if (!$this->isBigEndian()) {
80 6
            $binary = $binary->flip();
81
        }
82
83 12
        return $binary->getBinary();
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     * @see \BitWasp\Buffertools\Types\TypeInterface::read()
89
     */
90 12
    public function read(Parser $binary)
91
    {
92 12
        return $this->readBits($binary);
93
    }
94
}
95