Passed
Push — master ( 582f31...c01dfe )
by Edward
03:23
created

RangeSetCalc::andSingleRange()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 14
nc 7
nop 2
dl 0
loc 22
rs 9.2222
c 1
b 0
f 0
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
        $ranges = $rangeSet->getRanges();
39
        $otherRanges = $anotherRangeSet->getRanges();
40
        $index = 0;
41
        $anotherIndex = 0;
42
        $newRangeList = [];
43
        while (true) {
44
            $range = $ranges[$index] ?? null;
45
            $anotherRange = $otherRanges[$anotherIndex] ?? null;
46
47
            if (!isset($range, $anotherRange)) {
48
                break;
49
            }
50
            if (!$range->intersects($anotherRange)) {
51
                if ($range->getStart() < $anotherRange->getStart()) {
52
                    $index++;
53
                } else {
54
                    $anotherIndex++;
55
                }
56
                continue;
57
            }
58
            if ($range->startsBeforeStartOf($anotherRange)) {
59
                $range = $range->copyAfterStartOf($anotherRange);
60
            } elseif ($anotherRange->startsBeforeStartOf($range)) {
61
                $anotherRange = $anotherRange->copyAfterStartOf($range);
62
            }
63
            if ($range->endsBeforeFinishOf($anotherRange)) {
64
                $newRangeList[] = $range;
65
                $index++;
66
                continue;
67
            }
68
            if ($anotherRange->endsBeforeFinishOf($range)) {
69
                $newRangeList[] = $anotherRange;
70
                $anotherIndex++;
71
                continue;
72
            }
73
            $newRangeList[] = $range;
74
            $index++;
75
            $anotherIndex++;
76
        }
77
78
        return RangeSet::loadUnsafe(...$newRangeList);
79
    }
80
81
    /**
82
     * @param RangeSet $rangeSet
83
     * @param RangeSet $anotherRangeSet
84
     * @return RangeSet
85
     * @throws Exception
86
     */
87
    public function xor(RangeSet $rangeSet, RangeSet $anotherRangeSet): RangeSet
88
    {
89
        $ranges = $rangeSet->getRanges();
90
        $otherRanges = $anotherRangeSet->getRanges();
91
        $index = 0;
92
        $anotherIndex = 0;
93
        $newRangeList = [];
94
        /** @var Range $rangeBuffer */
95
        $rangeBuffer = null;
96
        while (true) {
97
            $range = $ranges[$index] ?? null;
98
            $anotherRange = $otherRanges[$anotherIndex] ?? null;
99
100
            if (isset($range)) {
101
                if (isset($anotherRange) && $range->getStart() > $anotherRange->getStart()) {
102
                    $pickedRange = $anotherRange;
103
                    $anotherIndex++;
104
                } else {
105
                    $pickedRange = $range;
106
                    $index++;
107
                }
108
            } elseif (isset($anotherRange)) {
109
                $pickedRange = $anotherRange;
110
                $anotherIndex++;
111
            } else {
112
                if (isset($rangeBuffer)) {
113
                    $newRangeList[] = $rangeBuffer;
114
                }
115
                break;
116
            }
117
118
            if (isset($rangeBuffer)) {
119
                if ($rangeBuffer->intersects($pickedRange)) {
120
                    if ($rangeBuffer->startsBeforeStartOf($pickedRange)) {
121
                        $newRangeList[] = $rangeBuffer->copyBeforeStartOf($pickedRange);
122
                        $rangeBuffer = $rangeBuffer->copyAfterStartOf($pickedRange);
123
                    } elseif ($pickedRange->startsBeforeStartOf($rangeBuffer)) {
124
                        $newRangeList[] = $pickedRange->copyBeforeStartOf($rangeBuffer);
125
                        $rangeBuffer = $pickedRange->copyAfterStartOf($rangeBuffer);
126
                    }
127
                    if ($rangeBuffer->endsBeforeFinishOf($pickedRange)) {
128
                        $rangeBuffer = $pickedRange->copyAfterFinishOf($rangeBuffer);
129
                    } elseif ($pickedRange->endsBeforeFinishOf($rangeBuffer)) {
130
                        $rangeBuffer = $rangeBuffer->copyAfterFinishOf($pickedRange);
131
                    } else {
132
                        $rangeBuffer = null;
133
                    }
134
                    continue;
135
                }
136
                if ($pickedRange->follows($rangeBuffer)) {
137
                    $rangeBuffer = $rangeBuffer->copyBeforeFinishOf($pickedRange);
138
                    continue;
139
                }
140
                $newRangeList[] = $rangeBuffer;
141
            }
142
            $rangeBuffer = $pickedRange;
143
        }
144
145
        return RangeSet::loadUnsafe(...$newRangeList);
146
    }
147
}
148