Code Duplication    Length = 364-364 lines in 2 locations

src/IPv4/IPv4Interval.php 1 location

@@ 20-383 (lines=364) @@
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
     * Checks if this interval is equal to the specified interval.
154
     *
155
     * @param IPv4Interval $interval
156
     *
157
     * @return bool
158
     */
159
    public function equal(IPv4Interval $interval)
160
    {
161
        return $this->comparator->equal($interval);
162
    }
163
164
    /**
165
     * Does this interval contain the specified point.
166
     *
167
     * @param string $point
168
     *
169
     * @return bool
170
     */
171
    public function contains($point)
172
    {
173
        return $this->comparator->contains(new IPv4IntervalPoint($point));
174
    }
175
176
    /**
177
     * Does this interval intersect the specified interval.
178
     *
179
     * @param IPv4Interval $interval
180
     *
181
     * @return bool
182
     */
183
    public function intersects(IPv4Interval $interval)
184
    {
185
        return $this->comparator->intersects($interval);
186
    }
187
188
    /**
189
     * Gets the intersection between this interval and another interval.
190
     *
191
     * @param IPv4Interval $interval
192
     *
193
     * @return self|null
194
     */
195
    public function intersection(IPv4Interval $interval)
196
    {
197
        return $this->comparator->intersection($interval);
198
    }
199
200
    /**
201
     * Gets the covered interval between this Interval and another interval.
202
     *
203
     * @param IPv4Interval $interval
204
     *
205
     * @return self
206
     */
207
    public function cover(IPv4Interval $interval)
208
    {
209
        return $this->comparator->cover($interval);
210
    }
211
212
    /**
213
     * Gets the gap between this interval and another interval.
214
     *
215
     * @param IPv4Interval $interval
216
     *
217
     * @return self|null
218
     */
219
    public function gap(IPv4Interval $interval)
220
    {
221
        return $this->comparator->gap($interval);
222
    }
223
224
    /**
225
     * Does this interval abut with the interval specified.
226
     *
227
     * @param IPv4Interval $interval
228
     *
229
     * @return bool
230
     */
231
    public function abuts(IPv4Interval $interval)
232
    {
233
        return $this->comparator->abuts($interval);
234
    }
235
236
    /**
237
     * Joins the interval between the adjacent.
238
     *
239
     * @param IPv4Interval $interval
240
     *
241
     * @return self|null
242
     */
243
    public function join(IPv4Interval $interval)
244
    {
245
        return $this->comparator->join($interval);
246
    }
247
248
    /**
249
     * Gets the union between this interval and another interval.
250
     *
251
     * @param IPv4Interval $interval
252
     *
253
     * @return self|null
254
     */
255
    public function union(IPv4Interval $interval)
256
    {
257
        return $this->comparator->union($interval);
258
    }
259
260
    /**
261
     * The point is before the interval.
262
     *
263
     * @param string $point
264
     *
265
     * @return bool
266
     */
267
    public function before($point)
268
    {
269
        return $this->comparator->before(new IPv4IntervalPoint($point));
270
    }
271
272
    /**
273
     * The point is after the interval.
274
     *
275
     * @param string $point
276
     *
277
     * @return bool
278
     */
279
    public function after($point)
280
    {
281
        return $this->comparator->after(new IPv4IntervalPoint($point));
282
    }
283
284
    /**
285
     * @param int $step
286
     *
287
     * @return \Generator
288
     */
289
    public function iterate($step = 1)
290
    {
291
        $end = $this->endPoint()->value();
292
        $ip = $this->startPoint()->value();
293
294
        while ($ip < $end) {
295
            yield long2ip($ip);
296
            $ip += $step;
297
        }
298
    }
299
300
    /**
301
     * @return IntervalType
302
     */
303
    public function type()
304
    {
305
        return $this->type;
306
    }
307
308
    /**
309
     * @return string
310
     */
311
    public function start()
312
    {
313
        return (string) $this->start;
314
    }
315
316
    /**
317
     * @return string
318
     */
319
    public function end()
320
    {
321
        return (string) $this->end;
322
    }
323
324
    /**
325
     * @return IPv4IntervalPoint
326
     */
327
    public function startPoint()
328
    {
329
        return $this->start;
330
    }
331
332
    /**
333
     * @return IPv4IntervalPoint
334
     */
335
    public function endPoint()
336
    {
337
        return $this->end;
338
    }
339
340
    /**
341
     * Returns a copy of this Interval with the start point altered.
342
     *
343
     * @param IntervalPointInterface|IPv4IntervalPoint $start
344
     *
345
     * @return self
346
     */
347
    public function withStart(IntervalPointInterface $start)
348
    {
349
        return new self($start, $this->end, $this->type);
350
    }
351
352
    /**
353
     * Returns a copy of this Interval with the end point altered.
354
     *
355
     * @param IntervalPointInterface|IPv4IntervalPoint $end
356
     *
357
     * @return self
358
     */
359
    public function withEnd(IntervalPointInterface $end)
360
    {
361
        return new self($this->start, $end, $this->type);
362
    }
363
364
    /**
365
     * Returns a copy of this Interval with the interval type altered.
366
     *
367
     * @param IntervalType $type
368
     *
369
     * @return self
370
     */
371
    public function withType(IntervalType $type)
372
    {
373
        return new self($this->start, $this->end, $type);
374
    }
375
376
    /**
377
     * @return string
378
     */
379
    public function __toString()
380
    {
381
        return $this->type->getReadable($this);
382
    }
383
}
384

src/Number/NumberInterval.php 1 location

@@ 20-383 (lines=364) @@
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
     * Checks if this interval is equal to the specified interval.
154
     *
155
     * @param NumberInterval $interval
156
     *
157
     * @return bool
158
     */
159
    public function equal(NumberInterval $interval)
160
    {
161
        return $this->comparator->equal($interval);
162
    }
163
164
    /**
165
     * Does this interval contain the specified point.
166
     *
167
     * @param int|float $point
168
     *
169
     * @return bool
170
     */
171
    public function contains($point)
172
    {
173
        return $this->comparator->contains(new NumberIntervalPoint($point));
174
    }
175
176
    /**
177
     * Does this interval intersect the specified interval.
178
     *
179
     * @param NumberInterval $interval
180
     *
181
     * @return bool
182
     */
183
    public function intersects(NumberInterval $interval)
184
    {
185
        return $this->comparator->intersects($interval);
186
    }
187
188
    /**
189
     * Gets the intersection between this interval and another interval.
190
     *
191
     * @param NumberInterval $interval
192
     *
193
     * @return self|null
194
     */
195
    public function intersection(NumberInterval $interval)
196
    {
197
        return $this->comparator->intersection($interval);
198
    }
199
200
    /**
201
     * Gets the covered interval between this Interval and another interval.
202
     *
203
     * @param NumberInterval $interval
204
     *
205
     * @return self
206
     */
207
    public function cover(NumberInterval $interval)
208
    {
209
        return $this->comparator->cover($interval);
210
    }
211
212
    /**
213
     * Gets the gap between this interval and another interval.
214
     *
215
     * @param NumberInterval $interval
216
     *
217
     * @return self|null
218
     */
219
    public function gap(NumberInterval $interval)
220
    {
221
        return $this->comparator->gap($interval);
222
    }
223
224
    /**
225
     * Does this interval abut with the interval specified.
226
     *
227
     * @param NumberInterval $interval
228
     *
229
     * @return bool
230
     */
231
    public function abuts(NumberInterval $interval)
232
    {
233
        return $this->comparator->abuts($interval);
234
    }
235
236
    /**
237
     * Joins the interval between the adjacent.
238
     *
239
     * @param NumberInterval $interval
240
     *
241
     * @return self|null
242
     */
243
    public function join(NumberInterval $interval)
244
    {
245
        return $this->comparator->join($interval);
246
    }
247
248
    /**
249
     * Gets the union between this interval and another interval.
250
     *
251
     * @param NumberInterval $interval
252
     *
253
     * @return self|null
254
     */
255
    public function union(NumberInterval $interval)
256
    {
257
        return $this->comparator->union($interval);
258
    }
259
260
    /**
261
     * The point is before the interval.
262
     *
263
     * @param int|float $point
264
     *
265
     * @return bool
266
     */
267
    public function before($point)
268
    {
269
        return $this->comparator->before(new NumberIntervalPoint($point));
270
    }
271
272
    /**
273
     * The point is after the interval.
274
     *
275
     * @param int|float $point
276
     *
277
     * @return bool
278
     */
279
    public function after($point)
280
    {
281
        return $this->comparator->after(new NumberIntervalPoint($point));
282
    }
283
284
    /**
285
     * @param int $step
286
     *
287
     * @return \Generator
288
     */
289
    public function iterate($step = 1)
290
    {
291
        $end = $this->end();
292
        $number = $this->start();
293
294
        while ($number < $end) {
295
            yield $number;
296
            $number += $step;
297
        }
298
    }
299
300
    /**
301
     * @return IntervalType
302
     */
303
    public function type()
304
    {
305
        return $this->type;
306
    }
307
308
    /**
309
     * @return int|float
310
     */
311
    public function start()
312
    {
313
        return $this->start->value();
314
    }
315
316
    /**
317
     * @return int|float
318
     */
319
    public function end()
320
    {
321
        return $this->end->value();
322
    }
323
324
    /**
325
     * @return NumberIntervalPoint
326
     */
327
    public function startPoint()
328
    {
329
        return $this->start;
330
    }
331
332
    /**
333
     * @return NumberIntervalPoint
334
     */
335
    public function endPoint()
336
    {
337
        return $this->end;
338
    }
339
340
    /**
341
     * Returns a copy of this Interval with the start point altered.
342
     *
343
     * @param IntervalPointInterface|NumberIntervalPoint $start
344
     *
345
     * @return self
346
     */
347
    public function withStart(IntervalPointInterface $start)
348
    {
349
        return new self($start, $this->end, $this->type);
350
    }
351
352
    /**
353
     * Returns a copy of this Interval with the end point altered.
354
     *
355
     * @param IntervalPointInterface|NumberIntervalPoint $end
356
     *
357
     * @return self
358
     */
359
    public function withEnd(IntervalPointInterface $end)
360
    {
361
        return new self($this->start, $end, $this->type);
362
    }
363
364
    /**
365
     * Returns a copy of this Interval with the interval type altered.
366
     *
367
     * @param IntervalType $type
368
     *
369
     * @return self
370
     */
371
    public function withType(IntervalType $type)
372
    {
373
        return new self($this->start, $this->end, $type);
374
    }
375
376
    /**
377
     * @return string
378
     */
379
    public function __toString()
380
    {
381
        return $this->type->getReadable($this);
382
    }
383
}
384