Completed
Push — master ( 569d13...84f4c4 )
by Camilo
17s queued 10s
created

ReadableContent::performSpecialActions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace unreal4u\MQTT\Internals;
6
7
use unreal4u\MQTT\Exceptions\InvalidResponseType;
8
use unreal4u\MQTT\Utilities;
9
use function ord;
10
use function strlen;
11
12
/**
13
 * Trait ReadableContent
14
 * @package unreal4u\MQTT\Internals
15
 */
16
trait ReadableContent
17
{
18
    /**
19
     * Length of variable header
20
     * @var int
21
     */
22
    protected $variableHeaderSize = 0;
23
24
    /**
25
     * The remaining length field may be from 1 to 4 bytes long, this field will represent that offset
26
     * @var int
27
     */
28
    private $sizeOfRemainingLengthField = 1;
29
30
    /**
31
     * @param string $rawMQTTHeaders
32
     * @param ClientInterface $client
33
     * @return bool
34
     * @throws InvalidResponseType
35
     */
36 8
    final public function instantiateObject(string $rawMQTTHeaders, ClientInterface $client): bool
37
    {
38
        //var_dump(base64_encode($rawMQTTHeaders)); // Make it a bit easier to create unit tests
39 8
        $this->checkControlPacketValue(ord($rawMQTTHeaders[0]) >> 4);
40 7
        $this->fillObject($rawMQTTHeaders, $client);
41
42 7
        return true;
43
    }
44
45
    /**
46
     * Checks whether the control packet corresponds to this object
47
     *
48
     * @param int $controlPacketValue
49
     * @return bool
50
     * @throws InvalidResponseType
51
     */
52 8
    private function checkControlPacketValue(int $controlPacketValue): bool
53
    {
54
        // Check whether the first byte corresponds to the expected control packet value
55 8
        if (static::CONTROL_PACKET_VALUE !== $controlPacketValue) {
0 ignored issues
show
Bug introduced by
The constant unreal4u\MQTT\Internals\...t::CONTROL_PACKET_VALUE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
56 1
            throw new InvalidResponseType(sprintf(
57 1
                'Value of received value does not correspond to response (Expected: %d, Actual: %d)',
58 1
                static::CONTROL_PACKET_VALUE,
59 1
                $controlPacketValue
60
            ));
61
        }
62
63 7
        return true;
64
    }
65
66
    /**
67
     * Returns the correct format for the length in bytes of the remaining bytes
68
     *
69
     * @param ClientInterface $client
70
     * @param string $rawMQTTHeaders
71
     * @return int
72
     */
73 15
    private function performRemainingLengthFieldOperations(
74
        string &$rawMQTTHeaders,
75
        ClientInterface $client
76
    ): int {
77
        // Early return: assume defaults if first digit has a value under 128, no further need for complex checks
78 15
        if (ord($rawMQTTHeaders{1}) < 128) {
79 11
            return ord($rawMQTTHeaders{1});
80
        }
81
82
        // If we have less than 4 bytes now, we should really try to recover the rest of the remaining field data
83 4
        if (strlen($rawMQTTHeaders) < 4) {
84
            // At this point we could actually read at least 128 as a minimum, but restrict it to what we need right now
85 1
            $rawMQTTHeaders .= $client->readBrokerData(4 - strlen($rawMQTTHeaders));
86
        }
87
88 4
        $remainingBytes = Utilities::convertRemainingLengthStringToInt(substr($rawMQTTHeaders, 1, 4));
89
90
        // Estimate how much longer is the remaining length field, this will also set $this->sizeOfRemainingLengthField
91 4
        $this->calculateSizeOfRemainingLengthField($remainingBytes);
92 4
        return $remainingBytes;
93
    }
94
95
    /**
96
     * Sets the offset of the remaining length field
97
     *
98
     * @param int $size
99
     * @return int
100
     */
101 13
    private function calculateSizeOfRemainingLengthField(int $size): int
102
    {
103 13
        $blockSize = $iterations = 0;
104 13
        while ($size >= $blockSize) {
105 13
            $iterations++;
106 13
            $blockSize = 128 ** $iterations;
107
        }
108
109 13
        $this->sizeOfRemainingLengthField = $iterations;
110 13
        return $iterations;
111
    }
112
113
    /**
114
     * All classes must implement how to handle the object filling
115
     * @param string $rawMQTTHeaders
116
     * @param ClientInterface $client
117
     * @return ReadableContentInterface
118
     */
119
    abstract public function fillObject(string $rawMQTTHeaders, ClientInterface $client): ReadableContentInterface;
120
121
    /**
122
     * Any class can overwrite the default behaviour
123
     * @param ClientInterface $client
124
     * @param WritableContentInterface $originalRequest
125
     * @return bool
126
     */
127 1
    public function performSpecialActions(ClientInterface $client, WritableContentInterface $originalRequest): bool
0 ignored issues
show
Unused Code introduced by
The parameter $originalRequest is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

127
    public function performSpecialActions(ClientInterface $client, /** @scrutinizer ignore-unused */ WritableContentInterface $originalRequest): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $client is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

127
    public function performSpecialActions(/** @scrutinizer ignore-unused */ ClientInterface $client, WritableContentInterface $originalRequest): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
128
    {
129 1
        return false;
130
    }
131
}
132