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

RangeSetCalc::xor()   C

Complexity

Conditions 14
Paths 3

Size

Total Lines 59
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 45
c 1
b 0
f 0
dl 0
loc 59
rs 6.2666
cc 14
nc 3
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Remorhaz\UniLex\RegExp\FSM;
4
5
use Remorhaz\UniLex\Exception;
6
7
class RangeSetCalc
8
{
9
10
    public function equals(RangeSet $rangeSet, RangeSet $anotherRangeSet): bool
11
    {
12
        $rangeList = $rangeSet->getRanges();
13
        $anotherRangeList = $anotherRangeSet->getRanges();
14
        if (count($rangeList) != count($anotherRangeList)) {
15
            return false;
16
        }
17
        foreach ($rangeList as $index => $range) {
18
            $anotherRange = $anotherRangeList[$index];
19
            if ($range->getStart() != $anotherRange->getStart()) {
20
                return false;
21
            }
22
            if ($range->getFinish() != $anotherRange->getFinish()) {
23
                return false;
24
            }
25
        }
26
27
        return true;
28
    }
29
30
    /**
31
     * @param RangeSet $rangeSet
32
     * @param RangeSet $anotherRangeSet
33
     * @return RangeSet
34
     * @throws Exception
35
     */
36
    public function and(RangeSet $rangeSet, RangeSet $anotherRangeSet): RangeSet
37
    {
38
        $result = new RangeSet();
39
        foreach ($anotherRangeSet->getRanges() as $range) {
40
            $andRangeSetPart = $this->andSingleRange($rangeSet, $range);
41
            $result->addRange(...$andRangeSetPart->getRanges());
42
        }
43
44
        return $result;
45
    }
46
47
    /**
48
     * @param RangeSet $rangeSetPart
49
     * @param Range    $range
50
     * @return RangeSet
51
     * @throws Exception
52
     */
53
    private function andSingleRange(RangeSet $rangeSetPart, Range $range): RangeSet
54
    {
55
        $rangeSet = new RangeSet();
56
        if ($rangeSetPart->isEmpty()) {
57
            return $rangeSet;
58
        }
59
        foreach ($rangeSetPart->getRanges() as $existingRange) {
60
            if (!$existingRange->intersects($range)) {
61
                continue;
62
            }
63
            if ($range->startsBeforeStartOf($existingRange)) {
64
                $range = $range->copyAfterStartOf($existingRange);
65
            }
66
            if ($existingRange->endsBeforeFinishOf($range)) {
67
                $rangeSet->addRange($range->copyBeforeFinishOf($existingRange));
68
                $range = $range->copyAfterFinishOf($existingRange);
69
                continue;
70
            }
71
            $rangeSet->addRange($range);
72
        }
73
74
        return $rangeSet;
75
    }
76
77
    /**
78
     * @param RangeSet $rangeSet
79
     * @param RangeSet $anotherRangeSet
80
     * @return RangeSet
81
     * @throws Exception
82
     */
83
    public function xor(RangeSet $rangeSet, RangeSet $anotherRangeSet): RangeSet
84
    {
85
        $ranges = $rangeSet->getRanges();
86
        $otherRanges = $anotherRangeSet->getRanges();
87
        $index = 0;
88
        $anotherIndex = 0;
89
        $newRangeList = [];
90
        /** @var Range $rangeBuffer */
91
        $rangeBuffer = null;
92
        while (true) {
93
            $range = $ranges[$index] ?? null;
94
            $anotherRange = $otherRanges[$anotherIndex] ?? null;
95
96
            if (isset($range)) {
97
                if (isset($anotherRange) && $range->getStart() > $anotherRange->getStart()) {
98
                    $pickedRange = $anotherRange;
99
                    $anotherIndex++;
100
                } else {
101
                    $pickedRange = $range;
102
                    $index++;
103
                }
104
            } elseif (isset($anotherRange)) {
105
                $pickedRange = $anotherRange;
106
                $anotherIndex++;
107
            } else {
108
                if (isset($rangeBuffer)) {
109
                    $newRangeList[] = $rangeBuffer;
110
                }
111
                break;
112
            }
113
114
            if (isset($rangeBuffer)) {
115
                if ($rangeBuffer->intersects($pickedRange)) {
116
                    if ($rangeBuffer->startsBeforeStartOf($pickedRange)) {
117
                        $newRangeList[] = $rangeBuffer->copyBeforeStartOf($pickedRange);
118
                        $rangeBuffer = $rangeBuffer->copyAfterStartOf($pickedRange);
119
                    } elseif ($pickedRange->startsBeforeStartOf($rangeBuffer)) {
120
                        $newRangeList[] = $pickedRange->copyBeforeStartOf($rangeBuffer);
121
                        $rangeBuffer = $pickedRange->copyAfterStartOf($rangeBuffer);
122
                    }
123
                    if ($rangeBuffer->endsBeforeFinishOf($pickedRange)) {
124
                        $rangeBuffer = $pickedRange->copyAfterFinishOf($rangeBuffer);
125
                    } elseif ($pickedRange->endsBeforeFinishOf($rangeBuffer)) {
126
                        $rangeBuffer = $rangeBuffer->copyAfterFinishOf($pickedRange);
127
                    } else {
128
                        $rangeBuffer = null;
129
                    }
130
                    continue;
131
                }
132
                if ($pickedRange->follows($rangeBuffer)) {
133
                    $rangeBuffer = $rangeBuffer->copyBeforeFinishOf($pickedRange);
134
                    continue;
135
                }
136
                $newRangeList[] = $rangeBuffer;
137
            }
138
            $rangeBuffer = $pickedRange;
139
        }
140
141
        return RangeSet::loadUnsafe(...$newRangeList);
142
    }
143
}
144