Completed
Push — master ( 0cf7cc...058dc6 )
by thomas
82:39 queued 67:47
created

Parser::getSize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace BitWasp\Buffertools;
4
5
use BitWasp\Buffertools\Exceptions\ParserOutOfRange;
6
use Mdanter\Ecc\EccFactory;
7
use Mdanter\Ecc\Math\GmpMathInterface;
8
9
class Parser
10
{
11
    /**
12
     * @var string
13
     */
14
    private $string;
15
16
    /**
17
     * @var \Mdanter\Ecc\Math\GmpMathInterface
18
     */
19
    private $math;
20
21
    /**
22
     * @var int
23
     */
24
    private $size = 0;
25
26
    /**
27
     * @var int
28
     */
29
    private $position = 0;
30
31
    /**
32
     * Instantiate class, optionally taking Buffer or HEX.
33
     *
34
     * @param null|string|BufferInterface $input
35
     * @param GmpMathInterface|null $math
36
     */
37
    public function __construct($input = null, GmpMathInterface $math = null)
38
    {
39
        $this->math = $math ?: EccFactory::getAdapter();
40
41
        if (!$input instanceof BufferInterface) {
42
            $input = Buffer::hex($input, null, $this->math);
43
        }
44
45
        $this->string = $input->getBinary();
46
        $this->position = 0;
47
        $this->size = 0;
48
    }
49
50
    /**
51
     * Get the position pointer of the parser - ie, how many bytes from 0
52
     *
53
     * @return int
54
     */
55
    public function getPosition()
56
    {
57
        return $this->position;
58
    }
59
60
    /**
61
     * Get the total size of the parser
62
     *
63
     * @return int
64
     */
65
    public function getSize()
66
    {
67
        return $this->size;
68
    }
69
70
    /**
71
     * Parse $bytes bytes from the string, and return the obtained buffer
72
     *
73
     * @param  integer $bytes
74
     * @param  bool $flipBytes
75
     * @return Buffer
76
     * @throws \Exception
77
     */
78
    public function readBytes($bytes, $flipBytes = false)
79
    {
80
        $string = substr($this->string, $this->getPosition(), $bytes);
81
        $length = strlen($string);
82
83
        if ($length == 0) {
84
            throw new ParserOutOfRange('Could not parse string of required length (empty)');
85
        } elseif ($length < $bytes) {
86
            throw new ParserOutOfRange('Could not parse string of required length (too short)');
87
        }
88
89
        $this->position += $bytes;
90
91
        if ($flipBytes) {
92
            $string = Buffertools::flipBytes($string);
93
        }
94
95
        return new Buffer($string, $length, $this->math);
0 ignored issues
show
Bug introduced by
It seems like $string defined by \BitWasp\Buffertools\Buf...ols::flipBytes($string) on line 92 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...
96
    }
97
98
    /**
99
     * Write $data as $bytes bytes. Can be flipped if needed.
100
     *
101
     * @param  integer $bytes
102
     * @param  $data
103
     * @param  bool $flipBytes
104
     * @return $this
105
     */
106
    public function writeBytes($bytes, $data, $flipBytes = false)
107
    {
108
        // Treat $data to ensure it's a buffer, with the correct size
109
        if ($data instanceof SerializableInterface) {
110
            $data = $data->getBuffer();
111
        }
112
113
        if (is_string($data)) {
114
            // Convert to a buffer
115
            $data = Buffer::hex($data, $bytes, $this->math);
116
        } else if (!($data instanceof BufferInterface)) {
117
            throw new \RuntimeException('Invalid data passed to Parser::writeBytes');
118
        }
119
120
        $this->writeBuffer($bytes, $data, $flipBytes);
121
122
        return $this;
123
    }
124
125
    /**
126
     * Write $data as $bytes bytes. Can be flipped if needed.
127
     *
128
     * @param  integer $bytes
129
     * @param  string $data
130
     * @param  bool $flipBytes
131
     * @return $this
132
     */
133
    public function writeRawBinary($bytes, $data, $flipBytes = false)
134
    {
135
        return $this->writeBuffer($bytes, new Buffer($data, $bytes), $flipBytes);
136
    }
137
138
    /**
139
     * @param BufferInterface $buffer
140
     * @param bool $flipBytes
141
     * @param int $bytes
142
     * @return $this
143
     */
144
    public function writeBuffer($bytes, BufferInterface $buffer, $flipBytes = false)
145
    {
146
        // only create a new buffer if the size does not match
147
        if ($buffer->getSize() != $bytes) {
148
            $buffer = new Buffer($buffer->getBinary(), $bytes, $this->math);
149
        }
150
151
        $this->appendBuffer($buffer, $flipBytes);
152
153
        return $this;
154
    }
155
156
    /**
157
     * @param BufferInterface $buffer
158
     * @param bool $flipBytes
159
     * @return $this
160
     */
161
    public function appendBuffer(BufferInterface $buffer, $flipBytes = false)
162
    {
163
        $this->appendBinary($buffer->getBinary(), $flipBytes);
164
        return $this;
165
    }
166
167
    /**
168
     * @param string $binary
169
     * @param bool $flipBytes
170
     * @return $this
171
     */
172
    public function appendBinary($binary, $flipBytes = false)
173
    {
174
        if ($flipBytes) {
175
            $binary = Buffertools::flipBytes($binary);
176
        }
177
178
        $this->string .= $binary;
179
        $this->size += strlen($binary);
180
        return $this;
181
    }
182
183
    /**
184
     * Take an array containing serializable objects.
185
     * @param SerializableInterface[]|Buffer[]
186
     * @return $this
187
     */
188
    public function writeArray($serializable)
189
    {
190
        $parser = new Parser(Buffertools::numToVarInt(count($serializable)), $this->math);
191
        foreach ($serializable as $object) {
192
            if ($object instanceof SerializableInterface) {
193
                $object = $object->getBuffer();
194
            }
195
196
            if ($object instanceof BufferInterface) {
197
                $parser->writeBytes($object->getSize(), $object);
198
            } else {
199
                throw new \RuntimeException('Input to writeArray must be Buffer[], or SerializableInterface[]');
200
            }
201
        }
202
203
        $this->string .= $parser->getBuffer()->getBinary();
204
        $this->size += $parser->getSize();
205
206
        return $this;
207
    }
208
209
    /**
210
     * Return the string as a buffer
211
     *
212
     * @return BufferInterface
213
     */
214
    public function getBuffer()
215
    {
216
        return new Buffer($this->string, null, $this->math);
217
    }
218
}
219