Lines
100.00%
16 / 16
Functions and Methods
100.00%
8 / 8
Classes and Traits
100.00%
1 / 1
| Name | Lines | Functions and Methods | CRAP | Classes and Traits | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| PacketBodyReader | 100.00% | 16 / 16 | 100.00% | 8 / 8 | 12 | 100.00% | 1 / 1 | |||
| __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 | |||||
| 1 | <?php | |
| 2 | ||
| 3 | declare(strict_types=1); | |
| 4 | ||
| 5 | namespace Stewart\Mqtt\Packet; | |
| 6 | ||
| 7 | use Stewart\Mqtt\Exception\MqttClientException; | |
| 8 | ||
| 9 | final 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 | } |