Passed
Push — master ( 487089...443b76 )
by Chris
03:30
created

MessageDecoder   B

Complexity

Total Complexity 52

Size/Duplication

Total Lines 532
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 532
ccs 0
cts 334
cp 0
rs 7.9487
c 0
b 0
f 0
wmc 52

44 Methods

Rating   Name   Duplication   Size   Complexity  
A decodeGetLabel() 0 3 1
A decodeEchoResponse() 0 3 1
A decodeGetGroup() 0 3 1
A decodeGet() 0 3 1
A decodeSetLightPower() 0 8 1
A decodeGetWifiInfo() 0 3 1
A decodeSetLabel() 0 3 1
A decodeStateHostInfo() 0 9 1
A decodeStateInfrared() 0 5 1
A decodeAcknowledgement() 0 3 1
A decodeStateGroup() 0 13 1
A decodeGetLocation() 0 3 1
A decodeGetLightPower() 0 3 1
A decodeStateVersion() 0 9 1
A decodeStateHostFirmware() 0 10 1
A decodeStateDevicePower() 0 5 1
A decodeGetDevicePower() 0 3 1
A decodeSetDevicePower() 0 5 1
B decodeSetWaveformOptional() 0 36 5
A decodeGetService() 0 3 1
A decodeStateLightPower() 0 5 1
A decodeStateService() 0 8 1
A decodeGetInfrared() 0 3 1
A decodeStateLabel() 0 3 1
A decodeState() 0 15 1
A decodeGetInfo() 0 3 1
A decodeStateInfo() 0 11 1
A decodeSetGroup() 0 13 1
B decodeSetWaveform() 0 26 1
A decodeGetHostFirmware() 0 3 1
A __construct() 0 3 1
A decodeSetColor() 0 13 1
A decodeMessage() 0 19 4
A decodeGetHostInfo() 0 3 1
A decodeSetLocation() 0 13 1
A decodeSetInfrared() 0 5 1
A unsignedShortToSignedShort() 0 7 2
A decodeGetWifiFirmware() 0 3 1
A nanotimeToDateTimeImmutable() 0 6 1
A decodeStateWifiFirmware() 0 10 1
A decodeEchoRequest() 0 3 1
A decodeStateWifiInfo() 0 10 1
A decodeGetVersion() 0 3 1
A decodeStateLocation() 0 13 1

How to fix   Complexity   

Complex Class

Complex classes like MessageDecoder often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MessageDecoder, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
3
namespace DaveRandom\LibLifxLan\Decoding;
4
5
use DaveRandom\LibLifxLan\DataTypes as DeviceDataTypes;
6
use DaveRandom\LibLifxLan\DataTypes\Light as LightDataTypes;
7
use DaveRandom\LibLifxLan\Decoding\Exceptions\DecodingException;
8
use DaveRandom\LibLifxLan\Decoding\Exceptions\InvalidMessagePayloadLengthException;
9
use DaveRandom\LibLifxLan\Decoding\Exceptions\MalformedMessagePayloadException;
10
use DaveRandom\LibLifxLan\Exceptions\InvalidValueException;
11
use DaveRandom\LibLifxLan\Messages\Device\Commands as DeviceCommands;
12
use DaveRandom\LibLifxLan\Messages\Device\Requests as DeviceRequests;
13
use DaveRandom\LibLifxLan\Messages\Device\Responses as DeviceResponses;
14
use DaveRandom\LibLifxLan\Messages\Light\Commands as LightCommmands;
15
use DaveRandom\LibLifxLan\Messages\Light\Requests as LightRequests;
16
use DaveRandom\LibLifxLan\Messages\Light\Responses as LightResponses;
17
use DaveRandom\LibLifxLan\Messages\Message;
18
use DaveRandom\LibLifxLan\Messages\UnknownMessage;
19
use Ramsey\Uuid\UuidFactory;
20
use Ramsey\Uuid\UuidFactoryInterface;
21
22
final class MessageDecoder
23
{
24
    private const HSBK_FORMAT = 'vhue/vsaturation/vbrightness/vtemperature';
25
26
    /**
27
     * @uses decodeAcknowledgement
28
     * @uses decodeEchoRequest
29
     * @uses decodeEchoResponse
30
     * @uses decodeGetGroup
31
     * @uses decodeSetGroup
32
     * @uses decodeStateGroup
33
     * @uses decodeGetHostFirmware
34
     * @uses decodeStateHostFirmware
35
     * @uses decodeGetHostInfo
36
     * @uses decodeStateHostInfo
37
     * @uses decodeGetInfo
38
     * @uses decodeStateInfo
39
     * @uses decodeGetLabel
40
     * @uses decodeSetLabel
41
     * @uses decodeStateLabel
42
     * @uses decodeGetLocation
43
     * @uses decodeSetLocation
44
     * @uses decodeStateLocation
45
     * @uses decodeGetDevicePower
46
     * @uses decodeSetDevicePower
47
     * @uses decodeStateDevicePower
48
     * @uses decodeGetService
49
     * @uses decodeStateService
50
     * @uses decodeGetVersion
51
     * @uses decodeStateVersion
52
     * @uses decodeGetWifiFirmware
53
     * @uses decodeStateWifiFirmware
54
     * @uses decodeGetWifiInfo
55
     * @uses decodeStateWifiInfo
56
     * @uses decodeGet
57
     * @uses decodeSetColor
58
     * @uses decodeSetWaveform
59
     * @uses decodeSetWaveformOptional
60
     * @uses decodeState
61
     * @uses decodeGetInfrared
62
     * @uses decodeSetInfrared
63
     * @uses decodeStateInfrared
64
     * @uses decodeGetLightPower
65
     * @uses decodeSetLightPower
66
     * @uses decodeStateLightPower
67
     */
68
    private const MESSAGE_INFO = [
69
        // Device command messages
70
        DeviceCommands\SetGroup::MESSAGE_TYPE_ID => [DeviceCommands\SetGroup::WIRE_SIZE, 'SetGroup'],
71
        DeviceCommands\SetLabel::MESSAGE_TYPE_ID => [DeviceCommands\SetLabel::WIRE_SIZE, 'SetLabel'],
72
        DeviceCommands\SetLocation::MESSAGE_TYPE_ID => [DeviceCommands\SetLocation::WIRE_SIZE, 'SetLocation'],
73
        DeviceCommands\SetPower::MESSAGE_TYPE_ID => [DeviceCommands\SetPower::WIRE_SIZE, 'SetDevicePower'],
74
75
        // Device request messages
76
        DeviceRequests\EchoRequest::MESSAGE_TYPE_ID => [DeviceRequests\EchoRequest::WIRE_SIZE, 'EchoRequest'],
77
        DeviceRequests\GetGroup::MESSAGE_TYPE_ID => [DeviceRequests\GetGroup::WIRE_SIZE, 'GetGroup'],
78
        DeviceRequests\GetHostFirmware::MESSAGE_TYPE_ID => [DeviceRequests\GetHostFirmware::WIRE_SIZE, 'GetHostFirmware'],
79
        DeviceRequests\GetHostInfo::MESSAGE_TYPE_ID => [DeviceRequests\GetHostInfo::WIRE_SIZE, 'GetHostInfo'],
80
        DeviceRequests\GetInfo::MESSAGE_TYPE_ID => [DeviceRequests\GetInfo::WIRE_SIZE, 'GetInfo'],
81
        DeviceRequests\GetLabel::MESSAGE_TYPE_ID => [DeviceRequests\GetLabel::WIRE_SIZE, 'GetLabel'],
82
        DeviceRequests\GetLocation::MESSAGE_TYPE_ID => [DeviceRequests\GetLocation::WIRE_SIZE, 'GetLocation'],
83
        DeviceRequests\GetPower::MESSAGE_TYPE_ID => [DeviceRequests\GetPower::WIRE_SIZE, 'GetDevicePower'],
84
        DeviceRequests\GetService::MESSAGE_TYPE_ID => [DeviceRequests\GetService::WIRE_SIZE, 'GetService'],
85
        DeviceRequests\GetVersion::MESSAGE_TYPE_ID => [DeviceRequests\GetVersion::WIRE_SIZE, 'GetVersion'],
86
        DeviceRequests\GetWifiFirmware::MESSAGE_TYPE_ID => [DeviceRequests\GetWifiFirmware::WIRE_SIZE, 'GetWifiFirmware'],
87
        DeviceRequests\GetWifiInfo::MESSAGE_TYPE_ID => [DeviceRequests\GetWifiInfo::WIRE_SIZE, 'GetWifiInfo'],
88
89
        // Device response messages
90
        DeviceResponses\Acknowledgement::MESSAGE_TYPE_ID => [DeviceResponses\Acknowledgement::WIRE_SIZE, 'Acknowledgement'],
91
        DeviceResponses\EchoResponse::MESSAGE_TYPE_ID => [DeviceResponses\EchoResponse::WIRE_SIZE, 'EchoResponse'],
92
        DeviceResponses\StateGroup::MESSAGE_TYPE_ID => [DeviceResponses\StateGroup::WIRE_SIZE, 'StateGroup'],
93
        DeviceResponses\StateHostFirmware::MESSAGE_TYPE_ID => [DeviceResponses\StateHostFirmware::WIRE_SIZE, 'StateHostFirmware'],
94
        DeviceResponses\StateHostInfo::MESSAGE_TYPE_ID => [DeviceResponses\StateHostInfo::WIRE_SIZE, 'StateHostInfo'],
95
        DeviceResponses\StateInfo::MESSAGE_TYPE_ID => [DeviceResponses\StateInfo::WIRE_SIZE, 'StateInfo'],
96
        DeviceResponses\StateLabel::MESSAGE_TYPE_ID => [DeviceResponses\StateLabel::WIRE_SIZE, 'StateLabel'],
97
        DeviceResponses\StateLocation::MESSAGE_TYPE_ID => [DeviceResponses\StateLocation::WIRE_SIZE, 'StateLocation'],
98
        DeviceResponses\StatePower::MESSAGE_TYPE_ID => [DeviceResponses\StatePower::WIRE_SIZE, 'StateDevicePower'],
99
        DeviceResponses\StateService::MESSAGE_TYPE_ID => [DeviceResponses\StateService::WIRE_SIZE, 'StateService'],
100
        DeviceResponses\StateVersion::MESSAGE_TYPE_ID => [DeviceResponses\StateVersion::WIRE_SIZE, 'StateVersion'],
101
        DeviceResponses\StateWifiFirmware::MESSAGE_TYPE_ID => [DeviceResponses\StateWifiFirmware::WIRE_SIZE, 'StateWifiFirmware'],
102
        DeviceResponses\StateWifiInfo::MESSAGE_TYPE_ID => [DeviceResponses\StateWifiInfo::WIRE_SIZE, 'StateWifiInfo'],
103
104
        // Light command messages
105
        LightCommmands\SetColor::MESSAGE_TYPE_ID => [LightCommmands\SetColor::WIRE_SIZE, 'SetColor'],
106
        LightCommmands\SetInfrared::MESSAGE_TYPE_ID => [LightCommmands\SetInfrared::WIRE_SIZE, 'SetInfrared'],
107
        LightCommmands\SetPower::MESSAGE_TYPE_ID => [LightCommmands\SetPower::WIRE_SIZE, 'SetLightPower'],
108
        LightCommmands\SetWaveform::MESSAGE_TYPE_ID => [LightCommmands\SetWaveform::WIRE_SIZE, 'SetWaveform'],
109
        LightCommmands\SetWaveformOptional::MESSAGE_TYPE_ID => [LightCommmands\SetWaveformOptional::WIRE_SIZE, 'SetWaveformOptional'],
110
111
        // Light request messages
112
        LightRequests\Get::MESSAGE_TYPE_ID => [LightRequests\Get::WIRE_SIZE, 'Get'],
113
        LightRequests\GetInfrared::MESSAGE_TYPE_ID => [LightRequests\GetInfrared::WIRE_SIZE, 'GetInfrared'],
114
        LightRequests\GetPower::MESSAGE_TYPE_ID => [LightRequests\GetPower::WIRE_SIZE, 'GetLightPower'],
115
116
        // Light response messages
117
        LightResponses\State::MESSAGE_TYPE_ID => [LightResponses\State::WIRE_SIZE, 'State'],
118
        LightResponses\StateInfrared::MESSAGE_TYPE_ID => [LightResponses\StateInfrared::WIRE_SIZE, 'StateInfrared'],
119
        LightResponses\StatePower::MESSAGE_TYPE_ID => [LightResponses\StatePower::WIRE_SIZE, 'StateLightPower'],
120
    ];
121
122
    private $uuidFactory;
123
124
    private function unsignedShortToSignedShort(int $unsigned): int
125
    {
126
        if (!($unsigned & 0x8000)) {
127
            return $unsigned;
128
        }
129
130
        return -(($unsigned & 0x7fff) + 1);
131
    }
132
133
    private function nanotimeToDateTimeImmutable(int $timestamp): \DateTimeImmutable
134
    {
135
        $usecs = (int)(($timestamp % 1000000000) / 1000);
136
        $secs = (int)($timestamp / 1000000000);
137
138
        return \DateTimeImmutable::createFromFormat('u U', \sprintf("%06d %d", $usecs, $secs));
0 ignored issues
show
Bug introduced by
The call to DateTimeImmutable::createFromFormat() has too few arguments starting with timezone. ( Ignorable by Annotation )

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

138
        return \DateTimeImmutable::/** @scrutinizer ignore-call */ createFromFormat('u U', \sprintf("%06d %d", $usecs, $secs));

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug Best Practice introduced by
The expression return DateTimeImmutable...6d %d', $usecs, $secs)) could return the type false which is incompatible with the type-hinted return DateTimeImmutable. Consider adding an additional type-check to rule them out.
Loading history...
139
    }
140
141
    private function decodeAcknowledgement(): DeviceResponses\Acknowledgement
1 ignored issue
show
Unused Code introduced by
The method decodeAcknowledgement() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
142
    {
143
        return new DeviceResponses\Acknowledgement();
144
    }
145
146
    private function decodeEchoRequest(string $data): DeviceRequests\EchoRequest
1 ignored issue
show
Unused Code introduced by
The method decodeEchoRequest() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
147
    {
148
        return new DeviceRequests\EchoRequest($data);
149
    }
150
151
    private function decodeEchoResponse(string $data): DeviceResponses\EchoResponse
1 ignored issue
show
Unused Code introduced by
The method decodeEchoResponse() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
152
    {
153
        return new DeviceResponses\EchoResponse($data);
154
    }
155
156
    private function decodeGetGroup(): DeviceRequests\GetGroup
1 ignored issue
show
Unused Code introduced by
The method decodeGetGroup() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
157
    {
158
        return new DeviceRequests\GetGroup;
159
    }
160
161
    private function decodeSetGroup(string $data): DeviceCommands\SetGroup
1 ignored issue
show
Unused Code introduced by
The method decodeSetGroup() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
162
    {
163
        [
164
            'guid'    => $guid,
165
            'label'   => $label,
166
            'updated' => $updatedAt,
167
        ] = \unpack('a16guid/a32label/Pupdated', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

167
        ] = /** @scrutinizer ignore-call */ \unpack('a16guid/a32label/Pupdated', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
168
169
        $guid = $this->uuidFactory->fromBytes($guid);
170
        $updatedAt = $this->nanotimeToDateTimeImmutable($updatedAt);
171
        $label = new DeviceDataTypes\Label(\rtrim($label, "\x00"));
172
173
        return new DeviceCommands\SetGroup(new DeviceDataTypes\Group($guid, $label, $updatedAt));
174
    }
175
176
    private function decodeStateGroup(string $data): DeviceResponses\StateGroup
1 ignored issue
show
Unused Code introduced by
The method decodeStateGroup() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
177
    {
178
        [
179
            'guid'    => $guid,
180
            'label'   => $label,
181
            'updated' => $updatedAt,
182
        ] = \unpack('a16guid/a32label/Pupdated', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

182
        ] = /** @scrutinizer ignore-call */ \unpack('a16guid/a32label/Pupdated', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
183
184
        $guid = $this->uuidFactory->fromBytes($guid);
185
        $updatedAt = $this->nanotimeToDateTimeImmutable($updatedAt);
186
        $label = new DeviceDataTypes\Label(\rtrim($label, "\x00"));
187
188
        return new DeviceResponses\StateGroup(new DeviceDataTypes\Group($guid, $label, $updatedAt));
189
    }
190
191
    private function decodeGetHostFirmware(): DeviceRequests\GetHostFirmware
1 ignored issue
show
Unused Code introduced by
The method decodeGetHostFirmware() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
192
    {
193
        return new DeviceRequests\GetHostFirmware;
194
    }
195
196
    private function decodeStateHostFirmware(string $data): DeviceResponses\StateHostFirmware
1 ignored issue
show
Unused Code introduced by
The method decodeStateHostFirmware() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
197
    {
198
        [
199
            'build'    => $build,
200
            'version'  => $version,
201
        ] = \unpack('Pbuild/Preserved/Vversion', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

201
        ] = /** @scrutinizer ignore-call */ \unpack('Pbuild/Preserved/Vversion', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
202
203
        $build = $this->nanotimeToDateTimeImmutable($build);
204
205
        return new DeviceResponses\StateHostFirmware(new DeviceDataTypes\HostFirmware($build, $version));
206
    }
207
208
    private function decodeGetHostInfo(): DeviceRequests\GetHostInfo
1 ignored issue
show
Unused Code introduced by
The method decodeGetHostInfo() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
209
    {
210
        return new DeviceRequests\GetHostInfo;
211
    }
212
213
    /**
214
     * @param string $data
215
     * @return DeviceResponses\StateHostInfo
216
     */
217
    private function decodeStateHostInfo(string $data): DeviceResponses\StateHostInfo
1 ignored issue
show
Unused Code introduced by
The method decodeStateHostInfo() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
218
    {
219
        [
220
            'signal'   => $signal,
221
            'tx'       => $tx,
222
            'rx'       => $rx,
223
        ] = \unpack(\DaveRandom\LibLifxLan\FLOAT32_CODE . 'signal/Vtx/Vrx/vreserved', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

223
        ] = /** @scrutinizer ignore-call */ \unpack(\DaveRandom\LibLifxLan\FLOAT32_CODE . 'signal/Vtx/Vrx/vreserved', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
224
225
        return new DeviceResponses\StateHostInfo(new DeviceDataTypes\HostInfo($signal, $tx, $rx));
226
    }
227
228
    private function decodeGetInfo(): DeviceRequests\GetInfo
1 ignored issue
show
Unused Code introduced by
The method decodeGetInfo() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
229
    {
230
        return new DeviceRequests\GetInfo;
231
    }
232
233
    private function decodeStateInfo(string $data): DeviceResponses\StateInfo
1 ignored issue
show
Unused Code introduced by
The method decodeStateInfo() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
234
    {
235
        [
236
            'time'     => $time,
237
            'uptime'   => $uptime,
238
            'downtime' => $downtime,
239
        ] = \unpack('Ptime/Puptime/Pdowntime', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

239
        ] = /** @scrutinizer ignore-call */ \unpack('Ptime/Puptime/Pdowntime', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
240
241
        $time = $this->nanotimeToDateTimeImmutable($time);
242
243
        return new DeviceResponses\StateInfo(new DeviceDataTypes\TimeInfo($time, $uptime, $downtime));
244
    }
245
246
    private function decodeGetLabel(): DeviceRequests\GetLabel
1 ignored issue
show
Unused Code introduced by
The method decodeGetLabel() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
247
    {
248
        return new DeviceRequests\GetLabel;
249
    }
250
251
    private function decodeSetLabel(string $data): DeviceCommands\SetLabel
1 ignored issue
show
Unused Code introduced by
The method decodeSetLabel() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
252
    {
253
        return new DeviceCommands\SetLabel(new DeviceDataTypes\Label(\rtrim($data, "\x00")));
254
    }
255
256
    private function decodeStateLabel(string $data): DeviceResponses\StateLabel
1 ignored issue
show
Unused Code introduced by
The method decodeStateLabel() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
257
    {
258
        return new DeviceResponses\StateLabel(new DeviceDataTypes\Label(\rtrim($data, "\x00")));
259
    }
260
261
    private function decodeGetLocation(): DeviceRequests\GetLocation
1 ignored issue
show
Unused Code introduced by
The method decodeGetLocation() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
262
    {
263
        return new DeviceRequests\GetLocation;
264
    }
265
266
    private function decodeSetLocation(string $data): DeviceCommands\SetLocation
1 ignored issue
show
Unused Code introduced by
The method decodeSetLocation() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
267
    {
268
        [
269
            'guid'    => $guid,
270
            'label'   => $label,
271
            'updated' => $updatedAt,
272
        ] = \unpack('a16guid/a32label/Pupdated', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

272
        ] = /** @scrutinizer ignore-call */ \unpack('a16guid/a32label/Pupdated', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
273
274
        $guid = $this->uuidFactory->fromBytes($guid);
275
        $updatedAt = $this->nanotimeToDateTimeImmutable($updatedAt);
276
        $label = new DeviceDataTypes\Label(\rtrim($label, "\x00"));
277
278
        return new DeviceCommands\SetLocation(new DeviceDataTypes\Location($guid, $label, $updatedAt));
279
    }
280
281
    private function decodeStateLocation(string $data): DeviceResponses\StateLocation
1 ignored issue
show
Unused Code introduced by
The method decodeStateLocation() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
282
    {
283
        [
284
            'guid'    => $guid,
285
            'label'   => $label,
286
            'updated' => $updatedAt,
287
        ] = \unpack('a16guid/a32label/Pupdated', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

287
        ] = /** @scrutinizer ignore-call */ \unpack('a16guid/a32label/Pupdated', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
288
289
        $guid = $this->uuidFactory->fromBytes($guid);
290
        $updatedAt = $this->nanotimeToDateTimeImmutable($updatedAt);
291
        $label = new DeviceDataTypes\Label(\rtrim($label, "\x00"));
292
293
        return new DeviceResponses\StateLocation(new DeviceDataTypes\Location($guid, $label, $updatedAt));
294
    }
295
296
    private function decodeGetDevicePower(): DeviceRequests\GetPower
1 ignored issue
show
Unused Code introduced by
The method decodeGetDevicePower() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
297
    {
298
        return new DeviceRequests\GetPower;
299
    }
300
301
    private function decodeSetDevicePower(string $data): DeviceCommands\SetPower
1 ignored issue
show
Unused Code introduced by
The method decodeSetDevicePower() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
302
    {
303
        $level = \unpack('vlevel', $data)['level'];
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

303
        $level = /** @scrutinizer ignore-call */ \unpack('vlevel', $data)['level'];

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
304
305
        return new DeviceCommands\SetPower($level);
306
    }
307
308
    private function decodeStateDevicePower(string $data): DeviceResponses\StatePower
1 ignored issue
show
Unused Code introduced by
The method decodeStateDevicePower() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
309
    {
310
        $level = \unpack('vlevel', $data)['level'];
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

310
        $level = /** @scrutinizer ignore-call */ \unpack('vlevel', $data)['level'];

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
311
312
        return new DeviceResponses\StatePower($level);
313
    }
314
315
    private function decodeGetService(): DeviceRequests\GetService
1 ignored issue
show
Unused Code introduced by
The method decodeGetService() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
316
    {
317
        return new DeviceRequests\GetService;
318
    }
319
320
    private function decodeStateService(string $data): DeviceResponses\StateService
1 ignored issue
show
Unused Code introduced by
The method decodeStateService() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
321
    {
322
        [
323
            'serviceType' => $serviceType,
324
            'port' => $port,
325
        ] = \unpack('CserviceType/Vport', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

325
        ] = /** @scrutinizer ignore-call */ \unpack('CserviceType/Vport', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
326
327
        return new DeviceResponses\StateService(new DeviceDataTypes\Service($serviceType, $port));
328
    }
329
330
    private function decodeGetVersion(): DeviceRequests\GetVersion
1 ignored issue
show
Unused Code introduced by
The method decodeGetVersion() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
331
    {
332
        return new DeviceRequests\GetVersion;
333
    }
334
335
    private function decodeStateVersion(string $data): DeviceResponses\StateVersion
1 ignored issue
show
Unused Code introduced by
The method decodeStateVersion() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
336
    {
337
        [
338
            'vendor'  => $vendor,
339
            'product' => $product,
340
            'version' => $version,
341
        ] = \unpack('Vvendor/Vproduct/Vversion', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

341
        ] = /** @scrutinizer ignore-call */ \unpack('Vvendor/Vproduct/Vversion', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
342
343
        return new DeviceResponses\StateVersion(new DeviceDataTypes\Version($vendor, $product, $version));
344
    }
345
346
    private function decodeGetWifiFirmware(): DeviceRequests\GetWifiFirmware
1 ignored issue
show
Unused Code introduced by
The method decodeGetWifiFirmware() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
347
    {
348
        return new DeviceRequests\GetWifiFirmware;
349
    }
350
351
    private function decodeStateWifiFirmware(string $data): DeviceResponses\StateWifiFirmware
1 ignored issue
show
Unused Code introduced by
The method decodeStateWifiFirmware() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
352
    {
353
        [
354
            'build'    => $build,
355
            'version'  => $version,
356
        ] = \unpack('Pbuild/Preserved/Vversion', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

356
        ] = /** @scrutinizer ignore-call */ \unpack('Pbuild/Preserved/Vversion', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
357
358
        $build = $this->nanotimeToDateTimeImmutable($build);
359
360
        return new DeviceResponses\StateWifiFirmware(new DeviceDataTypes\WifiFirmware($build, $version));
361
    }
362
363
    private function decodeGetWifiInfo(): DeviceRequests\GetWifiInfo
1 ignored issue
show
Unused Code introduced by
The method decodeGetWifiInfo() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
364
    {
365
        return new DeviceRequests\GetWifiInfo;
366
    }
367
368
    private function decodeStateWifiInfo(string $data): DeviceResponses\StateWifiInfo
1 ignored issue
show
Unused Code introduced by
The method decodeStateWifiInfo() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
369
    {
370
371
        [
372
            'signal'   => $signal,
373
            'tx'       => $tx,
374
            'rx'       => $rx,
375
        ] = \unpack(\DaveRandom\LibLifxLan\FLOAT32_CODE . 'signal/Vtx/Vrx/vreserved', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

375
        ] = /** @scrutinizer ignore-call */ \unpack(\DaveRandom\LibLifxLan\FLOAT32_CODE . 'signal/Vtx/Vrx/vreserved', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
376
377
        return new DeviceResponses\StateWifiInfo(new DeviceDataTypes\WifiInfo($signal, $tx, $rx));
378
    }
379
380
    private function decodeGet(): LightRequests\Get
1 ignored issue
show
Unused Code introduced by
The method decodeGet() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
381
    {
382
        return new LightRequests\Get;
383
    }
384
385
    private function decodeSetColor(string $data): LightCommmands\SetColor
1 ignored issue
show
Unused Code introduced by
The method decodeSetColor() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
386
    {
387
        [
388
            'hue'         => $hue,
389
            'saturation'  => $saturation,
390
            'brightness'  => $brightness,
391
            'temperature' => $temperature,
392
            'duration'    => $duration,
393
        ] = \unpack('Creserved/' . self::HSBK_FORMAT . '/Vduration', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

393
        ] = /** @scrutinizer ignore-call */ \unpack('Creserved/' . self::HSBK_FORMAT . '/Vduration', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
394
395
        $color = new LightDataTypes\HsbkColor($hue, $saturation, $brightness, $temperature);
396
397
        return new LightCommmands\SetColor(new LightDataTypes\ColorTransition($color, $duration));
398
    }
399
400
    private function decodeSetWaveform(string $data): LightCommmands\SetWaveform
1 ignored issue
show
Unused Code introduced by
The method decodeSetWaveform() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
401
    {
402
        $format
403
            = 'Creserved/Ctransient/'
404
            . self::HSBK_FORMAT
405
            . '/Vperiod/' . \DaveRandom\LibLifxLan\FLOAT32_CODE . 'cycles/vskewRatio/Cwaveform'
406
        ;
407
408
        [
409
            'transient'   => $transient,
410
            'hue'         => $hue,
411
            'saturation'  => $saturation,
412
            'brightness'  => $brightness,
413
            'temperature' => $temperature,
414
            'period'      => $period,
415
            'cycles'      => $cycles,
416
            'skewRatio'   => $skewRatio,
417
            'waveform'    => $waveform,
418
        ] = \unpack($format, $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

418
        ] = /** @scrutinizer ignore-call */ \unpack($format, $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
419
420
        $color = new LightDataTypes\HsbkColor($hue, $saturation, $brightness, $temperature);
421
422
        $skewRatio = $this->unsignedShortToSignedShort($skewRatio);
423
        $effect = new LightDataTypes\Effect((bool)$transient, $color, $period, $cycles, $skewRatio, $waveform);
424
425
        return new LightCommmands\SetWaveform($effect);
426
    }
427
428
    private function decodeSetWaveformOptional(string $data): LightCommmands\SetWaveformOptional
1 ignored issue
show
Unused Code introduced by
The method decodeSetWaveformOptional() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
429
    {
430
        $format
431
            = 'Creserved/Ctransient/'
432
            . self::HSBK_FORMAT
433
            . '/Vperiod/' . \DaveRandom\LibLifxLan\FLOAT32_CODE . 'cycles/vskewRatio/Cwaveform'
434
            . '/CsetHue/CsetSaturation/CsetBrightness/CsetTemperature'
435
        ;
436
437
        [
438
            'transient'      => $transient,
439
            'hue'            => $hue,
440
            'saturation'     => $saturation,
441
            'brightness'     => $brightness,
442
            'temperature'    => $temperature,
443
            'period'         => $period,
444
            'cycles'         => $cycles,
445
            'skewRatio'      => $skewRatio,
446
            'waveform'       => $waveform,
447
            'setHue'         => $setHue,
448
            'setSaturation'  => $setSaturation,
449
            'setBrightness'  => $setBrightness,
450
            'setTemperature' => $setTemperature,
451
        ] = \unpack($format, $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

451
        ] = /** @scrutinizer ignore-call */ \unpack($format, $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
452
453
        $color = new LightDataTypes\HsbkColor($hue, $saturation, $brightness, $temperature);
454
        $skewRatio = $this->unsignedShortToSignedShort($skewRatio);
455
456
        $options = ($setHue ? LightDataTypes\Effect::SET_HUE : 0)
457
            | ($setSaturation ? LightDataTypes\Effect::SET_SATURATION : 0)
458
            | ($setBrightness ? LightDataTypes\Effect::SET_BRIGHTNESS : 0)
459
            | ($setTemperature ? LightDataTypes\Effect::SET_TEMPERATURE : 0);
460
461
        $effect = new LightDataTypes\Effect((bool)$transient, $color, $period, $cycles, $skewRatio, $waveform, $options);
462
463
        return new LightCommmands\SetWaveformOptional($effect);
464
    }
465
466
    private function decodeState(string $data): LightResponses\State
1 ignored issue
show
Unused Code introduced by
The method decodeState() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
467
    {
468
        [
469
            'hue'         => $hue,
470
            'saturation'  => $saturation,
471
            'brightness'  => $brightness,
472
            'temperature' => $temperature,
473
            'power'       => $power,
474
            'label'       => $label,
475
        ] = \unpack(self::HSBK_FORMAT . '/vreserved/vpower/a32label/Preserved', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

475
        ] = /** @scrutinizer ignore-call */ \unpack(self::HSBK_FORMAT . '/vreserved/vpower/a32label/Preserved', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
476
477
        $color = new LightDataTypes\HsbkColor($hue, $saturation, $brightness, $temperature);
478
        $label = new DeviceDataTypes\Label(\rtrim($label, "\x00"));
479
480
        return new LightResponses\State(new LightDataTypes\State($color, $power, $label));
481
    }
482
483
    private function decodeGetInfrared(): LightRequests\GetInfrared
1 ignored issue
show
Unused Code introduced by
The method decodeGetInfrared() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
484
    {
485
        return new LightRequests\GetInfrared;
486
    }
487
488
    private function decodeSetInfrared(string $data): LightCommmands\SetInfrared
1 ignored issue
show
Unused Code introduced by
The method decodeSetInfrared() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
489
    {
490
        $level = \unpack('vlevel', $data)['level'];
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

490
        $level = /** @scrutinizer ignore-call */ \unpack('vlevel', $data)['level'];

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
491
492
        return new LightCommmands\SetInfrared($level);
493
    }
494
495
    private function decodeStateInfrared(string $data): LightResponses\StateInfrared
1 ignored issue
show
Unused Code introduced by
The method decodeStateInfrared() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
496
    {
497
        $level = \unpack('vlevel', $data)['level'];
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

497
        $level = /** @scrutinizer ignore-call */ \unpack('vlevel', $data)['level'];

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
498
499
        return new LightResponses\StateInfrared($level);
500
    }
501
502
    private function decodeGetLightPower(): LightRequests\GetPower
1 ignored issue
show
Unused Code introduced by
The method decodeGetLightPower() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
503
    {
504
        return new LightRequests\GetPower;
505
    }
506
507
    private function decodeSetLightPower(string $data): LightCommmands\SetPower
1 ignored issue
show
Unused Code introduced by
The method decodeSetLightPower() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
508
    {
509
        [
510
            'level'    => $level,
511
            'duration' => $duration,
512
        ] = \unpack('vlevel/Vduration', $data);
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

512
        ] = /** @scrutinizer ignore-call */ \unpack('vlevel/Vduration', $data);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
513
514
        return new LightCommmands\SetPower(new LightDataTypes\PowerTransition($level, $duration));
515
    }
516
517
    private function decodeStateLightPower(string $data): LightResponses\StatePower
1 ignored issue
show
Unused Code introduced by
The method decodeStateLightPower() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
518
    {
519
        $level = \unpack('vlevel', $data)['level'];
0 ignored issues
show
Bug introduced by
The call to unpack() has too few arguments starting with offset. ( Ignorable by Annotation )

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

519
        $level = /** @scrutinizer ignore-call */ \unpack('vlevel', $data)['level'];

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
520
521
        return new LightResponses\StatePower($level);
522
    }
523
524
    public function __construct(UuidFactoryInterface $uuidFactory = null)
525
    {
526
        $this->uuidFactory = $uuidFactory ?? new UuidFactory;
527
    }
528
529
    /**
530
     * @param int $type
531
     * @param string $data
532
     * @return Message
533
     * @throws DecodingException
534
     */
535
    public function decodeMessage(int $type, string $data): Message
536
    {
537
        if (!\array_key_exists($type, self::MESSAGE_INFO)) {
538
            return new UnknownMessage($type, $data);
539
        }
540
541
        [$payloadLength, $messageName] = self::MESSAGE_INFO[$type];
542
543
        if (\strlen($data) !== $payloadLength) {
544
            throw new InvalidMessagePayloadLengthException(
545
                "Invalid payload length for {$messageName} message,"
546
                . " expecting {$payloadLength} bytes, got " . \strlen($data)
547
            );
548
        }
549
550
        try {
551
            return ([$this, 'decode' . $messageName])($data);
552
        } /** @noinspection PhpRedundantCatchClauseInspection */ catch (InvalidValueException $e) {
553
            throw new MalformedMessagePayloadException($e->getMessage(), $e->getCode(), $e);
554
        }
555
    }
556
}
557