Passed
Push — master ( eff209...0e7332 )
by Edward
05:02
created

PropertiesRangeIterator   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 59
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
eloc 33
c 1
b 0
f 0
dl 0
loc 59
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A fetchPropertyRange() 0 23 5
A getIterator() 0 10 3
A __construct() 0 4 1
A fetchNextLine() 0 8 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\UniLex\Tool\RegExp;
6
7
use Iterator;
8
use IteratorAggregate;
9
use Remorhaz\UniLex\RegExp\FSM\Range;
10
use SplFileObject;
11
use Throwable;
12
13
final class PropertiesRangeIterator implements IteratorAggregate
14
{
15
16
    private $file;
17
18
    private $onProgress;
19
20
    public function __construct(SplFileObject $file, callable $onProgress)
21
    {
22
        $this->file = $file;
23
        $this->onProgress = $onProgress;
24
    }
25
26
    public function getIterator(): Iterator
27
    {
28
        while (!$this->file->eof()) {
29
            $line = $this->fetchNextLine($this->file);
30
            if (!isset($line)) {
31
                continue;
32
            }
33
            yield from $this->fetchPropertyRange($line);
34
35
            ($this->onProgress)(strlen($line));
36
        }
37
    }
38
39
    private function fetchNextLine(SplFileObject $file): ?string
40
    {
41
        $line = $file->fgets();
42
        if (false === $line) {
43
            throw new Exception\LineNotReadException($file->getFilename());
44
        }
45
46
        return '' == $line ? null : $line;
47
    }
48
49
    private function fetchPropertyRange(string $line): Iterator
50
    {
51
        $dataWithComment = explode('#', $line, 2);
52
        $data = trim($dataWithComment[0] ?? '');
53
        if ('' == $data) {
54
            return null;
55
        }
56
        $rangeWithProp = explode(';', $data);
57
        $unSplitRange = trim($rangeWithProp[0] ?? null);
58
        $prop = trim($rangeWithProp[1] ?? null);
59
        if (!isset($unSplitRange, $prop)) {
60
            throw new Exception\InvalidLineException($line);
61
        }
62
        $splitRange = explode('..', $unSplitRange);
63
        $start = hexdec($splitRange[0]);
64
        $finish = isset($splitRange[1])
65
            ? hexdec($splitRange[1])
66
            : $start;
67
68
        try {
69
            yield $prop => new Range($start, $finish);
0 ignored issues
show
Bug introduced by
It seems like $finish can also be of type double; however, parameter $finish of Remorhaz\UniLex\RegExp\FSM\Range::__construct() does only seem to accept integer|null, 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

69
            yield $prop => new Range($start, /** @scrutinizer ignore-type */ $finish);
Loading history...
Bug introduced by
It seems like $start can also be of type double; however, parameter $start of Remorhaz\UniLex\RegExp\FSM\Range::__construct() 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

69
            yield $prop => new Range(/** @scrutinizer ignore-type */ $start, $finish);
Loading history...
70
        } catch (Throwable $e) {
71
            throw new Exception\RangeNotCreatedException($e);
72
        }
73
    }
74
}
75