Lines 100.00% 16 / 16
Methods 100.00% 8 / 8
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 readUint8 100.00% 1 / 1 100.00% 1 / 1 1
 readUint16 100.00% 2 / 2 100.00% 1 / 1 3
 readString 100.00% 1 / 1 100.00% 1 / 1 1
 readRemainder 100.00% 3 / 3 100.00% 1 / 1 1
 assertFullyRead 100.00% 2 / 2 100.00% 1 / 1 2
 createMalformedException 100.00% 1 / 1 100.00% 1 / 1 1
 readBytes 100.00% 5 / 5 100.00% 1 / 1 2
9final class PacketBodyReader
10{
11    private int $offset = 0;
12
13    public function __construct(
14        private readonly PacketType $type,
15        private readonly string $body,
16    ) {}
17
18    /** @throws MqttClientException */
19    public function readUint8(): int
20    {
21        return \ord($this->readBytes(1));
22    }
23
24    /** @throws MqttClientException */
25    public function readUint16(): int
26    {
27        $unpacked = unpack('n', $this->readBytes(2));
28
29        return \is_array($unpacked) && \is_int($unpacked[1] ?? null) ? $unpacked[1] : throw $this->createMalformedException();
30    }
31
32    /** @throws MqttClientException */
33    public function readString(): string
34    {
35        return $this->readBytes($this->readUint16());
36    }
37
38    public function readRemainder(): string
39    {
40        $remainder = substr($this->body, $this->offset);
41        $this->offset = \strlen($this->body);
42
43        return $remainder;
44    }
45
46    /** @throws MqttClientException */
47    public function assertFullyRead(): void
48    {
49        if ($this->offset !== \strlen($this->body)) {
50            throw $this->createMalformedException();
51        }
52    }
53
54    public function createMalformedException(): MqttClientException
55    {
56        return MqttClientException::packetMalformed($this->type->name);
57    }
58
59    /** @throws MqttClientException */
60    private function readBytes(int $length): string
61    {
62        if ($this->offset + $length > \strlen($this->body)) {
63            throw $this->createMalformedException();
64        }
65
66        $bytes = substr($this->body, $this->offset, $length);
67        $this->offset += $length;
68
69        return $bytes;
70    }
71}