BinnMapDecoder::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Knik\Binn\Decoder\Containers;
4
5
use Knik\Binn\Binn;
6
use Knik\Binn\Contracts\BinnValueDecoder;
7
use Knik\Binn\Decoder\Decoder;
8
use Knik\Binn\Decoder\DecoderCollection;
9
use Knik\Binn\Decoder\Unpacker;
10
11
class BinnMapDecoder extends Decoder implements BinnValueDecoder
12
{
13
    /** @var DecoderCollection */
14
    private $decoders;
15
16
    public function __construct(DecoderCollection $decoders)
17
    {
18
        $this->decoders = $decoders;
19
    }
20
21
    public function decode(string $bytes)
22
    {
23
        $readPosition = 1;
24
        $totalSize = Unpacker::unpackSize8($bytes[$readPosition]);
25
26
        if ($totalSize > Binn::BINN_MAX_ONE_BYTE_SIZE) {
27
            $totalSize = Unpacker::unpackSize32(substr($bytes, $readPosition, 4));
28
            $readPosition += 4;
29
        } else {
30
            $readPosition++;
31
        }
32
33
        $totalItems = Unpacker::unpackSize8($bytes[$readPosition]);
34
35
        if ($totalItems > Binn::BINN_MAX_ONE_BYTE_SIZE) {
36
            $totalItems = Unpacker::unpackSize32(substr($bytes, $readPosition, 4));
37
            $readPosition += 4;
38
        } else {
39
            $readPosition++;
40
        }
41
42
        $readedItems = 0;
43
44
        $result = [];
45
46
        while ($readedItems < $totalItems && $readPosition < $totalSize) {
47
            $keyValue = Unpacker::unpackInt32(substr($bytes, $readPosition, 4));
48
            $readPosition += 4;
49
50
            $readSize = $this->readSizeWithType(substr($bytes, $readPosition, 4));
51
            $innerStorage = substr($bytes, $readPosition, $readSize);
52
53
            /** @var BinnValueDecoder $decoder */
54
            foreach ($this->decoders->getAll() as $decoder) {
55
                if ($decoder->supportsDecoding($innerStorage)) {
56
                    $result[$keyValue] = $decoder->decode($innerStorage);
57
                    break;
58
                }
59
            }
60
61
            $readPosition += $readSize;
62
            $readedItems++;
63
        }
64
65
        return $result;
66
    }
67
68
    public function supportsDecoding(string $bytes): bool
69
    {
70
        $type = $this->detectType($bytes);
71
72
        return $type === Binn::BINN_MAP;
73
    }
74
}
75