Completed
Push — master ( 236ac6...a2dcd1 )
by thomas
14:08
created

Parser::getPosition()   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 $position = 0;
25
26
    /**
27
     * Instantiate class, optionally taking Buffer or HEX.
28
     *
29
     * @param null|string|BufferInterface $input
30
     * @param GmpMathInterface|null $math
31
     */
32
    public function __construct($input = null, GmpMathInterface $math = null)
33
    {
34
        $this->math = $math ?: EccFactory::getAdapter();
35
36
        if (!$input instanceof BufferInterface) {
37
            $input = Buffer::hex($input, null, $this->math);
38
        }
39
40
        $this->string = $input->getBinary();
41
        $this->position = 0;
42
    }
43
44
    /**
45
     * Get the position pointer of the parser - ie, how many bytes from 0
46
     *
47
     * @return int
48
     */
49
    public function getPosition()
50
    {
51
        return $this->position;
52
    }
53
54
    /**
55
     * Parse $bytes bytes from the string, and return the obtained buffer
56
     *
57
     * @param  integer $bytes
58
     * @param  bool $flipBytes
59
     * @return Buffer
60
     * @throws \Exception
61
     */
62
    public function readBytes($bytes, $flipBytes = false)
63
    {
64
        $string = substr($this->string, $this->getPosition(), $bytes);
65
        $length = strlen($string);
66
67
        if ($length == 0) {
68
            throw new ParserOutOfRange('Could not parse string of required length (empty)');
69
        } elseif ($length < $bytes) {
70
            throw new ParserOutOfRange('Could not parse string of required length (too short)');
71
        }
72
73
        $this->position += $bytes;
74
75
        if ($flipBytes) {
76
            $string = Buffertools::flipBytes($string);
77
        }
78
79
        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 76 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...
80
    }
81
82
    /**
83
     * Write $data as $bytes bytes. Can be flipped if needed.
84
     *
85
     * @param  integer $bytes
86
     * @param  $data
87
     * @param  bool $flipBytes
88
     * @return $this
89
     */
90
    public function writeBytes($bytes, $data, $flipBytes = false)
91
    {
92
        // Treat $data to ensure it's a buffer, with the correct size
93
        if ($data instanceof SerializableInterface) {
94
            $data = $data->getBuffer();
95
        }
96
97
        if ($data instanceof BufferInterface) {
98
            // only create a new buffer if the size does not match
99
            if ($data->getSize() != $bytes) {
100
                $data = new Buffer($data->getBinary(), $bytes, $this->math);
101
            }
102
        } else {
103
            // Convert to a buffer
104
            $data = Buffer::hex($data, $bytes, $this->math);
105
        }
106
107
        $this->appendBuffer($data, $flipBytes);
108
109
        return $this;
110
    }
111
112
    /**
113
     * Write $data as $bytes bytes. Can be flipped if needed.
114
     *
115
     * @param  integer $bytes
116
     * @param  string $data
117
     * @param  bool $flipBytes
118
     * @return $this
119
     */
120
    public function writeRawBinary($bytes, $data, $flipBytes = false)
121
    {
122
        return $this->appendBuffer(new Buffer($data, $bytes), $flipBytes);
123
    }
124
125
    /**
126
     * @param BufferInterface $buffer
127
     * @param bool $flipBytes
128
     * @return $this
129
     */
130
    private function appendBuffer(BufferInterface $buffer, $flipBytes = false)
131
    {
132
        if ($flipBytes) {
133
            $buffer = $buffer->flip();
134
        }
135
136
        $this->string .= $buffer->getBinary();
137
        return $this;
138
    }
139
140
    /**
141
     * Take an array containing serializable objects.
142
     * @param SerializableInterface[]|Buffer[]
143
     * @return $this
144
     */
145
    public function writeArray($serializable)
146
    {
147
        $parser = new Parser(Buffertools::numToVarInt(count($serializable)), $this->math);
148
        foreach ($serializable as $object) {
149
            if ($object instanceof SerializableInterface) {
150
                $object = $object->getBuffer();
151
            }
152
153
            if ($object instanceof BufferInterface) {
154
                $parser->writeBytes($object->getSize(), $object);
155
            } else {
156
                throw new \RuntimeException('Input to writeArray must be Buffer[], or SerializableInterface[]');
157
            }
158
        }
159
160
        $this->string .= $parser->getBuffer()->getBinary();
161
162
        return $this;
163
    }
164
165
    /**
166
     * Return the string as a buffer
167
     *
168
     * @return BufferInterface
169
     */
170
    public function getBuffer()
171
    {
172
        return new Buffer($this->string, null, $this->math);
173
    }
174
}
175