Passed
Push — master ( 5531ab...342a74 )
by Eugene
02:03
created

BufferUnpacker::release()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 0
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 3
rs 10
c 0
b 0
f 0
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\InvalidOptionException;
17
use MessagePack\Exception\UnpackingFailedException;
18
use MessagePack\TypeTransformer\Extension;
19
20
class BufferUnpacker
21
{
22
    private $buffer;
23
    private $offset = 0;
24
    private $isBigIntAsStr;
25
    private $isBigIntAsGmp;
26
27
    /**
28
     * @var Extension[]
29
     */
30
    private $extensions = [];
31
32
    /**
33
     * @param UnpackOptions|int|null $options
34
     * @param Extension[] $extensions
35
     *
36
     * @throws InvalidOptionException
37
     */
38 320
    public function __construct(string $buffer = '', $options = null, array $extensions = [])
39
    {
40 320
        if (\is_null($options)) {
41 319
            $options = UnpackOptions::fromDefaults();
42 8
        } elseif (!$options instanceof PackOptions) {
0 ignored issues
show
introduced by
$options is never a sub-type of MessagePack\PackOptions.
Loading history...
43 8
            $options = UnpackOptions::fromBitmask($options);
0 ignored issues
show
Bug introduced by
It seems like $options can also be of type MessagePack\UnpackOptions; however, parameter $bitmask of MessagePack\UnpackOptions::fromBitmask() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

43
            $options = UnpackOptions::fromBitmask(/** @scrutinizer ignore-type */ $options);
Loading history...
44
        }
45
46 320
        $this->isBigIntAsStr = $options->isBigIntAsStrMode();
47 320
        $this->isBigIntAsGmp = $options->isBigIntAsGmpMode();
48
49 320
        $this->buffer = $buffer;
50
51 320
        if ([] !== $extensions) {
52 1
            $this->extensions = [];
53 1
            foreach ($extensions as $extension) {
54 1
                $this->extensions[$extension->getType()] = $extension;
55
            }
56
        }
57 320
    }
58
59 1
    public function extendWith(Extension $extension, Extension ...$extensions) : self
60
    {
61 1
        $new = clone $this;
62 1
        $new->extensions[$extension->getType()] = $extension;
63
64 1
        if ([] !== $extensions) {
65 1
            foreach ($extensions as $extraExtension) {
66 1
                $new->extensions[$extraExtension->getType()] = $extraExtension;
67
            }
68
        }
69
70 1
        return $new;
71
    }
72
73 2
    public function withBuffer(string $buffer) : self
74
    {
75 2
        $new = clone $this;
76 2
        $new->buffer = $buffer;
77 2
        $new->offset = 0;
78
79 2
        return $new;
80
    }
81
82 10
    public function append(string $data) : self
83
    {
84 10
        $this->buffer .= $data;
85
86 10
        return $this;
87
    }
88
89 293
    public function reset(string $buffer = '') : self
90
    {
91 293
        $this->buffer = $buffer;
92 293
        $this->offset = 0;
93
94 293
        return $this;
95
    }
96
97 3
    public function seek(int $offset) : self
98
    {
99 3
        if ($offset < 0) {
100 1
            $offset += \strlen($this->buffer);
101
        }
102
103 3
        if (!isset($this->buffer[$offset])) {
104 1
            throw new InsufficientDataException("Unable to seek to position $offset.");
105
        }
106
107 2
        $this->offset = $offset;
108
109 2
        return $this;
110
    }
111
112 2
    public function skip(int $length) : self
113
    {
114 2
        $offset = $this->offset + $length;
115
116 2
        if (!isset($this->buffer[$offset])) {
117 1
            throw new InsufficientDataException("Unable to seek to position $offset.");
118
        }
119
120 1
        $this->offset = $offset;
121
122 1
        return $this;
123
    }
124
125 2
    public function getRemainingCount() : int
126
    {
127 2
        return \strlen($this->buffer) - $this->offset;
128
    }
129
130 176
    public function hasRemaining() : bool
131
    {
132 176
        return isset($this->buffer[$this->offset]);
133
    }
134
135 1
    public function release() : int
136
    {
137 1
        if (0 === $this->offset) {
138 1
            return 0;
139
        }
140
141 1
        $releasedBytesCount = $this->offset;
142 1
        $this->buffer = isset($this->buffer[$this->offset]) ? \substr($this->buffer, $this->offset) : '';
143 1
        $this->offset = 0;
144
145 1
        return $releasedBytesCount;
146
    }
147
148
    /**
149
     * @param int $length
150
     *
151
     * @return string
152
     */
153 47
    public function read($length)
154
    {
155 47
        if (!isset($this->buffer[$this->offset + $length - 1])) {
156 1
            throw new InsufficientDataException();
157
        }
158
159 47
        $data = \substr($this->buffer, $this->offset, $length);
160 47
        $this->offset += $length;
161
162 47
        return $data;
163
    }
164
165 3
    public function tryUnpack() : array
166
    {
167 3
        $data = [];
168 3
        $offset = $this->offset;
169
170
        try {
171
            do {
172 3
                $data[] = $this->unpack();
173 3
                $offset = $this->offset;
174 3
            } while (isset($this->buffer[$this->offset]));
175 1
        } catch (InsufficientDataException $e) {
176 1
            $this->offset = $offset;
177
        }
178
179 3
        return $data;
180
    }
181
182 189
    public function unpack()
183
    {
184 189
        if (!isset($this->buffer[$this->offset])) {
185 4
            throw new InsufficientDataException();
186
        }
187
188 187
        $c = \ord($this->buffer[$this->offset]);
189 187
        ++$this->offset;
190
191
        // fixint
192 187
        if ($c <= 0x7f) {
193 29
            return $c;
194
        }
195
        // fixstr
196 175
        if ($c >= 0xa0 && $c <= 0xbf) {
197 16
            return ($c & 0x1f) ? $this->read($c & 0x1f) : '';
198
        }
199
        // negfixint
200 169
        if ($c >= 0xe0) {
201 5
            return $c - 0x100;
202
        }
203
204
        switch ($c) {
205 165
            case 0xc0: return null;
206 163
            case 0xc2: return false;
207 159
            case 0xc3: return true;
208
209
            // fixmap
210 151
            case 0x80: return [];
211 150
            case 0x81: return [$this->unpackMapKey() => $this->unpack()];
212 117
            case 0x82: return [$this->unpackMapKey() => $this->unpack(), $this->unpackMapKey() => $this->unpack()];
213 116
            case 0x83: return [$this->unpackMapKey() => $this->unpack(), $this->unpackMapKey() => $this->unpack(), $this->unpackMapKey() => $this->unpack()];
214 116
            case 0x84: return $this->unpackMapData(4);
215 116
            case 0x85: return $this->unpackMapData(5);
216 116
            case 0x86: return $this->unpackMapData(6);
217 116
            case 0x87: return $this->unpackMapData(7);
218 116
            case 0x88: return $this->unpackMapData(8);
219 116
            case 0x89: return $this->unpackMapData(9);
220 116
            case 0x8a: return $this->unpackMapData(10);
221 116
            case 0x8b: return $this->unpackMapData(11);
222 116
            case 0x8c: return $this->unpackMapData(12);
223 116
            case 0x8d: return $this->unpackMapData(13);
224 116
            case 0x8e: return $this->unpackMapData(14);
225 116
            case 0x8f: return $this->unpackMapData(15);
226
227
            // fixarray
228 116
            case 0x90: return [];
229 115
            case 0x91: return [$this->unpack()];
230 115
            case 0x92: return [$this->unpack(), $this->unpack()];
231 110
            case 0x93: return [$this->unpack(), $this->unpack(), $this->unpack()];
232 109
            case 0x94: return $this->unpackArrayData(4);
233 109
            case 0x95: return $this->unpackArrayData(5);
234 109
            case 0x96: return $this->unpackArrayData(6);
235 109
            case 0x97: return $this->unpackArrayData(7);
236 109
            case 0x98: return $this->unpackArrayData(8);
237 109
            case 0x99: return $this->unpackArrayData(9);
238 109
            case 0x9a: return $this->unpackArrayData(10);
239 109
            case 0x9b: return $this->unpackArrayData(11);
240 109
            case 0x9c: return $this->unpackArrayData(12);
241 109
            case 0x9d: return $this->unpackArrayData(13);
242 109
            case 0x9e: return $this->unpackArrayData(14);
243 109
            case 0x9f: return $this->unpackArrayData(15);
244
245
            // bin
246 109
            case 0xc4: return $this->read($this->unpackUint8());
247 104
            case 0xc5: return $this->read($this->unpackUint16());
248 103
            case 0xc6: return $this->read($this->unpackUint32());
249
250
            // float
251 102
            case 0xca: return $this->unpackFloat32();
252 99
            case 0xcb: return $this->unpackFloat64();
253
254
            // uint
255 95
            case 0xcc: return $this->unpackUint8();
256 91
            case 0xcd: return $this->unpackUint16();
257 85
            case 0xce: return $this->unpackUint32();
258 81
            case 0xcf: return $this->unpackUint64();
259
260
            // int
261 71
            case 0xd0: return $this->unpackInt8();
262 66
            case 0xd1: return $this->unpackInt16();
263 61
            case 0xd2: return $this->unpackInt32();
264 56
            case 0xd3: return $this->unpackInt64();
265
266
            // str
267 48
            case 0xd9: return $this->read($this->unpackUint8());
268 44
            case 0xda: return $this->read($this->unpackUint16());
269 42
            case 0xdb: return $this->read($this->unpackUint32());
270
271
            // array
272 41
            case 0xdc: return $this->unpackArrayData($this->unpackUint16());
273 39
            case 0xdd: return $this->unpackArrayData($this->unpackUint32());
274
275
            // map
276 38
            case 0xde: return $this->unpackMapData($this->unpackUint16());
277 36
            case 0xdf: return $this->unpackMapData($this->unpackUint32());
278
279
            // ext
280 35
            case 0xd4: return $this->unpackExtData(1);
281 30
            case 0xd5: return $this->unpackExtData(2);
282 27
            case 0xd6: return $this->unpackExtData(4);
283 24
            case 0xd7: return $this->unpackExtData(8);
284 21
            case 0xd8: return $this->unpackExtData(16);
285 18
            case 0xc7: return $this->unpackExtData($this->unpackUint8());
286 11
            case 0xc8: return $this->unpackExtData($this->unpackUint16());
287 6
            case 0xc9: return $this->unpackExtData($this->unpackUint32());
288
        }
289
290 1
        throw UnpackingFailedException::unknownCode($c);
291
    }
292
293 3
    public function unpackNil()
294
    {
295 3
        if (!isset($this->buffer[$this->offset])) {
296 1
            throw new InsufficientDataException();
297
        }
298
299 2
        if ("\xc0" === $this->buffer[$this->offset]) {
300 1
            ++$this->offset;
301
302 1
            return null;
303
        }
304
305 1
        throw UnpackingFailedException::unexpectedCode(\ord($this->buffer[$this->offset++]), 'nil');
306
    }
307
308 5
    public function unpackBool()
309
    {
310 5
        if (!isset($this->buffer[$this->offset])) {
311 1
            throw new InsufficientDataException();
312
        }
313
314 4
        $c = \ord($this->buffer[$this->offset]);
315 4
        ++$this->offset;
316
317 4
        if (0xc2 === $c) {
318 2
            return false;
319
        }
320 2
        if (0xc3 === $c) {
321 1
            return true;
322
        }
323
324 1
        throw UnpackingFailedException::unexpectedCode($c, 'bool');
325
    }
326
327 40
    public function unpackInt()
328
    {
329 40
        if (!isset($this->buffer[$this->offset])) {
330 1
            throw new InsufficientDataException();
331
        }
332
333 39
        $c = \ord($this->buffer[$this->offset]);
334 39
        ++$this->offset;
335
336
        // fixint
337 39
        if ($c <= 0x7f) {
338 3
            return $c;
339
        }
340
        // negfixint
341 36
        if ($c >= 0xe0) {
342 3
            return $c - 0x100;
343
        }
344
345
        switch ($c) {
346
            // uint
347 33
            case 0xcc: return $this->unpackUint8();
348 30
            case 0xcd: return $this->unpackUint16();
349 27
            case 0xce: return $this->unpackUint32();
350 24
            case 0xcf: return $this->unpackUint64();
351
352
            // int
353 20
            case 0xd0: return $this->unpackInt8();
354 16
            case 0xd1: return $this->unpackInt16();
355 12
            case 0xd2: return $this->unpackInt32();
356 8
            case 0xd3: return $this->unpackInt64();
357
        }
358
359 1
        throw UnpackingFailedException::unexpectedCode($c, 'int');
360
    }
361
362 7
    public function unpackFloat()
363
    {
364 7
        if (!isset($this->buffer[$this->offset])) {
365 1
            throw new InsufficientDataException();
366
        }
367
368 6
        $c = \ord($this->buffer[$this->offset]);
369 6
        ++$this->offset;
370
371 6
        if (0xcb === $c) {
372 3
            return $this->unpackFloat64();
373
        }
374 3
        if (0xca === $c) {
375 2
            return $this->unpackFloat32();
376
        }
377
378 1
        throw UnpackingFailedException::unexpectedCode($c, 'float');
379
    }
380
381 14
    public function unpackStr()
382
    {
383 14
        if (!isset($this->buffer[$this->offset])) {
384 1
            throw new InsufficientDataException();
385
        }
386
387 13
        $c = \ord($this->buffer[$this->offset]);
388 13
        ++$this->offset;
389
390 13
        if ($c >= 0xa0 && $c <= 0xbf) {
391 5
            return ($c & 0x1f) ? $this->read($c & 0x1f) : '';
392
        }
393 8
        if (0xd9 === $c) {
394 4
            return $this->read($this->unpackUint8());
395
        }
396 4
        if (0xda === $c) {
397 2
            return $this->read($this->unpackUint16());
398
        }
399 2
        if (0xdb === $c) {
400 1
            return $this->read($this->unpackUint32());
401
        }
402
403 1
        throw UnpackingFailedException::unexpectedCode($c, 'str');
404
    }
405
406 7
    public function unpackBin()
407
    {
408 7
        if (!isset($this->buffer[$this->offset])) {
409 1
            throw new InsufficientDataException();
410
        }
411
412 6
        $c = \ord($this->buffer[$this->offset]);
413 6
        ++$this->offset;
414
415 6
        if (0xc4 === $c) {
416 3
            return $this->read($this->unpackUint8());
417
        }
418 3
        if (0xc5 === $c) {
419 1
            return $this->read($this->unpackUint16());
420
        }
421 2
        if (0xc6 === $c) {
422 1
            return $this->read($this->unpackUint32());
423
        }
424
425 1
        throw UnpackingFailedException::unexpectedCode($c, 'bin');
426
    }
427
428 9
    public function unpackArray()
429
    {
430 9
        $size = $this->unpackArrayHeader();
431
432 7
        $array = [];
433 7
        while ($size--) {
434 6
            $array[] = $this->unpack();
435
        }
436
437 7
        return $array;
438
    }
439
440 9
    public function unpackArrayHeader()
441
    {
442 9
        if (!isset($this->buffer[$this->offset])) {
443 1
            throw new InsufficientDataException();
444
        }
445
446 8
        $c = \ord($this->buffer[$this->offset]);
447 8
        ++$this->offset;
448
449 8
        if ($c >= 0x90 && $c <= 0x9f) {
450 4
            return $c & 0xf;
451
        }
452 4
        if (0xdc === $c) {
453 2
            return $this->unpackUint16();
454
        }
455 2
        if (0xdd === $c) {
456 1
            return $this->unpackUint32();
457
        }
458
459 1
        throw UnpackingFailedException::unexpectedCode($c, 'array');
460
    }
461
462 43
    public function unpackMap()
463
    {
464 43
        $size = $this->unpackMapHeader();
465
466 41
        $map = [];
467 41
        while ($size--) {
468 40
            $map[$this->unpackMapKey()] = $this->unpack();
469
        }
470
471 9
        return $map;
472
    }
473
474 43
    public function unpackMapHeader()
475
    {
476 43
        if (!isset($this->buffer[$this->offset])) {
477 1
            throw new InsufficientDataException();
478
        }
479
480 42
        $c = \ord($this->buffer[$this->offset]);
481 42
        ++$this->offset;
482
483 42
        if ($c >= 0x80 && $c <= 0x8f) {
484 38
            return $c & 0xf;
485
        }
486 4
        if (0xde === $c) {
487 2
            return $this->unpackUint16();
488
        }
489 2
        if (0xdf === $c) {
490 1
            return $this->unpackUint32();
491
        }
492
493 1
        throw UnpackingFailedException::unexpectedCode($c, 'map');
494
    }
495
496 13
    public function unpackExt()
497
    {
498 13
        if (!isset($this->buffer[$this->offset])) {
499 1
            throw new InsufficientDataException();
500
        }
501
502 12
        $c = \ord($this->buffer[$this->offset]);
503 12
        ++$this->offset;
504
505
        switch ($c) {
506 12
            case 0xd4: return $this->unpackExtData(1);
507 11
            case 0xd5: return $this->unpackExtData(2);
508 10
            case 0xd6: return $this->unpackExtData(4);
509 9
            case 0xd7: return $this->unpackExtData(8);
510 8
            case 0xd8: return $this->unpackExtData(16);
511 7
            case 0xc7: return $this->unpackExtData($this->unpackUint8());
512 5
            case 0xc8: return $this->unpackExtData($this->unpackUint16());
513 3
            case 0xc9: return $this->unpackExtData($this->unpackUint32());
514
        }
515
516 1
        throw UnpackingFailedException::unexpectedCode($c, 'ext');
517
    }
518
519 38
    private function unpackUint8()
520
    {
521 38
        if (!isset($this->buffer[$this->offset])) {
522 2
            throw new InsufficientDataException();
523
        }
524
525 36
        return \ord($this->buffer[$this->offset++]);
526
    }
527
528 32
    private function unpackUint16()
529
    {
530 32
        if (!isset($this->buffer[$this->offset + 1])) {
531 2
            throw new InsufficientDataException();
532
        }
533
534 30
        return \ord($this->buffer[$this->offset++]) << 8
535 30
            | \ord($this->buffer[$this->offset++]);
536
    }
537
538 24
    private function unpackUint32()
539
    {
540 24
        if (!isset($this->buffer[$this->offset + 3])) {
541 2
            throw new InsufficientDataException();
542
        }
543
544 22
        return \ord($this->buffer[$this->offset++]) << 24
545 22
            | \ord($this->buffer[$this->offset++]) << 16
546 22
            | \ord($this->buffer[$this->offset++]) << 8
547 22
            | \ord($this->buffer[$this->offset++]);
548
    }
549
550 16
    private function unpackUint64()
551
    {
552 16
        if (!isset($this->buffer[$this->offset + 7])) {
553 1
            throw new InsufficientDataException();
554
        }
555
556 15
        $num = \unpack('J', $this->buffer, $this->offset)[1];
557 15
        $this->offset += 8;
558
559 15
        return $num < 0 ? $this->handleIntOverflow($num) : $num;
560
    }
561
562 9
    private function unpackInt8()
563
    {
564 9
        if (!isset($this->buffer[$this->offset])) {
565 1
            throw new InsufficientDataException();
566
        }
567
568 8
        $num = \ord($this->buffer[$this->offset]);
569 8
        ++$this->offset;
570
571 8
        return $num > 0x7f ? $num - 0x100 : $num;
572
    }
573
574 9
    private function unpackInt16()
575
    {
576 9
        if (!isset($this->buffer[$this->offset + 1])) {
577 1
            throw new InsufficientDataException();
578
        }
579
580 8
        $num = \ord($this->buffer[$this->offset]) << 8
581 8
            | \ord($this->buffer[++$this->offset]);
582 8
        ++$this->offset;
583
584 8
        return $num > 0x7fff ? $num - 0x10000 : $num;
585
    }
586
587 9
    private function unpackInt32()
588
    {
589 9
        if (!isset($this->buffer[$this->offset + 3])) {
590 1
            throw new InsufficientDataException();
591
        }
592
593 8
        $num = \ord($this->buffer[$this->offset]) << 24
594 8
            | \ord($this->buffer[++$this->offset]) << 16
595 8
            | \ord($this->buffer[++$this->offset]) << 8
596 8
            | \ord($this->buffer[++$this->offset]);
597 8
        ++$this->offset;
598
599 8
        return $num > 0x7fffffff ? $num - 0x100000000 : $num;
600
    }
601
602 15
    private function unpackInt64()
603
    {
604 15
        if (!isset($this->buffer[$this->offset + 7])) {
605 1
            throw new InsufficientDataException();
606
        }
607
608 14
        $num = \unpack('J', $this->buffer, $this->offset)[1];
609 14
        $this->offset += 8;
610
611 14
        return $num;
612
    }
613
614 5
    private function unpackFloat32()
615
    {
616 5
        if (!isset($this->buffer[$this->offset + 3])) {
617 1
            throw new InsufficientDataException();
618
        }
619
620 4
        $num = \unpack('G', $this->buffer, $this->offset)[1];
621 4
        $this->offset += 4;
622
623 4
        return $num;
624
    }
625
626 7
    private function unpackFloat64()
627
    {
628 7
        if (!isset($this->buffer[$this->offset + 7])) {
629 1
            throw new InsufficientDataException();
630
        }
631
632 6
        $num = \unpack('E', $this->buffer, $this->offset)[1];
633 6
        $this->offset += 8;
634
635 6
        return $num;
636
    }
637
638 4
    private function unpackArrayData($size)
639
    {
640 4
        $array = [];
641 4
        while ($size--) {
642 4
            $array[] = $this->unpack();
643
        }
644
645 4
        return $array;
646
    }
647
648 5
    private function unpackMapData($size)
649
    {
650 5
        $map = [];
651 5
        while ($size--) {
652 5
            $map[$this->unpackMapKey()] = $this->unpack();
653
        }
654
655 5
        return $map;
656
    }
657
658 82
    private function unpackMapKey()
659
    {
660 82
        if (!isset($this->buffer[$this->offset])) {
661
            throw new InsufficientDataException();
662
        }
663
664 82
        $c = \ord($this->buffer[$this->offset]);
665 82
        ++$this->offset;
666
667
        // fixint
668 82
        if ($c <= 0x7f) {
669 14
            return $c;
670
        }
671
        // fixstr
672 76
        if ($c >= 0xa0 && $c <= 0xbf) {
673 2
            return ($c & 0x1f) ? $this->read($c & 0x1f) : '';
674
        }
675
        // negfixint
676 74
        if ($c >= 0xe0) {
677 2
            return $c - 0x100;
678
        }
679
680
        switch ($c) {
681
            // uint
682 72
            case 0xcc: return $this->unpackUint8();
683 72
            case 0xcd: return $this->unpackUint16();
684 70
            case 0xce: return $this->unpackUint32();
685 68
            case 0xcf: return $this->unpackUint64();
686
687
            // int
688 66
            case 0xd0: return $this->unpackInt8();
689 66
            case 0xd1: return $this->unpackInt16();
690 66
            case 0xd2: return $this->unpackInt32();
691 66
            case 0xd3: return $this->unpackInt64();
692
693
            // str
694 66
            case 0xd9: return $this->read($this->unpackUint8());
695 66
            case 0xda: return $this->read($this->unpackUint16());
696 66
            case 0xdb: return $this->read($this->unpackUint32());
697
698
            // bin
699 66
            case 0xc4: return $this->read($this->unpackUint8());
700 64
            case 0xc5: return $this->read($this->unpackUint16());
701 64
            case 0xc6: return $this->read($this->unpackUint32());
702
        }
703
704 64
        throw UnpackingFailedException::invalidMapKeyType($c);
705
    }
706
707 42
    private function unpackExtData($length)
708
    {
709 42
        if (!isset($this->buffer[$this->offset + $length])) { // 1 (type) + length - 1
710 16
            throw new InsufficientDataException();
711
        }
712
713
        // int8
714 26
        $type = \ord($this->buffer[$this->offset]);
715 26
        ++$this->offset;
716
717 26
        if ($type > 0x7f) {
718
            $type -= 0x100;
719
        }
720
721 26
        if (isset($this->extensions[$type])) {
722 2
            return $this->extensions[$type]->unpackExt($this, $length);
723
        }
724
725 24
        $data = \substr($this->buffer, $this->offset, $length);
726 24
        $this->offset += $length;
727
728 24
        return new Ext($type, $data);
729
    }
730
731 5
    private function handleIntOverflow($value)
732
    {
733 5
        if ($this->isBigIntAsStr) {
734 3
            return \sprintf('%u', $value);
735
        }
736 2
        if ($this->isBigIntAsGmp) {
737 1
            return \gmp_init(\sprintf('%u', $value));
738
        }
739
740 1
        throw new IntegerOverflowException($value);
741
    }
742
}
743