Code Duplication    Length = 281-281 lines in 2 locations

src/IPv4/IPv4Interval.php 1 location

@@ 20-300 (lines=281) @@
17
use GpsLab\Component\Interval\IntervalPointInterface;
18
use GpsLab\Component\Interval\IntervalType;
19
20
class IPv4Interval implements ComparableIntervalInterface
21
{
22
    /**
23
     * @var string
24
     */
25
    const REGEXP = '/^
26
        (?:\(|\[)                                    # start type char
27
        \s*
28
        (?<start>\d{1-3}\.\d{1-3}\.\d{1-3}\.\d{1-3}) # start point
29
        \s*,\s*                                      # separator
30
        (?<end>\d{1-3}\.\d{1-3}\.\d{1-3}\.\d{1-3})   # end point
31
        \s*
32
        (?:\)|\])                                    # end type char
33
    $/x';
34
35
    /**
36
     * @var IntervalType
37
     */
38
    private $type;
39
40
    /**
41
     * @var IntervalComparator
42
     */
43
    private $comparator;
44
45
    /**
46
     * @var IPv4IntervalPoint
47
     */
48
    private $start;
49
50
    /**
51
     * @var IPv4IntervalPoint
52
     */
53
    private $end;
54
55
    /**
56
     * @param IPv4IntervalPoint $start
57
     * @param IPv4IntervalPoint $end
58
     * @param IntervalType $type
59
     */
60
    private function __construct(IPv4IntervalPoint $start, IPv4IntervalPoint $end, IntervalType $type)
61
    {
62
        if ($start->gte($end)) {
63
            throw IncorrectIntervalException::create();
64
        }
65
66
        $this->type = $type;
67
        $this->start = $start;
68
        $this->end = $end;
69
        $this->comparator = new IntervalComparator($this);
70
    }
71
72
    /**
73
     * @param string $start
74
     * @param string $end
75
     * @param IntervalType $type
76
     *
77
     * @return self
78
     */
79
    public static function create($start, $end, IntervalType $type)
80
    {
81
        return new self(new IPv4IntervalPoint($start), new IPv4IntervalPoint($end), $type);
82
    }
83
84
    /**
85
     * @param string $start
86
     * @param string $end
87
     *
88
     * @return self
89
     */
90
    public static function closed($start, $end)
91
    {
92
        return static::create($start, $end, IntervalType::closed());
93
    }
94
95
    /**
96
     * @param string $start
97
     * @param string $end
98
     *
99
     * @return self
100
     */
101
    public static function halfClosed($start, $end)
102
    {
103
        return static::create($start, $end, IntervalType::halfClosed());
104
    }
105
106
    /**
107
     * @param string $start
108
     * @param string $end
109
     *
110
     * @return self
111
     */
112
    public static function halfOpen($start, $end)
113
    {
114
        return static::create($start, $end, IntervalType::halfOpen());
115
    }
116
117
    /**
118
     * @param string $start
119
     * @param string $end
120
     *
121
     * @return self
122
     */
123
    public static function open($start, $end)
124
    {
125
        return static::create($start, $end, IntervalType::open());
126
    }
127
128
    /**
129
     * Create interval from string.
130
     *
131
     * Example formats for all interval types:
132
     *   [10.0.1.0, 10.0.1.255]
133
     *   (10.0.0.0, 10.255.255.255]
134
     *   [172.16.0.0, 172.31.255.255)
135
     *   (192.168.0.0, 192.168.255.255)
136
     *
137
     * Spaces are ignored in format.
138
     *
139
     * @param string $string
140
     *
141
     * @return self
142
     */
143
    public static function fromString($string)
144
    {
145
        if (!preg_match(self::REGEXP, $string, $match)) {
146
            throw InvalidIntervalFormatException::create('[0.0.0.0, 255.255.255.255]', $string);
147
        }
148
149
        return self::create($match['start'], $match['end'], IntervalType::fromString($string));
150
    }
151
152
    /**
153
     * @param IPv4Interval $interval
154
     *
155
     * @return bool
156
     */
157
    public function equal(IPv4Interval $interval)
158
    {
159
        return $this->comparator->equal($interval);
160
    }
161
162
    /**
163
     * @param string $point
164
     *
165
     * @return bool
166
     */
167
    public function contains($point)
168
    {
169
        return $this->comparator->contains(new IPv4IntervalPoint($point));
170
    }
171
172
    /**
173
     * @param IPv4Interval $interval
174
     * @param bool $check_interval_type
175
     *
176
     * @return bool
177
     */
178
    public function intersects(IPv4Interval $interval, $check_interval_type = true)
179
    {
180
        return $this->comparator->intersects($interval, $check_interval_type);
181
    }
182
183
    /**
184
     * @param IPv4Interval $interval
185
     *
186
     * @return IPv4Interval|null
187
     */
188
    public function intersection(IPv4Interval $interval)
189
    {
190
        return $this->comparator->intersection($interval);
191
    }
192
193
    /**
194
     * The point is before the interval.
195
     *
196
     * @param string $point
197
     *
198
     * @return bool
199
     */
200
    public function before($point)
201
    {
202
        return $this->comparator->before(new IPv4IntervalPoint($point));
203
    }
204
205
    /**
206
     * The point is after the interval.
207
     *
208
     * @param string $point
209
     *
210
     * @return bool
211
     */
212
    public function after($point)
213
    {
214
        return $this->comparator->after(new IPv4IntervalPoint($point));
215
    }
216
217
    /**
218
     * @return IntervalType
219
     */
220
    public function type()
221
    {
222
        return $this->type;
223
    }
224
225
    /**
226
     * @return string
227
     */
228
    public function start()
229
    {
230
        return (string) $this->start;
231
    }
232
233
    /**
234
     * @return string
235
     */
236
    public function end()
237
    {
238
        return (string) $this->end;
239
    }
240
241
    /**
242
     * @return IPv4IntervalPoint
243
     */
244
    public function startPoint()
245
    {
246
        return $this->start;
247
    }
248
249
    /**
250
     * @return IPv4IntervalPoint
251
     */
252
    public function endPoint()
253
    {
254
        return $this->end;
255
    }
256
257
    /**
258
     * Returns a copy of this Interval with the start point altered.
259
     *
260
     * @param IntervalPointInterface|IPv4IntervalPoint $start
261
     *
262
     * @return self
263
     */
264
    public function withStart(IntervalPointInterface $start)
265
    {
266
        return new self($start, $this->end, $this->type);
267
    }
268
269
    /**
270
     * Returns a copy of this Interval with the end point altered.
271
     *
272
     * @param IntervalPointInterface|IPv4IntervalPoint $end
273
     *
274
     * @return self
275
     */
276
    public function withEnd(IntervalPointInterface $end)
277
    {
278
        return new self($this->start, $end, $this->type);
279
    }
280
281
    /**
282
     * Returns a copy of this Interval with the interval type altered.
283
     *
284
     * @param IntervalType $type
285
     *
286
     * @return self
287
     */
288
    public function withType(IntervalType $type)
289
    {
290
        return new self($this->start, $this->end, $type);
291
    }
292
293
    /**
294
     * @return string
295
     */
296
    public function __toString()
297
    {
298
        return $this->type->getReadable($this);
299
    }
300
}
301

src/Number/NumberInterval.php 1 location

@@ 20-300 (lines=281) @@
17
use GpsLab\Component\Interval\IntervalPointInterface;
18
use GpsLab\Component\Interval\IntervalType;
19
20
class NumberInterval implements ComparableIntervalInterface
21
{
22
    /**
23
     * @var string
24
     */
25
    const REGEXP = '/^
26
        (?:\(|\[)        # start type char
27
        \s*
28
        (?<start>\-?\d+) # start point
29
        \s*,\s*          # separator
30
        (?<end>\-?\d+)   # end point
31
        \s*
32
        (?:\)|\])        # end type char
33
    $/x';
34
35
    /**
36
     * @var IntervalType
37
     */
38
    private $type;
39
40
    /**
41
     * @var IntervalComparator
42
     */
43
    private $comparator;
44
45
    /**
46
     * @var NumberIntervalPoint
47
     */
48
    private $start;
49
50
    /**
51
     * @var NumberIntervalPoint
52
     */
53
    private $end;
54
55
    /**
56
     * @param NumberIntervalPoint $start
57
     * @param NumberIntervalPoint $end
58
     * @param IntervalType $type
59
     */
60
    private function __construct(NumberIntervalPoint $start, NumberIntervalPoint $end, IntervalType $type)
61
    {
62
        if ($start->gte($end)) {
63
            throw IncorrectIntervalException::create();
64
        }
65
66
        $this->start = $start;
67
        $this->end = $end;
68
        $this->type = $type;
69
        $this->comparator = new IntervalComparator($this);
70
    }
71
72
    /**
73
     * @param int|float $start
74
     * @param int|float $end
75
     * @param IntervalType $type
76
     *
77
     * @return self
78
     */
79
    public static function create($start, $end, IntervalType $type)
80
    {
81
        return new self(new NumberIntervalPoint($start), new NumberIntervalPoint($end), $type);
82
    }
83
84
    /**
85
     * @param int|float $start
86
     * @param int|float $end
87
     *
88
     * @return self
89
     */
90
    public static function closed($start, $end)
91
    {
92
        return self::create($start, $end, IntervalType::closed());
93
    }
94
95
    /**
96
     * @param int|float $start
97
     * @param int|float $end
98
     *
99
     * @return self
100
     */
101
    public static function halfClosed($start, $end)
102
    {
103
        return self::create($start, $end, IntervalType::halfClosed());
104
    }
105
106
    /**
107
     * @param int|float $start
108
     * @param int|float $end
109
     *
110
     * @return self
111
     */
112
    public static function halfOpen($start, $end)
113
    {
114
        return self::create($start, $end, IntervalType::halfOpen());
115
    }
116
117
    /**
118
     * @param int|float $start
119
     * @param int|float $end
120
     *
121
     * @return self
122
     */
123
    public static function open($start, $end)
124
    {
125
        return self::create($start, $end, IntervalType::open());
126
    }
127
128
    /**
129
     * Create interval from string.
130
     *
131
     * Example formats:
132
     *   [0, 5]
133
     *   (-3, 2]
134
     *   [-3, -1)
135
     *   (3, 9)
136
     *
137
     * Spaces are ignored in format.
138
     *
139
     * @param string $string
140
     *
141
     * @return self
142
     */
143
    public static function fromString($string)
144
    {
145
        if (!preg_match(self::REGEXP, $string, $match)) {
146
            throw InvalidIntervalFormatException::create('[N, N]', $string);
147
        }
148
149
        return self::create($match['start'], $match['end'], IntervalType::fromString($string));
150
    }
151
152
    /**
153
     * @param NumberInterval $interval
154
     *
155
     * @return bool
156
     */
157
    public function equal(NumberInterval $interval)
158
    {
159
        return $this->comparator->equal($interval);
160
    }
161
162
    /**
163
     * @param int|float $point
164
     *
165
     * @return bool
166
     */
167
    public function contains($point)
168
    {
169
        return $this->comparator->contains(new NumberIntervalPoint($point));
170
    }
171
172
    /**
173
     * @param NumberInterval $interval
174
     * @param bool $check_interval_type
175
     *
176
     * @return bool
177
     */
178
    public function intersects(NumberInterval $interval, $check_interval_type = true)
179
    {
180
        return $this->comparator->intersects($interval, $check_interval_type);
181
    }
182
183
    /**
184
     * @param NumberInterval $interval
185
     *
186
     * @return NumberInterval|null
187
     */
188
    public function intersection(NumberInterval $interval)
189
    {
190
        return $this->comparator->intersection($interval);
191
    }
192
193
    /**
194
     * The point is before the interval.
195
     *
196
     * @param int|float $point
197
     *
198
     * @return bool
199
     */
200
    public function before($point)
201
    {
202
        return $this->comparator->before(new NumberIntervalPoint($point));
203
    }
204
205
    /**
206
     * The point is after the interval.
207
     *
208
     * @param int|float $point
209
     *
210
     * @return bool
211
     */
212
    public function after($point)
213
    {
214
        return $this->comparator->after(new NumberIntervalPoint($point));
215
    }
216
217
    /**
218
     * @return IntervalType
219
     */
220
    public function type()
221
    {
222
        return $this->type;
223
    }
224
225
    /**
226
     * @return int|float
227
     */
228
    public function start()
229
    {
230
        return $this->start->value();
231
    }
232
233
    /**
234
     * @return int|float
235
     */
236
    public function end()
237
    {
238
        return $this->end->value();
239
    }
240
241
    /**
242
     * @return NumberIntervalPoint
243
     */
244
    public function startPoint()
245
    {
246
        return $this->start;
247
    }
248
249
    /**
250
     * @return NumberIntervalPoint
251
     */
252
    public function endPoint()
253
    {
254
        return $this->end;
255
    }
256
257
    /**
258
     * Returns a copy of this Interval with the start point altered.
259
     *
260
     * @param IntervalPointInterface|NumberIntervalPoint $start
261
     *
262
     * @return self
263
     */
264
    public function withStart(IntervalPointInterface $start)
265
    {
266
        return new self($start, $this->end, $this->type);
267
    }
268
269
    /**
270
     * Returns a copy of this Interval with the end point altered.
271
     *
272
     * @param IntervalPointInterface|NumberIntervalPoint $end
273
     *
274
     * @return self
275
     */
276
    public function withEnd(IntervalPointInterface $end)
277
    {
278
        return new self($this->start, $end, $this->type);
279
    }
280
281
    /**
282
     * Returns a copy of this Interval with the interval type altered.
283
     *
284
     * @param IntervalType $type
285
     *
286
     * @return self
287
     */
288
    public function withType(IntervalType $type)
289
    {
290
        return new self($this->start, $this->end, $type);
291
    }
292
293
    /**
294
     * @return string
295
     */
296
    public function __toString()
297
    {
298
        return $this->type->getReadable($this);
299
    }
300
}
301