FloatingPoint::newOffset()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 1
c 1
b 0
f 1
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PBurggraf\BinaryUtilities\DataType;
6
7
use PBurggraf\BinaryUtilities\Exception\EndOfFileReachedException;
8
use PBurggraf\BinaryUtilities\Exception\InvalidByteSequenceException;
9
10
/**
11
 * @author Philip Burggraf <[email protected]>
12
 */
13
class FloatingPoint extends AbstractDataType
14
{
15
    /**
16
     * @throws EndOfFileReachedException
17
     * @throws InvalidByteSequenceException
18
     *
19
     * @return array
20
     */
21
    public function read(): array
22
    {
23
        $bytes = [];
24
25
        $this->assertNotEndOfFile();
26
        $bytes[] = $this->getByte($this->offset++);
27
        $this->assertNotEndOfFile();
28
        $bytes[] = $this->getByte($this->offset++);
29
        $this->assertNotEndOfFile();
30
        $bytes[] = $this->getByte($this->offset++);
31
        $this->assertNotEndOfFile();
32
        $bytes[] = $this->getByte($this->offset++);
33
34
        $data = $this->endianMode->applyEndianess($bytes);
35
36
        return [
37
            $this->mergeBytes($data),
38
        ];
39
    }
40
41
    /**
42
     * @param int $length
43
     *
44
     * @throws EndOfFileReachedException
45
     * @throws InvalidByteSequenceException
46
     *
47
     * @return array
48
     */
49
    public function readArray(int $length): array
50
    {
51
        $buffer = [];
52
53
        for ($iterator = 0; $iterator < $length; ++$iterator) {
54
            $bytes = [];
55
56
            $this->assertNotEndOfFile();
57
            $bytes[] = $this->getByte($this->offset++);
58
            $this->assertNotEndOfFile();
59
            $bytes[] = $this->getByte($this->offset++);
60
            $this->assertNotEndOfFile();
61
            $bytes[] = $this->getByte($this->offset++);
62
            $this->assertNotEndOfFile();
63
            $bytes[] = $this->getByte($this->offset++);
64
65
            $data = $this->endianMode->applyEndianess($bytes);
66
67
            $buffer[] = $this->mergeBytes($data);
68
        }
69
70
        return $buffer;
71
    }
72
73
    /**
74
     * @param array $data
75
     *
76
     * @throws InvalidByteSequenceException
77
     *
78
     * @return float
79
     */
80
    private function mergeBytes(array $data): float
81
    {
82
        $string = hex2bin(str_pad(dechex($data[0]), 2, '0', STR_PAD_LEFT) . str_pad(dechex($data[1]), 2, '0', STR_PAD_LEFT) . str_pad(dechex($data[2]), 2, '0', STR_PAD_LEFT) . str_pad(dechex($data[3]), 2, '0', STR_PAD_LEFT));
83
84
        $result = unpack('G', $string);
85
86
        if (is_array($result) === false) {
87
            throw new InvalidByteSequenceException();
88
        }
89
90
        return $result[1];
91
    }
92
93
    /**
94
     * @param float|int $data
95
     *
96
     * @throws EndOfFileReachedException
97
     */
98
    public function write($data): void
99
    {
100
        $bytes = $this->splitBytes($data);
101
102
        $bytes = $this->endianMode->applyEndianess($bytes);
103
104
        $this->assertNotEndOfFile();
105
        $this->setByte($this->offset++, $bytes[0]);
106
107
        $this->assertNotEndOfFile();
108
        $this->setByte($this->offset++, $bytes[1]);
109
110
        $this->assertNotEndOfFile();
111
        $this->setByte($this->offset++, $bytes[2]);
112
113
        $this->assertNotEndOfFile();
114
        $this->setByte($this->offset++, $bytes[3]);
115
    }
116
117
    /**
118
     * @param array $data
119
     *
120
     * @throws EndOfFileReachedException
121
     */
122
    public function writeArray(array $data): void
123
    {
124
        $dataLength = count($data);
125
        $startBytePosition = $this->offset;
126
127
        for ($i = $startBytePosition; $i <= $startBytePosition - 1 + $dataLength; ++$i) {
128
            $bytes = $this->splitBytes($data[$i - $startBytePosition]);
129
130
            $bytes = $this->endianMode->applyEndianess($bytes);
131
132
            $this->assertNotEndOfFile();
133
            $this->setByte($this->offset++, $bytes[0]);
134
135
            $this->assertNotEndOfFile();
136
            $this->setByte($this->offset++, $bytes[1]);
137
138
            $this->assertNotEndOfFile();
139
            $this->setByte($this->offset++, $bytes[2]);
140
141
            $this->assertNotEndOfFile();
142
            $this->setByte($this->offset++, $bytes[3]);
143
        }
144
    }
145
146
    /**
147
     * @param float|int $data
148
     *
149
     * @return array
150
     */
151
    public function splitBytes($data): array
152
    {
153
        $data = hexdec(bin2hex(pack('G', $data)));
154
155
        $bytes = [];
156
157
        $bytes[] = ($data & 0xff000000) >> 24;
158
        $bytes[] = ($data & 0x00ff0000) >> 16;
159
        $bytes[] = ($data & 0x0000ff00) >> 8;
160
        $bytes[] = ($data & 0x000000ff);
161
162
        return $bytes;
163
    }
164
165
    /**
166
     * @return string
167
     */
168
    public function newContent(): string
169
    {
170
        return $this->content;
171
    }
172
173
    /**
174
     * @return int
175
     */
176
    public function newOffset(): int
177
    {
178
        return $this->offset;
179
    }
180
}
181