BinnListEncoder::encode()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
c 1
b 0
f 0
dl 0
loc 29
rs 9.3888
cc 5
nc 5
nop 1
1
<?php
2
3
namespace Knik\Binn\Encoder\Containers;
4
5
use Knik\Binn\Binn;
6
use Knik\Binn\Contracts\BinnValueEncoder;
7
use Knik\Binn\Encoder\EncoderCollection;
8
use Knik\Binn\Encoder\Packer;
9
use Knik\Binn\Exceptions\InvalidArrayException;
10
11
class BinnListEncoder implements BinnValueEncoder
12
{
13
    public const TYPE = Binn::BINN_LIST;
14
15
    /** @var EncoderCollection */
16
    private $encoders;
17
18
    public function __construct(EncoderCollection $encoders)
19
    {
20
        $this->encoders = $encoders;
21
    }
22
23
    public function encode($value): string
24
    {
25
        if ($this->isArrayAssoc($value)) {
26
            throw new InvalidArrayException('Array should be sequential');
27
        }
28
29
        $encodedItems = '';
30
31
        foreach ($value as $item) {
32
            /** @var BinnValueEncoder $encoder */
33
            foreach ($this->encoders->getAll() as $encoder) {
34
                if ($encoder->supportsEncoding($item)) {
35
                    $encodedItems .= $encoder->encode($item);
36
                    break;
37
                }
38
            }
39
        }
40
41
        $encodedType  = Packer::packUint8(self::TYPE);
42
        $encodedCount = Packer::packSize(count($value));
43
        $encodedSize  = Packer::packSize(
44
            strlen($encodedType) + strlen($encodedCount) + strlen($encodedItems),
45
            true
46
        );
47
48
        return $encodedType
49
            . $encodedSize
50
            . $encodedCount
51
            . $encodedItems;
52
    }
53
54
    public function supportsEncoding($value): bool
55
    {
56
        return is_array($value) && !$this->isArrayAssoc($value);
57
    }
58
59
    private function isArrayAssoc($arr)
60
    {
61
        $arr = (array)$arr;
62
63
        if ([] === $arr) {
64
            return false;
65
        }
66
67
        return array_keys($arr) !== range(0, count($arr) - 1);
68
    }
69
}
70