NonDiscardingBinaryCodec::encodeMessage()   C
last analyzed

Complexity

Conditions 15
Paths 19

Size

Total Lines 71

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 47.3354

Importance

Changes 0
Metric Value
dl 0
loc 71
ccs 20
cts 42
cp 0.4762
rs 5.9166
c 0
b 0
f 0
cc 15
nc 19
nop 1
crap 47.3354

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Bip70\Protobuf\Codec;
6
7
use DrSlump\Protobuf;
8
use DrSlump\Protobuf\Codec\Binary\Writer as BinaryWriter;
9
use DrSlump\Protobuf\Codec\Binary as BinaryCodec;
10
11
class NonDiscardingBinaryCodec extends BinaryCodec
12
{
13
    /**
14
     * Same as upstreams, but removing the part that
15
     * discards fields where the current value matches
16
     * the default
17
     *
18
     * @param Protobuf\Message $message
19
     * @return string
20
     */
21 11
    protected function encodeMessage(Protobuf\Message $message)
22
    {
23 11
        $writer = new BinaryWriter();
24
25
        // Get message descriptor
26 11
        $descriptor = Protobuf::getRegistry()->getDescriptor($message);
27
28 11
        foreach ($descriptor->getFields() as $tag => $field) {
29 11
            $empty = !$message->_has($tag);
30 11
            if ($field->isRequired() && $empty) {
31 1
                throw new \UnexpectedValueException(
32 1
                    'Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value'
33
                );
34
            }
35
36
            // Skip empty fields
37 11
            if ($empty) {
38 6
                continue;
39
            }
40
41 11
            $type = $field->getType();
42 11
            $wire = $field->isPacked() ? self::WIRE_LENGTH : $this->getWireType($type, null);
43
44
            // Compute key with tag number and wire type
45 11
            $key = $tag << 3 | $wire;
46
47 11
            $value = $message->_get($tag);
48
49 11
            if ($field->isRepeated()) {
50
                // Packed fields are encoded as a length-delimited stream containing
51
                // the concatenated encoding of each value.
52
                if ($field->isPacked() && !empty($value)) {
53
                    $subwriter = new BinaryWriter();
54
                    foreach ($value as $val) {
55
                        $this->encodeSimpleType($subwriter, $type, $val);
56
                    }
57
                    $data = $subwriter->getBytes();
58
                    $writer->varint($key);
59
                    $writer->varint(strlen($data));
60
                    $writer->write($data);
61
                } else {
62
                    // Make sure the value is an array of values
63
                    $value = is_array($value) ? $value : array($value);
64
                    foreach ($value as $val) {
65
                        // Skip nullified repeated values
66
                        if (null === $val) {
67
                            continue;
68
                        } else if ($type !== Protobuf::TYPE_MESSAGE) {
69
                            $writer->varint($key);
70
                            $this->encodeSimpleType($writer, $type, $val);
71
                        } else {
72
                            $writer->varint($key);
73
                            $data = $this->encodeMessage($val);
74
                            $writer->varint(strlen($data));
75
                            $writer->write($data);
76
                        }
77
                    }
78
                }
79 11
            } else if ($type !== Protobuf::TYPE_MESSAGE) {
80 11
                $writer->varint($key);
81 11
                $this->encodeSimpleType($writer, $type, $value);
82
            } else {
83
                $writer->varint($key);
84
                $data = $this->encodeMessage($value);
85
                $writer->varint(strlen($data));
86 11
                $writer->write($data);
87
            }
88
        }
89
90 10
        return $writer->getBytes();
91
    }
92
}
93