Completed
Pull Request — master (#14)
by
unknown
03:00
created

Int64::getEndianBig()   A

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 0
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 16
            $value = bcadd($secondHalf, bcmul($firstHalf, "4294967296"));
44
        else
45 10
            $value = bcadd($firstHalf, bcmul($secondHalf, "4294967296"));
46
47 16
        if ($br->getCurrentBit() != 0) {
48 4
            $value = $this->bitReader($br, $value);
49 4
        }
50
51 16
        return $value;
52
    }
53
54
    /**
55
     * Returns a Signed 64-Bit Integer
56
     *
57
     * @param  \PhpBinaryReader\BinaryReader $br
58
     * @return int
59
     */
60 8
    public function readSigned(&$br)
61
    {
62 8
        $value = $this->read($br);
63 8
        if (bccomp($value, bcpow(2, 63)) >= 0) {
64 2
            $value = bcsub($value, bcpow(2, 64));
65 2
        }
66
67 8
        return $value;
68
    }
69
70
    /**
71
     * @param  \PhpBinaryReader\BinaryReader $br
72
     * @param  int                           $data
73
     * @return int
74
     */
75 4
    private function bitReader(&$br, $data)
76
    {
77 4
        $bitmask = new BitMask();
78 4
        $loMask = $bitmask->getMask($br->getCurrentBit(), BitMask::MASK_LO);
79 4
        $hiMask = $bitmask->getMask($br->getCurrentBit(), BitMask::MASK_HI);
80 4
        $hiBits = ($br->getNextByte() & $hiMask) << 56;
81 4
        $miBits = ($data & 0xFFFFFFFFFFFFFF00) >> (8 - $br->getCurrentBit());
82 4
        $loBits = ($data & $loMask);
83 4
        $br->setNextByte($data & 0xFF);
84
85 4
        return $hiBits | $miBits | $loBits;
86
    }
87
88
    /**
89
     * @param string $endianBig
90
     */
91 1
    public function setEndianBig($endianBig)
92
    {
93 1
        $this->endianBig = $endianBig;
94 1
    }
95
96
    /**
97
     * @return string
98
     */
99 1
    public function getEndianBig()
100
    {
101 1
        return $this->endianBig;
102
    }
103
104
    /**
105
     * @param string $endianLittle
106
     */
107 1
    public function setEndianLittle($endianLittle)
108
    {
109 1
        $this->endianLittle = $endianLittle;
110 1
    }
111
112
    /**
113
     * @return string
114
     */
115 1
    public function getEndianLittle()
116
    {
117 1
        return $this->endianLittle;
118
    }
119
}
120