Passed
Pull Request — master (#2)
by thomas
02:16
created

HexCodec::parsePayload()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 14
cts 14
cp 1
rs 9.0534
c 0
b 0
f 0
cc 4
eloc 13
nc 4
nop 1
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Trezor\Bridge\Codec\CallMessage;
6
7
use BitWasp\Trezor\Bridge\Exception\InvalidMessageException;
8
use BitWasp\Trezor\Bridge\Util\StreamUtil;
9
use Psr\Http\Message\StreamInterface;
10
11
class HexCodec
12
{
13
    /**
14
     * @var StreamUtil
15
     */
16
    private $stream;
17
18 22
    public function __construct()
19
    {
20 22
        $this->stream = new StreamUtil();
21 22
    }
22
23
    /**
24
     * Implement integer comparison
25
     * Returns: 0 if  $a === $b
26
     *         -1 if  $a  <  $b
27
     *         +1 if  $a  >  $b
28
     *
29
     * @param int $a
30
     * @param int $b
31
     * @return int
32
     */
33 3
    private function intcmp(int $a, int $b): int
34
    {
35 3
        return ($a < $b) ? -1 : (($a > $b) ? 1 : 0);
36
    }
37
38 9
    public function parsePayload(StreamInterface $stream): array
39
    {
40 9
        if ($stream->getSize() < 12) {
41 6
            throw new InvalidMessageException("Malformed data (size too small)");
42
        }
43
44 3
        $stream = $this->stream->hex2bin($stream);
45 3
        list ($type) = array_values(unpack('n', $stream->read(2)));
46 3
        $stream->seek(2);
47
48 3
        list ($size) = array_values(unpack('N', $stream->read(4)));
49 3
        $stream->seek(6);
50
51 3
        $lCmp = $this->intcmp($stream->getSize() - 6, $size);
52 3
        if ($lCmp < 0) {
53 1
            throw new InvalidMessageException("Malformed data (not enough data)");
54 2
        } else if ($lCmp > 0) {
55 1
            throw new InvalidMessageException("Malformed data (too much data)");
56
        }
57
58 1
        return [$type, $this->stream->createStream($stream->read($size))];
59
    }
60
61 1
    public function encode(int $messageType, \Protobuf\Message $protobuf): string
62
    {
63 1
        $stream = $protobuf->toStream();
64 1
        return unpack(
65 1
            'H*',
66 1
            sprintf(
67 1
                "%s%s",
68 1
                pack('nN', $messageType, $stream->getSize()),
69 1
                $stream->getContents()
70
            )
71 1
        )[1];
72
    }
73
}
74