Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like BufferUnpacker often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use BufferUnpacker, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class BufferUnpacker |
||
21 | { |
||
22 | private $buffer; |
||
23 | private $offset = 0; |
||
24 | private $isBigIntAsStr; |
||
25 | private $isBigIntAsGmp; |
||
26 | |||
27 | /** |
||
28 | * @var CanUnpackExt[] |
||
29 | */ |
||
30 | private $transformers = []; |
||
31 | |||
32 | /** |
||
33 | * @param string $buffer |
||
34 | * @param UnpackOptions|int|null $options |
||
35 | * @param CanUnpackExt[] $transformers |
||
36 | * |
||
37 | * @throws InvalidOptionException |
||
38 | */ |
||
39 | 243 | public function __construct(string $buffer = '', $options = null, array $transformers = []) |
|
40 | { |
||
41 | 243 | if (null === $options) { |
|
42 | 242 | $options = UnpackOptions::fromDefaults(); |
|
43 | 8 | } elseif (!$options instanceof PackOptions) { |
|
44 | 8 | $options = UnpackOptions::fromBitmask($options); |
|
|
|||
45 | } |
||
46 | |||
47 | 243 | $this->isBigIntAsStr = $options->isBigIntAsStrMode(); |
|
48 | 243 | $this->isBigIntAsGmp = $options->isBigIntAsGmpMode(); |
|
49 | |||
50 | 243 | $this->buffer = $buffer; |
|
51 | |||
52 | 243 | if ([] !== $transformers) { |
|
53 | 1 | $this->transformers = []; |
|
54 | 1 | foreach ($transformers as $transformer) { |
|
55 | 1 | $this->transformers[$transformer->getType()] = $transformer; |
|
56 | } |
||
57 | } |
||
58 | 243 | } |
|
59 | |||
60 | 1 | public function extendWith(CanUnpackExt $transformer, CanUnpackExt ...$transformers) : self |
|
61 | { |
||
62 | 1 | $new = clone $this; |
|
63 | 1 | $new->transformers[$transformer->getType()] = $transformer; |
|
64 | |||
65 | 1 | if ([] !== $transformers) { |
|
66 | 1 | foreach ($transformers as $extraTransformer) { |
|
67 | 1 | $new->transformers[$extraTransformer->getType()] = $extraTransformer; |
|
68 | } |
||
69 | } |
||
70 | |||
71 | 1 | return $new; |
|
72 | } |
||
73 | |||
74 | 10 | public function append(string $data) : self |
|
80 | |||
81 | 216 | public function reset(string $buffer = '') : self |
|
82 | { |
||
83 | 216 | $this->buffer = $buffer; |
|
84 | 216 | $this->offset = 0; |
|
85 | |||
86 | 216 | return $this; |
|
87 | } |
||
88 | |||
89 | 3 | View Code Duplication | public function seek(int $offset) : self |
90 | { |
||
91 | 3 | if ($offset < 0) { |
|
92 | 1 | $offset += \strlen($this->buffer); |
|
93 | } |
||
94 | |||
95 | 3 | if (!isset($this->buffer[$offset])) { |
|
96 | 1 | throw new \OutOfBoundsException("Unable to seek to position $offset."); |
|
97 | } |
||
98 | |||
99 | 2 | $this->offset = $offset; |
|
100 | |||
101 | 2 | return $this; |
|
102 | } |
||
103 | |||
104 | 2 | View Code Duplication | public function skip(int $offset) : self |
116 | |||
117 | 2 | public function withBuffer(string $buffer) : self |
|
118 | { |
||
119 | 2 | $new = clone $this; |
|
120 | 2 | $new->buffer = $buffer; |
|
121 | 2 | $new->offset = 0; |
|
122 | |||
123 | 2 | return $new; |
|
124 | } |
||
125 | |||
126 | 3 | public function tryUnpack() : array |
|
127 | { |
||
128 | 3 | $data = []; |
|
129 | 3 | $offset = $this->offset; |
|
130 | |||
131 | try { |
||
132 | do { |
||
133 | 3 | $data[] = $this->unpack(); |
|
134 | 3 | $offset = $this->offset; |
|
135 | 3 | } while (isset($this->buffer[$this->offset])); |
|
136 | 1 | } catch (InsufficientDataException $e) { |
|
137 | 1 | $this->offset = $offset; |
|
138 | } |
||
139 | |||
140 | 3 | if ($this->offset) { |
|
141 | 3 | $this->buffer = isset($this->buffer[$this->offset]) ? \substr($this->buffer, $this->offset) : ''; |
|
142 | 3 | $this->offset = 0; |
|
143 | } |
||
144 | |||
145 | 3 | return $data; |
|
146 | } |
||
147 | |||
148 | 148 | public function unpack() |
|
149 | { |
||
150 | 148 | if (!isset($this->buffer[$this->offset])) { |
|
151 | 5 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
152 | } |
||
153 | |||
154 | 145 | $c = \ord($this->buffer[$this->offset]); |
|
155 | 145 | ++$this->offset; |
|
156 | |||
157 | // fixint |
||
158 | 145 | if ($c <= 0x7f) { |
|
159 | 31 | return $c; |
|
160 | } |
||
161 | // fixstr |
||
162 | 138 | View Code Duplication | if ($c >= 0xa0 && $c <= 0xbf) { |
163 | 18 | return ($c & 0x1f) ? $this->unpackStrData($c & 0x1f) : ''; |
|
164 | } |
||
165 | // negfixint |
||
166 | 131 | if ($c >= 0xe0) { |
|
167 | 5 | return $c - 0x100; |
|
168 | } |
||
169 | |||
170 | 127 | switch ($c) { |
|
171 | 127 | case 0xc0: return null; |
|
172 | 125 | case 0xc2: return false; |
|
173 | 120 | case 0xc3: return true; |
|
174 | |||
175 | // fixmap |
||
176 | 111 | case 0x80: return []; |
|
177 | 110 | case 0x81: return [$this->unpack() => $this->unpack()]; |
|
178 | 107 | case 0x82: return [$this->unpack() => $this->unpack(), $this->unpack() => $this->unpack()]; |
|
179 | 104 | case 0x83: return [$this->unpack() => $this->unpack(), $this->unpack() => $this->unpack(), $this->unpack() => $this->unpack()]; |
|
180 | 104 | case 0x84: return $this->unpackMapData(4); |
|
181 | 104 | case 0x85: return $this->unpackMapData(5); |
|
182 | 104 | case 0x86: return $this->unpackMapData(6); |
|
183 | 104 | case 0x87: return $this->unpackMapData(7); |
|
184 | 104 | case 0x88: return $this->unpackMapData(8); |
|
185 | 104 | case 0x89: return $this->unpackMapData(9); |
|
186 | 104 | case 0x8a: return $this->unpackMapData(10); |
|
187 | 104 | case 0x8b: return $this->unpackMapData(11); |
|
188 | 104 | case 0x8c: return $this->unpackMapData(12); |
|
189 | 104 | case 0x8d: return $this->unpackMapData(13); |
|
190 | 104 | case 0x8e: return $this->unpackMapData(14); |
|
191 | 104 | case 0x8f: return $this->unpackMapData(15); |
|
192 | |||
193 | // fixarray |
||
194 | 104 | case 0x90: return []; |
|
195 | 103 | case 0x91: return [$this->unpack()]; |
|
196 | 103 | case 0x92: return [$this->unpack(), $this->unpack()]; |
|
197 | 100 | case 0x93: return [$this->unpack(), $this->unpack(), $this->unpack()]; |
|
198 | 99 | case 0x94: return $this->unpackArrayData(4); |
|
199 | 99 | case 0x95: return $this->unpackArrayData(5); |
|
200 | 99 | case 0x96: return $this->unpackArrayData(6); |
|
201 | 99 | case 0x97: return $this->unpackArrayData(7); |
|
202 | 99 | case 0x98: return $this->unpackArrayData(8); |
|
203 | 99 | case 0x99: return $this->unpackArrayData(9); |
|
204 | 99 | case 0x9a: return $this->unpackArrayData(10); |
|
205 | 99 | case 0x9b: return $this->unpackArrayData(11); |
|
206 | 99 | case 0x9c: return $this->unpackArrayData(12); |
|
207 | 99 | case 0x9d: return $this->unpackArrayData(13); |
|
208 | 99 | case 0x9e: return $this->unpackArrayData(14); |
|
209 | 99 | case 0x9f: return $this->unpackArrayData(15); |
|
210 | |||
211 | // bin |
||
212 | 99 | case 0xc4: return $this->unpackStrData($this->unpackUint8()); |
|
213 | 94 | case 0xc5: return $this->unpackStrData($this->unpackUint16()); |
|
214 | 93 | case 0xc6: return $this->unpackStrData($this->unpackUint32()); |
|
215 | |||
216 | // float |
||
217 | 92 | case 0xca: return $this->unpackFloat32(); |
|
218 | 89 | case 0xcb: return $this->unpackFloat64(); |
|
219 | |||
220 | // uint |
||
221 | 85 | case 0xcc: return $this->unpackUint8(); |
|
222 | 81 | case 0xcd: return $this->unpackUint16(); |
|
223 | 74 | case 0xce: return $this->unpackUint32(); |
|
224 | 69 | case 0xcf: return $this->unpackUint64(); |
|
225 | |||
226 | // int |
||
227 | 57 | case 0xd0: return $this->unpackInt8(); |
|
228 | 52 | case 0xd1: return $this->unpackInt16(); |
|
229 | 47 | case 0xd2: return $this->unpackInt32(); |
|
230 | 42 | case 0xd3: return $this->unpackInt64(); |
|
231 | |||
232 | // str |
||
233 | 34 | case 0xd9: return $this->unpackStrData($this->unpackUint8()); |
|
234 | 30 | case 0xda: return $this->unpackStrData($this->unpackUint16()); |
|
235 | 28 | case 0xdb: return $this->unpackStrData($this->unpackUint32()); |
|
236 | |||
237 | // array |
||
238 | 27 | case 0xdc: return $this->unpackArrayData($this->unpackUint16()); |
|
239 | 25 | case 0xdd: return $this->unpackArrayData($this->unpackUint32()); |
|
240 | |||
241 | // map |
||
242 | 24 | case 0xde: return $this->unpackMapData($this->unpackUint16()); |
|
243 | 22 | case 0xdf: return $this->unpackMapData($this->unpackUint32()); |
|
244 | |||
245 | // ext |
||
246 | 21 | case 0xd4: return $this->unpackExtData(1); |
|
247 | 17 | case 0xd5: return $this->unpackExtData(2); |
|
248 | 15 | case 0xd6: return $this->unpackExtData(4); |
|
249 | 13 | case 0xd7: return $this->unpackExtData(8); |
|
250 | 11 | case 0xd8: return $this->unpackExtData(16); |
|
251 | 9 | case 0xc7: return $this->unpackExtData($this->unpackUint8()); |
|
252 | 5 | case 0xc8: return $this->unpackExtData($this->unpackUint16()); |
|
253 | 3 | case 0xc9: return $this->unpackExtData($this->unpackUint32()); |
|
254 | } |
||
255 | |||
256 | 1 | throw UnpackingFailedException::unknownCode($c); |
|
257 | } |
||
258 | |||
259 | 3 | public function unpackNil() |
|
260 | { |
||
261 | 3 | if (!isset($this->buffer[$this->offset])) { |
|
262 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
263 | } |
||
264 | |||
265 | 2 | if ("\xc0" === $this->buffer[$this->offset]) { |
|
266 | 1 | ++$this->offset; |
|
267 | |||
268 | 1 | return null; |
|
269 | } |
||
270 | |||
271 | 1 | throw UnpackingFailedException::unexpectedCode(\ord($this->buffer[$this->offset++]), 'nil'); |
|
272 | } |
||
273 | |||
274 | 5 | public function unpackBool() |
|
275 | { |
||
276 | 5 | if (!isset($this->buffer[$this->offset])) { |
|
277 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
278 | } |
||
279 | |||
280 | 4 | $c = \ord($this->buffer[$this->offset]); |
|
281 | 4 | ++$this->offset; |
|
282 | |||
283 | 4 | if (0xc2 === $c) { |
|
284 | 2 | return false; |
|
285 | } |
||
286 | 2 | if (0xc3 === $c) { |
|
287 | 1 | return true; |
|
288 | } |
||
289 | |||
290 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'bool'); |
|
291 | } |
||
292 | |||
293 | 40 | public function unpackInt() |
|
327 | |||
328 | 7 | public function unpackFloat() |
|
346 | |||
347 | 14 | public function unpackStr() |
|
348 | { |
||
349 | 14 | if (!isset($this->buffer[$this->offset])) { |
|
350 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
351 | } |
||
352 | |||
353 | 13 | $c = \ord($this->buffer[$this->offset]); |
|
354 | 13 | ++$this->offset; |
|
355 | |||
356 | 13 | View Code Duplication | if ($c >= 0xa0 && $c <= 0xbf) { |
357 | 5 | return ($c & 0x1f) ? $this->unpackStrData($c & 0x1f) : ''; |
|
358 | } |
||
359 | 8 | if (0xd9 === $c) { |
|
360 | 4 | return $this->unpackStrData($this->unpackUint8()); |
|
361 | } |
||
362 | 4 | if (0xda === $c) { |
|
363 | 2 | return $this->unpackStrData($this->unpackUint16()); |
|
364 | } |
||
365 | 2 | if (0xdb === $c) { |
|
366 | 1 | return $this->unpackStrData($this->unpackUint32()); |
|
367 | } |
||
368 | |||
369 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'str'); |
|
370 | } |
||
371 | |||
372 | 7 | public function unpackBin() |
|
373 | { |
||
374 | 7 | if (!isset($this->buffer[$this->offset])) { |
|
375 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
376 | } |
||
377 | |||
378 | 6 | $c = \ord($this->buffer[$this->offset]); |
|
379 | 6 | ++$this->offset; |
|
380 | |||
381 | 6 | if (0xc4 === $c) { |
|
382 | 3 | return $this->unpackStrData($this->unpackUint8()); |
|
383 | } |
||
384 | 3 | if (0xc5 === $c) { |
|
385 | 1 | return $this->unpackStrData($this->unpackUint16()); |
|
386 | } |
||
387 | 2 | if (0xc6 === $c) { |
|
388 | 1 | return $this->unpackStrData($this->unpackUint32()); |
|
389 | } |
||
390 | |||
391 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'bin'); |
|
392 | } |
||
393 | |||
394 | 9 | public function unpackArray() |
|
405 | |||
406 | 9 | View Code Duplication | public function unpackArrayHeader() |
407 | { |
||
408 | 9 | if (!isset($this->buffer[$this->offset])) { |
|
409 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
410 | } |
||
411 | |||
412 | 8 | $c = \ord($this->buffer[$this->offset]); |
|
413 | 8 | ++$this->offset; |
|
414 | |||
415 | 8 | if ($c >= 0x90 && $c <= 0x9f) { |
|
416 | 4 | return $c & 0xf; |
|
417 | } |
||
418 | 4 | if (0xdc === $c) { |
|
419 | 2 | return $this->unpackUint16(); |
|
420 | } |
||
421 | 2 | if (0xdd === $c) { |
|
422 | 1 | return $this->unpackUint32(); |
|
423 | } |
||
424 | |||
425 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'array header'); |
|
426 | } |
||
427 | |||
428 | 13 | public function unpackMap() |
|
439 | |||
440 | 13 | View Code Duplication | public function unpackMapHeader() |
441 | { |
||
442 | 13 | if (!isset($this->buffer[$this->offset])) { |
|
443 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
444 | } |
||
445 | |||
446 | 12 | $c = \ord($this->buffer[$this->offset]); |
|
447 | 12 | ++$this->offset; |
|
448 | |||
449 | 12 | if ($c >= 0x80 && $c <= 0x8f) { |
|
450 | 8 | return $c & 0xf; |
|
451 | } |
||
452 | 4 | if (0xde === $c) { |
|
453 | 2 | return $this->unpackUint16(); |
|
454 | } |
||
455 | 2 | if (0xdf === $c) { |
|
456 | 1 | return $this->unpackUint32(); |
|
457 | } |
||
458 | |||
459 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'map header'); |
|
460 | } |
||
461 | |||
462 | 10 | public function unpackExt() |
|
463 | { |
||
464 | 10 | if (!isset($this->buffer[$this->offset])) { |
|
465 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
466 | } |
||
467 | |||
468 | 9 | $c = \ord($this->buffer[$this->offset]); |
|
469 | 9 | ++$this->offset; |
|
470 | |||
471 | 9 | switch ($c) { |
|
472 | 9 | case 0xd4: return $this->unpackExtData(1); |
|
473 | 8 | case 0xd5: return $this->unpackExtData(2); |
|
474 | 7 | case 0xd6: return $this->unpackExtData(4); |
|
475 | 6 | case 0xd7: return $this->unpackExtData(8); |
|
476 | 5 | case 0xd8: return $this->unpackExtData(16); |
|
477 | 4 | case 0xc7: return $this->unpackExtData($this->unpackUint8()); |
|
478 | 3 | case 0xc8: return $this->unpackExtData($this->unpackUint16()); |
|
479 | 2 | case 0xc9: return $this->unpackExtData($this->unpackUint32()); |
|
480 | } |
||
481 | |||
482 | 1 | throw UnpackingFailedException::unexpectedCode($c, 'ext header'); |
|
483 | } |
||
484 | |||
485 | 34 | private function unpackUint8() |
|
493 | |||
494 | 28 | private function unpackUint16() |
|
495 | { |
||
496 | 28 | if (!isset($this->buffer[$this->offset + 1])) { |
|
497 | 2 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 2); |
|
498 | } |
||
499 | |||
500 | 26 | $hi = \ord($this->buffer[$this->offset]); |
|
501 | 26 | $lo = \ord($this->buffer[++$this->offset]); |
|
502 | 26 | ++$this->offset; |
|
503 | |||
504 | 26 | return $hi << 8 | $lo; |
|
505 | } |
||
506 | |||
507 | 20 | private function unpackUint32() |
|
508 | { |
||
509 | 20 | if (!isset($this->buffer[$this->offset + 3])) { |
|
510 | 2 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 4); |
|
511 | } |
||
512 | |||
513 | 18 | $num = \unpack('N', $this->buffer, $this->offset)[1]; |
|
514 | 18 | $this->offset += 4; |
|
515 | |||
516 | 18 | return $num; |
|
517 | } |
||
518 | |||
519 | 16 | View Code Duplication | private function unpackUint64() |
520 | { |
||
521 | 16 | if (!isset($this->buffer[$this->offset + 7])) { |
|
522 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 8); |
|
523 | } |
||
524 | |||
525 | 15 | $num = \unpack('J', $this->buffer, $this->offset)[1]; |
|
526 | 15 | $this->offset += 8; |
|
527 | |||
528 | 15 | return $num < 0 ? $this->handleIntOverflow($num) : $num; |
|
529 | } |
||
530 | |||
531 | 9 | private function unpackInt8() |
|
532 | { |
||
533 | 9 | if (!isset($this->buffer[$this->offset])) { |
|
534 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); |
|
535 | } |
||
536 | |||
537 | 8 | $num = \ord($this->buffer[$this->offset]); |
|
538 | 8 | ++$this->offset; |
|
539 | |||
540 | 8 | return $num > 0x7f ? $num - 0x100 : $num; |
|
541 | } |
||
542 | |||
543 | 9 | private function unpackInt16() |
|
544 | { |
||
545 | 9 | if (!isset($this->buffer[$this->offset + 1])) { |
|
546 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 2); |
|
547 | } |
||
548 | |||
549 | 8 | $hi = \ord($this->buffer[$this->offset]); |
|
550 | 8 | $lo = \ord($this->buffer[++$this->offset]); |
|
551 | 8 | ++$this->offset; |
|
552 | |||
553 | 8 | return $hi > 0x7f ? $hi << 8 | $lo - 0x10000 : $hi << 8 | $lo; |
|
554 | } |
||
555 | |||
556 | 9 | View Code Duplication | private function unpackInt32() |
557 | { |
||
558 | 9 | if (!isset($this->buffer[$this->offset + 3])) { |
|
559 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 4); |
|
560 | } |
||
561 | |||
562 | 8 | $num = \unpack('N', $this->buffer, $this->offset)[1]; |
|
563 | 8 | $this->offset += 4; |
|
564 | |||
565 | 8 | return $num > 0x7fffffff ? $num - 0x100000000 : $num; |
|
566 | } |
||
567 | |||
568 | 15 | private function unpackInt64() |
|
569 | { |
||
570 | 15 | if (!isset($this->buffer[$this->offset + 7])) { |
|
571 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 8); |
|
572 | } |
||
573 | |||
574 | 14 | $num = \unpack('J', $this->buffer, $this->offset)[1]; |
|
575 | 14 | $this->offset += 8; |
|
576 | |||
577 | 14 | return $num; |
|
578 | } |
||
579 | |||
580 | 5 | private function unpackFloat32() |
|
581 | { |
||
582 | 5 | if (!isset($this->buffer[$this->offset + 3])) { |
|
583 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 4); |
|
584 | } |
||
585 | |||
586 | 4 | $num = \unpack('G', $this->buffer, $this->offset)[1]; |
|
587 | 4 | $this->offset += 4; |
|
588 | |||
589 | 4 | return $num; |
|
590 | } |
||
591 | |||
592 | 7 | private function unpackFloat64() |
|
593 | { |
||
594 | 7 | if (!isset($this->buffer[$this->offset + 7])) { |
|
595 | 1 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 8); |
|
596 | } |
||
597 | |||
598 | 6 | $num = \unpack('E', $this->buffer, $this->offset)[1]; |
|
599 | 6 | $this->offset += 8; |
|
600 | |||
601 | 6 | return $num; |
|
602 | } |
||
603 | |||
604 | 47 | private function unpackStrData($length) |
|
615 | |||
616 | 4 | private function unpackArrayData($size) |
|
617 | { |
||
618 | 4 | $array = []; |
|
619 | 4 | while ($size--) { |
|
620 | 4 | $array[] = $this->unpack(); |
|
621 | } |
||
622 | |||
623 | 4 | return $array; |
|
624 | } |
||
625 | |||
626 | 5 | private function unpackMapData($size) |
|
627 | { |
||
628 | 5 | $map = []; |
|
629 | 5 | while ($size--) { |
|
630 | 5 | $map[$this->unpack()] = $this->unpack(); |
|
631 | } |
||
632 | |||
633 | 5 | return $map; |
|
634 | } |
||
635 | |||
636 | 25 | private function unpackExtData($length) |
|
637 | { |
||
638 | 25 | if (!isset($this->buffer[$this->offset + $length - 1])) { |
|
639 | 5 | throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, $length); |
|
640 | } |
||
659 | |||
660 | 5 | private function handleIntOverflow($value) |
|
671 | } |
||
672 |
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:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.