Completed
Pull Request — master (#71)
by thomas
20:44
created

Parser::writeBytes()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4.5923

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 18
ccs 6
cts 9
cp 0.6667
rs 9.2
cc 4
eloc 9
nc 6
nop 3
crap 4.5923
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Buffertools;
6
7
use BitWasp\Buffertools\Exceptions\ParserOutOfRange;
8
9
class Parser
10
{
11
    /**
12
     * @var string
13
     */
14
    private $string = '';
15
16
    /**
17
     * @var int
18
     */
19
    private $size = 0;
20
21
    /**
22
     * @var int
23
     */
24
    private $position = 0;
25
26
    /**
27
     * Instantiate class, optionally taking Buffer or HEX.
28
     *
29
     * @param BufferInterface $input
30
     */
31 164
    public function __construct(BufferInterface $input = null)
32
    {
33 164
        if ($input instanceof BufferInterface) {
34 14
            $this->string = $input->getBinary();
35
            $this->size = $input->getSize();
36
            assert(strlen($this->string) === $this->size);
37 164
        }
38 24
    }
39 142
40 142
    /**
41
     * Get the position pointer of the parser - ie, how many bytes from 0
42
     *
43
     * @return int
44
     */
45 164
    public function getPosition(): int
46 164
    {
47 164
        return $this->position;
48 164
    }
49
50
    /**
51
     * Get the total size of the parser
52
     *
53
     * @return int
54
     */
55 148
    public function getSize()
56
    {
57 148
        return $this->size;
58
    }
59
60
    /**
61
     * Parse $bytes bytes from the string, and return the obtained buffer
62
     *
63
     * @param  int $numBytes
64
     * @param  bool $flipBytes
65 16
     * @return BufferInterface
66
     * @throws \Exception
67 16
     */
68
    public function readBytes(int $numBytes, bool $flipBytes = false): BufferInterface
69
    {
70
        $string = substr($this->string, $this->getPosition(), $numBytes);
71
        $length = strlen($string);
72
73
        if ($length === 0) {
74
            throw new ParserOutOfRange('Could not parse string of required length (empty)');
75
        } elseif ($length < $numBytes) {
76
            throw new ParserOutOfRange('Could not parse string of required length (too short)');
77
        }
78 146
79
        $this->position += $numBytes;
80 146
81 146
        if ($flipBytes) {
82
            $string = Buffertools::flipBytes($string);
83 146
            /** @var string $string */
84 4
        }
85 144
86 2
        return new Buffer($string, $length);
0 ignored issues
show
Bug introduced by
It seems like $string defined by \BitWasp\Buffertools\Buf...ols::flipBytes($string) on line 82 can also be of type object<BitWasp\Buffertools\Buffer>; however, BitWasp\Buffertools\Buffer::__construct() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
87
    }
88
89 142
    /**
90
     * @param BufferInterface $buffer
91 142
     * @param bool $flipBytes
92 2
     * @return Parser
93
     */
94
    public function appendBuffer(BufferInterface $buffer, bool $flipBytes = false): Parser
95
    {
96 142
        $this->appendBinary($buffer->getBinary(), $flipBytes);
97
        return $this;
98
    }
99
100
    /**
101
     * @param string $binary
102
     * @param bool $flipBytes
103
     * @return Parser
104
     */
105
    public function appendBinary(string $binary, bool $flipBytes = false): Parser
106
    {
107 10
        if ($flipBytes) {
108
            $binary = Buffertools::flipBytes($binary);
109
        }
110 10
111
        $this->string .= $binary;
112
        $this->size += strlen($binary);
113
        return $this;
114 10
    }
115
116
    /**
117 10
     * Take an array containing serializable objects.
118
     * @param SerializableInterface[]|BufferInterface[] $serializable
119
     * @return Parser
120
     */
121 10
    public function writeArray(array $serializable): Parser
122
    {
123 10
        $parser = new Parser(Buffertools::numToVarInt(count($serializable)));
124
        foreach ($serializable as $object) {
125
            if ($object instanceof SerializableInterface) {
126
                $object = $object->getBuffer();
127
            }
128
129
            if ($object instanceof BufferInterface) {
130
                $parser->appendBinary($object->getBinary());
131
            } else {
132
                throw new \RuntimeException('Input to writeArray must be Buffer[], or SerializableInterface[]');
133
            }
134
        }
135
136
        $this->string .= $parser->getBuffer()->getBinary();
137
        $this->size += $parser->getSize();
138
139
        return $this;
140
    }
141
142
    /**
143
     * Return the string as a buffer
144
     *
145 10
     * @return BufferInterface
146
     */
147
    public function getBuffer(): BufferInterface
148 10
    {
149 4
        return new Buffer($this->string, $this->size);
150
    }
151
}
152