Int64::setEndianBig()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace PhpBinaryReader\Type;
4
5
use PhpBinaryReader\BinaryReader;
6
use PhpBinaryReader\BitMask;
7
use PhpBinaryReader\Endian;
8
9
class Int64 implements TypeInterface
10
{
11
    /**
12
     * @var string
13
     */
14
    private $endianBig = 'N';
15
16
    /**
17
     * @var string
18
     */
19
    private $endianLittle = 'V';
20
21
    /**
22
     * Returns an Unsigned 64-bit Integer
23
     *
24
     * @param  \PhpBinaryReader\BinaryReader $br
25
     * @param  null                          $length
26
     * @return int
27
     * @throws \OutOfBoundsException
28
     */
29 20
    public function read(BinaryReader &$br, $length = null)
30
    {
31 20
        if (!$br->canReadBytes(8)) {
32 4
            throw new \OutOfBoundsException('Cannot read 64-bit int, it exceeds the boundary of the file');
33
        }
34
35 16
        $endian = $br->getEndian() == Endian::ENDIAN_BIG ? $this->endianBig : $this->endianLittle;
36 16
        $firstSegment = $br->readFromHandle(4);
37 16
        $secondSegment = $br->readFromHandle(4);
38
39 16
        $firstHalf = unpack($endian, $firstSegment)[1];
40 16
        $secondHalf = unpack($endian, $secondSegment)[1];
41
42 16
        if ($br->getEndian() == Endian::ENDIAN_BIG) {
43 8
            $value = bcadd($secondHalf, bcmul($firstHalf, "4294967296"));
44
        } else {
45 10
            $value = bcadd($firstHalf, bcmul($secondHalf, "4294967296"));
46
        }
47
48 16
        if ($br->getCurrentBit() != 0) {
49 4
            $value = $this->bitReader($br, $value);
50
        }
51
52 16
        return $value;
53
    }
54
55
    /**
56
     * Returns a Signed 64-Bit Integer
57
     *
58
     * @param  \PhpBinaryReader\BinaryReader $br
59
     * @return int
60
     */
61 8
    public function readSigned(&$br)
62
    {
63 8
        $value = $this->read($br);
64 8
        if (bccomp($value, bcpow(2, 63)) >= 0) {
65 2
            $value = bcsub($value, bcpow(2, 64));
66
        }
67
68 8
        return $value;
69
    }
70
71
    /**
72
     * @param  \PhpBinaryReader\BinaryReader $br
73
     * @param  int                           $data
74
     * @return int
75
     */
76 4
    private function bitReader(&$br, $data)
77
    {
78 4
        $bitmask = new BitMask();
79 4
        $loMask = $bitmask->getMask($br->getCurrentBit(), BitMask::MASK_LO);
80 4
        $hiMask = $bitmask->getMask($br->getCurrentBit(), BitMask::MASK_HI);
81 4
        $hiBits = ($br->getNextByte() & $hiMask) << 56;
82 4
        $miBits = ($data & 0xFFFFFFFFFFFFFF00) >> (8 - $br->getCurrentBit());
83 4
        $loBits = ($data & $loMask);
84 4
        $br->setNextByte($data & 0xFF);
85
86 4
        return $hiBits | $miBits | $loBits;
87
    }
88
89
    /**
90
     * @param string $endianBig
91
     */
92 1
    public function setEndianBig($endianBig)
93
    {
94 1
        $this->endianBig = $endianBig;
95 1
    }
96
97
    /**
98
     * @return string
99
     */
100 1
    public function getEndianBig()
101
    {
102 1
        return $this->endianBig;
103
    }
104
105
    /**
106
     * @param string $endianLittle
107
     */
108 1
    public function setEndianLittle($endianLittle)
109
    {
110 1
        $this->endianLittle = $endianLittle;
111 1
    }
112
113
    /**
114
     * @return string
115
     */
116 1
    public function getEndianLittle()
117
    {
118 1
        return $this->endianLittle;
119
    }
120
}
121