These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the rybakit/msgpack.php package. |
||
5 | * |
||
6 | * (c) Eugene Leonovich <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace MessagePack; |
||
13 | |||
14 | use MessagePack\Exception\InsufficientDataException; |
||
15 | use MessagePack\Exception\IntegerOverflowException; |
||
16 | use MessagePack\Exception\UnpackingFailedException; |
||
17 | use MessagePack\TypeTransformer\Unpackable; |
||
18 | |||
19 | class BufferUnpacker |
||
20 | { |
||
21 | private $buffer; |
||
22 | private $offset = 0; |
||
23 | private $isBigIntAsStr; |
||
24 | private $isBigIntAsGmp; |
||
25 | |||
26 | /** |
||
27 | * @var Unpackable[]|null |
||
28 | */ |
||
29 | private $transformers; |
||
30 | |||
31 | /** |
||
32 | * @param string $buffer |
||
33 | * @param UnpackOptions|int|null $options |
||
34 | * |
||
35 | * @throws \MessagePack\Exception\InvalidOptionException |
||
36 | */ |
||
37 | 240 | public function __construct(string $buffer = '', $options = null) |
|
38 | { |
||
39 | 240 | if (null === $options) { |
|
40 | 239 | $options = UnpackOptions::fromDefaults(); |
|
41 | 8 | } elseif (!$options instanceof PackOptions) { |
|
42 | 8 | $options = UnpackOptions::fromBitmask($options); |
|
43 | } |
||
44 | |||
45 | 240 | $this->isBigIntAsStr = $options->isBigIntAsStrMode(); |
|
46 | 240 | $this->isBigIntAsGmp = $options->isBigIntAsGmpMode(); |
|
47 | |||
48 | 240 | $this->buffer = $buffer; |
|
49 | 240 | } |
|
50 | |||
51 | 1 | public function registerTransformer(Unpackable $transformer) : self |
|
52 | { |
||
53 | 1 | $this->transformers[$transformer->getType()] = $transformer; |
|
54 | |||
55 | 1 | return $this; |
|
56 | } |
||
57 | |||
58 | 10 | public function append(string $data) : self |
|
59 | { |
||
60 | 10 | $this->buffer .= $data; |
|
61 | |||
62 | 10 | return $this; |
|
63 | } |
||
64 | |||
65 | 213 | public function reset(string $buffer = '') : self |
|
66 | { |
||
67 | 213 | $this->buffer = $buffer; |
|
68 | 213 | $this->offset = 0; |
|
69 | |||
70 | 213 | return $this; |
|
71 | } |
||
72 | |||
73 | 3 | View Code Duplication | public function seek(int $offset) : self |
0 ignored issues
–
show
|
|||
74 | { |
||
75 | 3 | if ($offset < 0) { |
|
76 | 1 | $offset += \strlen($this->buffer); |
|
77 | } |
||
78 | |||
79 | 3 | if (!isset($this->buffer[$offset])) { |
|
80 | 1 | throw new \OutOfBoundsException("Unable to seek to position $offset."); |
|
81 | } |
||
82 | |||
83 | 2 | $this->offset = $offset; |
|
84 | |||
85 | 2 | return $this; |
|
86 | } |
||
87 | |||
88 | 2 | View Code Duplication | public function skip(int $offset) : self |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
89 | { |
||
90 | 2 | $offset += $this->offset; |
|
91 | |||
92 | 2 | if (!isset($this->buffer[$offset])) { |
|
93 | 1 | throw new \OutOfBoundsException("Unable to seek to position $offset."); |
|
94 | } |
||
95 | |||
96 | 1 | $this->offset = $offset; |
|
97 | |||
98 | 1 | return $this; |
|
99 | } |
||
100 | |||
101 | 1 | public function __clone() |
|
102 | { |
||
103 | 1 | $this->buffer = ''; |
|
104 | 1 | $this->offset = 0; |
|
105 | 1 | } |
|
106 | |||
107 | 3 | public function tryUnpack() : array |
|
108 | { |
||
109 | 3 | $data = []; |
|
110 | 3 | $offset = $this->offset; |
|
111 | |||
112 | try { |
||
113 | do { |
||
114 | 3 | $data[] = $this->unpack(); |
|
115 | 3 | $offset = $this->offset; |
|
116 | 3 | } while (isset($this->buffer[$this->offset])); |
|
117 | 1 | } catch (InsufficientDataException $e) { |
|
118 | 1 | $this->offset = $offset; |
|
119 | } |
||
120 | |||
121 | 3 | if ($this->offset) { |
|
122 | 3 | $this->buffer = isset($this->buffer[$this->offset]) ? \substr($this->buffer, $this->offset) : ''; |
|
123 | 3 | $this->offset = 0; |
|
124 | } |
||
125 | |||
126 | 3 | return $data; |
|
127 | } |
||
128 | |||
129 | 145 | public function unpack() |
|
130 | { |
||
131 | 145 | if (!isset($this->buffer[$this->offset])) { |
|
132 | 5 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
133 | } |
||
134 | |||
135 | 142 | $c = \ord($this->buffer[$this->offset]); |
|
136 | 142 | ++$this->offset; |
|
137 | |||
138 | // fixint |
||
139 | 142 | if ($c <= 0x7f) { |
|
140 | 31 | return $c; |
|
141 | } |
||
142 | // fixstr |
||
143 | 135 | View Code Duplication | if ($c >= 0xa0 && $c <= 0xbf) { |
144 | 18 | return ($c & 0x1f) ? $this->unpackStrData($c & 0x1f) : ''; |
|
145 | } |
||
146 | // fixarray |
||
147 | 128 | if ($c >= 0x90 && $c <= 0x9f) { |
|
148 | 9 | return ($c & 0xf) ? $this->unpackArrayData($c & 0xf) : []; |
|
149 | } |
||
150 | // fixmap |
||
151 | 125 | if ($c >= 0x80 && $c <= 0x8f) { |
|
152 | 13 | return ($c & 0xf) ? $this->unpackMapData($c & 0xf) : []; |
|
153 | } |
||
154 | // negfixint |
||
155 | 121 | if ($c >= 0xe0) { |
|
156 | 5 | return $c - 0x100; |
|
157 | } |
||
158 | |||
159 | 116 | switch ($c) { |
|
160 | 116 | case 0xc0: return null; |
|
161 | 113 | case 0xc2: return false; |
|
162 | 108 | case 0xc3: return true; |
|
163 | |||
164 | // bin |
||
165 | 98 | case 0xc4: return $this->unpackStrData($this->unpackUint8()); |
|
166 | 93 | case 0xc5: return $this->unpackStrData($this->unpackUint16()); |
|
167 | 92 | case 0xc6: return $this->unpackStrData($this->unpackUint32()); |
|
168 | |||
169 | // float |
||
170 | 91 | case 0xca: return $this->unpackFloat32(); |
|
171 | 88 | case 0xcb: return $this->unpackFloat64(); |
|
172 | |||
173 | // uint |
||
174 | 84 | case 0xcc: return $this->unpackUint8(); |
|
175 | 80 | case 0xcd: return $this->unpackUint16(); |
|
176 | 73 | case 0xce: return $this->unpackUint32(); |
|
177 | 68 | case 0xcf: return $this->unpackUint64(); |
|
178 | |||
179 | // int |
||
180 | 56 | case 0xd0: return $this->unpackInt8(); |
|
181 | 51 | case 0xd1: return $this->unpackInt16(); |
|
182 | 46 | case 0xd2: return $this->unpackInt32(); |
|
183 | 41 | case 0xd3: return $this->unpackInt64(); |
|
184 | |||
185 | // str |
||
186 | 33 | case 0xd9: return $this->unpackStrData($this->unpackUint8()); |
|
187 | 29 | case 0xda: return $this->unpackStrData($this->unpackUint16()); |
|
188 | 27 | case 0xdb: return $this->unpackStrData($this->unpackUint32()); |
|
189 | |||
190 | // array |
||
191 | 26 | case 0xdc: return $this->unpackArrayData($this->unpackUint16()); |
|
192 | 24 | case 0xdd: return $this->unpackArrayData($this->unpackUint32()); |
|
193 | |||
194 | // map |
||
195 | 23 | case 0xde: return $this->unpackMapData($this->unpackUint16()); |
|
196 | 21 | case 0xdf: return $this->unpackMapData($this->unpackUint32()); |
|
197 | |||
198 | // ext |
||
199 | 20 | case 0xd4: return $this->unpackExtData(1); |
|
200 | 17 | case 0xd5: return $this->unpackExtData(2); |
|
201 | 15 | case 0xd6: return $this->unpackExtData(4); |
|
202 | 13 | case 0xd7: return $this->unpackExtData(8); |
|
203 | 11 | case 0xd8: return $this->unpackExtData(16); |
|
204 | 9 | case 0xc7: return $this->unpackExtData($this->unpackUint8()); |
|
205 | 5 | case 0xc8: return $this->unpackExtData($this->unpackUint16()); |
|
206 | 3 | case 0xc9: return $this->unpackExtData($this->unpackUint32()); |
|
207 | } |
||
208 | |||
209 | 1 | throw UnpackingFailedException::unknownCode($c); |
|
210 | } |
||
211 | |||
212 | 3 | public function unpackNil() |
|
213 | { |
||
214 | 3 | if (!isset($this->buffer[$this->offset])) { |
|
215 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
216 | } |
||
217 | |||
218 | 2 | if ("\xc0" === $this->buffer[$this->offset]) { |
|
219 | 1 | ++$this->offset; |
|
220 | |||
221 | 1 | return null; |
|
222 | } |
||
223 | |||
224 | 1 | throw UnpackingFailedException::unexpectedCode(\ord($this->buffer[$this->offset++]), 'nil'); |
|
225 | } |
||
226 | |||
227 | 5 | public function unpackBool() |
|
228 | { |
||
229 | 5 | if (!isset($this->buffer[$this->offset])) { |
|
230 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
231 | } |
||
232 | |||
233 | 4 | $c = \ord($this->buffer[$this->offset]); |
|
234 | 4 | ++$this->offset; |
|
235 | |||
236 | 4 | if (0xc2 === $c) { |
|
237 | 2 | return false; |
|
238 | } |
||
239 | 2 | if (0xc3 === $c) { |
|
240 | 1 | return true; |
|
241 | } |
||
242 | |||
243 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'bool'); |
|
244 | } |
||
245 | |||
246 | 40 | public function unpackInt() |
|
247 | { |
||
248 | 40 | if (!isset($this->buffer[$this->offset])) { |
|
249 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
250 | } |
||
251 | |||
252 | 39 | $c = \ord($this->buffer[$this->offset]); |
|
253 | 39 | ++$this->offset; |
|
254 | |||
255 | // fixint |
||
256 | 39 | if ($c <= 0x7f) { |
|
257 | 3 | return $c; |
|
258 | } |
||
259 | // negfixint |
||
260 | 36 | if ($c >= 0xe0) { |
|
261 | 3 | return $c - 0x100; |
|
262 | } |
||
263 | |||
264 | 33 | switch ($c) { |
|
265 | // uint |
||
266 | 33 | case 0xcc: return $this->unpackUint8(); |
|
267 | 30 | case 0xcd: return $this->unpackUint16(); |
|
268 | 27 | case 0xce: return $this->unpackUint32(); |
|
269 | 24 | case 0xcf: return $this->unpackUint64(); |
|
270 | |||
271 | // int |
||
272 | 20 | case 0xd0: return $this->unpackInt8(); |
|
273 | 16 | case 0xd1: return $this->unpackInt16(); |
|
274 | 12 | case 0xd2: return $this->unpackInt32(); |
|
275 | 8 | case 0xd3: return $this->unpackInt64(); |
|
276 | } |
||
277 | |||
278 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'int'); |
|
279 | } |
||
280 | |||
281 | 7 | public function unpackFloat() |
|
282 | { |
||
283 | 7 | if (!isset($this->buffer[$this->offset])) { |
|
284 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
285 | } |
||
286 | |||
287 | 6 | $c = \ord($this->buffer[$this->offset]); |
|
288 | 6 | ++$this->offset; |
|
289 | |||
290 | 6 | if (0xcb === $c) { |
|
291 | 3 | return $this->unpackFloat64(); |
|
292 | } |
||
293 | 3 | if (0xca === $c) { |
|
294 | 2 | return $this->unpackFloat32(); |
|
295 | } |
||
296 | |||
297 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'float'); |
|
298 | } |
||
299 | |||
300 | 14 | public function unpackStr() |
|
301 | { |
||
302 | 14 | if (!isset($this->buffer[$this->offset])) { |
|
303 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
304 | } |
||
305 | |||
306 | 13 | $c = \ord($this->buffer[$this->offset]); |
|
307 | 13 | ++$this->offset; |
|
308 | |||
309 | 13 | View Code Duplication | if ($c >= 0xa0 && $c <= 0xbf) { |
310 | 5 | return ($c & 0x1f) ? $this->unpackStrData($c & 0x1f) : ''; |
|
311 | } |
||
312 | 8 | if (0xd9 === $c) { |
|
313 | 4 | return $this->unpackStrData($this->unpackUint8()); |
|
314 | } |
||
315 | 4 | if (0xda === $c) { |
|
316 | 2 | return $this->unpackStrData($this->unpackUint16()); |
|
317 | } |
||
318 | 2 | if (0xdb === $c) { |
|
319 | 1 | return $this->unpackStrData($this->unpackUint32()); |
|
320 | } |
||
321 | |||
322 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'str'); |
|
323 | } |
||
324 | |||
325 | 7 | public function unpackBin() |
|
326 | { |
||
327 | 7 | if (!isset($this->buffer[$this->offset])) { |
|
328 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
329 | } |
||
330 | |||
331 | 6 | $c = \ord($this->buffer[$this->offset]); |
|
332 | 6 | ++$this->offset; |
|
333 | |||
334 | 6 | if (0xc4 === $c) { |
|
335 | 3 | return $this->unpackStrData($this->unpackUint8()); |
|
336 | } |
||
337 | 3 | if (0xc5 === $c) { |
|
338 | 1 | return $this->unpackStrData($this->unpackUint16()); |
|
339 | } |
||
340 | 2 | if (0xc6 === $c) { |
|
341 | 1 | return $this->unpackStrData($this->unpackUint32()); |
|
342 | } |
||
343 | |||
344 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'bin'); |
|
345 | } |
||
346 | |||
347 | 9 | public function unpackArray() |
|
348 | { |
||
349 | 9 | $size = $this->unpackArrayHeader(); |
|
350 | |||
351 | 7 | $array = []; |
|
352 | 7 | while ($size--) { |
|
353 | 6 | $array[] = $this->unpack(); |
|
354 | } |
||
355 | |||
356 | 7 | return $array; |
|
357 | } |
||
358 | |||
359 | 9 | View Code Duplication | public function unpackArrayHeader() |
360 | { |
||
361 | 9 | if (!isset($this->buffer[$this->offset])) { |
|
362 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
363 | } |
||
364 | |||
365 | 8 | $c = \ord($this->buffer[$this->offset]); |
|
366 | 8 | ++$this->offset; |
|
367 | |||
368 | 8 | if ($c >= 0x90 && $c <= 0x9f) { |
|
369 | 4 | return $c & 0xf; |
|
370 | } |
||
371 | 4 | if (0xdc === $c) { |
|
372 | 2 | return $this->unpackUint16(); |
|
373 | } |
||
374 | 2 | if (0xdd === $c) { |
|
375 | 1 | return $this->unpackUint32(); |
|
376 | } |
||
377 | |||
378 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'array header'); |
|
379 | } |
||
380 | |||
381 | 13 | public function unpackMap() |
|
382 | { |
||
383 | 13 | $size = $this->unpackMapHeader(); |
|
384 | |||
385 | 11 | $map = []; |
|
386 | 11 | while ($size--) { |
|
387 | 10 | $map[$this->unpack()] = $this->unpack(); |
|
388 | } |
||
389 | |||
390 | 11 | return $map; |
|
391 | } |
||
392 | |||
393 | 13 | View Code Duplication | public function unpackMapHeader() |
394 | { |
||
395 | 13 | if (!isset($this->buffer[$this->offset])) { |
|
396 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
397 | } |
||
398 | |||
399 | 12 | $c = \ord($this->buffer[$this->offset]); |
|
400 | 12 | ++$this->offset; |
|
401 | |||
402 | 12 | if ($c >= 0x80 && $c <= 0x8f) { |
|
403 | 8 | return $c & 0xf; |
|
404 | } |
||
405 | 4 | if (0xde === $c) { |
|
406 | 2 | return $this->unpackUint16(); |
|
407 | } |
||
408 | 2 | if (0xdf === $c) { |
|
409 | 1 | return $this->unpackUint32(); |
|
410 | } |
||
411 | |||
412 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'map header'); |
|
413 | } |
||
414 | |||
415 | 10 | public function unpackExt() |
|
416 | { |
||
417 | 10 | if (!isset($this->buffer[$this->offset])) { |
|
418 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
419 | } |
||
420 | |||
421 | 9 | $c = \ord($this->buffer[$this->offset]); |
|
422 | 9 | ++$this->offset; |
|
423 | |||
424 | 9 | switch ($c) { |
|
425 | 9 | case 0xd4: return $this->unpackExtData(1); |
|
426 | 8 | case 0xd5: return $this->unpackExtData(2); |
|
427 | 7 | case 0xd6: return $this->unpackExtData(4); |
|
428 | 6 | case 0xd7: return $this->unpackExtData(8); |
|
429 | 5 | case 0xd8: return $this->unpackExtData(16); |
|
430 | 4 | case 0xc7: return $this->unpackExtData($this->unpackUint8()); |
|
431 | 3 | case 0xc8: return $this->unpackExtData($this->unpackUint16()); |
|
432 | 2 | case 0xc9: return $this->unpackExtData($this->unpackUint32()); |
|
433 | } |
||
434 | |||
435 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'ext header'); |
|
436 | } |
||
437 | |||
438 | 34 | private function unpackUint8() |
|
439 | { |
||
440 | 34 | if (!isset($this->buffer[$this->offset])) { |
|
441 | 2 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
442 | } |
||
443 | |||
444 | 32 | return \ord($this->buffer[$this->offset++]); |
|
445 | } |
||
446 | |||
447 | 28 | private function unpackUint16() |
|
448 | { |
||
449 | 28 | if (!isset($this->buffer[$this->offset + 1])) { |
|
450 | 2 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 2); |
|
451 | } |
||
452 | |||
453 | 26 | $hi = \ord($this->buffer[$this->offset]); |
|
454 | 26 | $lo = \ord($this->buffer[++$this->offset]); |
|
455 | 26 | ++$this->offset; |
|
456 | |||
457 | 26 | return $hi << 8 | $lo; |
|
458 | } |
||
459 | |||
460 | 20 | private function unpackUint32() |
|
461 | { |
||
462 | 20 | if (!isset($this->buffer[$this->offset + 3])) { |
|
463 | 2 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 4); |
|
464 | } |
||
465 | |||
466 | 18 | $num = \unpack('N', $this->buffer, $this->offset)[1]; |
|
467 | 18 | $this->offset += 4; |
|
468 | |||
469 | 18 | return $num; |
|
470 | } |
||
471 | |||
472 | 16 | View Code Duplication | private function unpackUint64() |
473 | { |
||
474 | 16 | if (!isset($this->buffer[$this->offset + 7])) { |
|
475 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 8); |
|
476 | } |
||
477 | |||
478 | 15 | $num = \unpack('J', $this->buffer, $this->offset)[1]; |
|
479 | 15 | $this->offset += 8; |
|
480 | |||
481 | 15 | return $num < 0 ? $this->handleIntOverflow($num) : $num; |
|
482 | } |
||
483 | |||
484 | 9 | private function unpackInt8() |
|
485 | { |
||
486 | 9 | if (!isset($this->buffer[$this->offset])) { |
|
487 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
488 | } |
||
489 | |||
490 | 8 | $num = \ord($this->buffer[$this->offset]); |
|
491 | 8 | ++$this->offset; |
|
492 | |||
493 | 8 | return $num > 0x7f ? $num - 0x100 : $num; |
|
494 | } |
||
495 | |||
496 | 9 | private function unpackInt16() |
|
497 | { |
||
498 | 9 | if (!isset($this->buffer[$this->offset + 1])) { |
|
499 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 2); |
|
500 | } |
||
501 | |||
502 | 8 | $hi = \ord($this->buffer[$this->offset]); |
|
503 | 8 | $lo = \ord($this->buffer[++$this->offset]); |
|
504 | 8 | ++$this->offset; |
|
505 | |||
506 | 8 | return $hi > 0x7f ? $hi << 8 | $lo - 0x10000 : $hi << 8 | $lo; |
|
507 | } |
||
508 | |||
509 | 9 | View Code Duplication | private function unpackInt32() |
510 | { |
||
511 | 9 | if (!isset($this->buffer[$this->offset + 3])) { |
|
512 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 4); |
|
513 | } |
||
514 | |||
515 | 8 | $num = \unpack('N', $this->buffer, $this->offset)[1]; |
|
516 | 8 | $this->offset += 4; |
|
517 | |||
518 | 8 | return $num > 0x7fffffff ? $num - 0x100000000 : $num; |
|
519 | } |
||
520 | |||
521 | 15 | private function unpackInt64() |
|
522 | { |
||
523 | 15 | if (!isset($this->buffer[$this->offset + 7])) { |
|
524 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 8); |
|
525 | } |
||
526 | |||
527 | 14 | $num = \unpack('J', $this->buffer, $this->offset)[1]; |
|
528 | 14 | $this->offset += 8; |
|
529 | |||
530 | 14 | return $num; |
|
531 | } |
||
532 | |||
533 | 5 | private function unpackFloat32() |
|
534 | { |
||
535 | 5 | if (!isset($this->buffer[$this->offset + 3])) { |
|
536 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 4); |
|
537 | } |
||
538 | |||
539 | 4 | $num = \unpack('G', $this->buffer, $this->offset)[1]; |
|
540 | 4 | $this->offset += 4; |
|
541 | |||
542 | 4 | return $num; |
|
543 | } |
||
544 | |||
545 | 7 | private function unpackFloat64() |
|
546 | { |
||
547 | 7 | if (!isset($this->buffer[$this->offset + 7])) { |
|
548 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 8); |
|
549 | } |
||
550 | |||
551 | 6 | $num = \unpack('E', $this->buffer, $this->offset)[1]; |
|
552 | 6 | $this->offset += 8; |
|
553 | |||
554 | 6 | return $num; |
|
555 | } |
||
556 | |||
557 | 47 | private function unpackStrData($length) |
|
558 | { |
||
559 | 47 | if (!isset($this->buffer[$this->offset + $length - 1])) { |
|
560 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, $length); |
|
561 | } |
||
562 | |||
563 | 47 | $str = \substr($this->buffer, $this->offset, $length); |
|
564 | 47 | $this->offset += $length; |
|
565 | |||
566 | 47 | return $str; |
|
567 | } |
||
568 | |||
569 | 11 | private function unpackArrayData($size) |
|
570 | { |
||
571 | 11 | $array = []; |
|
572 | 11 | while ($size--) { |
|
573 | 11 | $array[] = $this->unpack(); |
|
574 | } |
||
575 | |||
576 | 11 | return $array; |
|
577 | } |
||
578 | |||
579 | 15 | private function unpackMapData($size) |
|
580 | { |
||
581 | 15 | $map = []; |
|
582 | 15 | while ($size--) { |
|
583 | 15 | $map[$this->unpack()] = $this->unpack(); |
|
584 | } |
||
585 | |||
586 | 15 | return $map; |
|
587 | } |
||
588 | |||
589 | 24 | private function unpackExtData($length) |
|
590 | { |
||
591 | 24 | if (!isset($this->buffer[$this->offset + $length - 1])) { |
|
592 | 5 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, $length); |
|
593 | } |
||
594 | |||
595 | // int8 |
||
596 | 19 | $type = \ord($this->buffer[$this->offset]); |
|
597 | 19 | ++$this->offset; |
|
598 | |||
599 | 19 | if ($type > 0x7f) { |
|
600 | $type -= 0x100; |
||
601 | } |
||
602 | |||
603 | 19 | if (isset($this->transformers[$type])) { |
|
604 | 1 | return $this->transformers[$type]->unpack($this, $length); |
|
605 | } |
||
606 | |||
607 | 18 | $data = \substr($this->buffer, $this->offset, $length); |
|
608 | 18 | $this->offset += $length; |
|
609 | |||
610 | 18 | return new Ext($type, $data); |
|
611 | } |
||
612 | |||
613 | 5 | private function handleIntOverflow($value) |
|
614 | { |
||
615 | 5 | if ($this->isBigIntAsStr) { |
|
616 | 3 | return \sprintf('%u', $value); |
|
617 | } |
||
618 | 2 | if ($this->isBigIntAsGmp) { |
|
619 | 1 | return \gmp_init(\sprintf('%u', $value)); |
|
620 | } |
||
621 | |||
622 | 1 | throw new IntegerOverflowException($value); |
|
623 | } |
||
624 | } |
||
625 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.