File Coverage

blib/lib/Farly/IPv4/Range.pm
Criterion Covered Total %
statement 58 63 92.0
branch 10 14 71.4
condition n/a
subroutine 15 16 93.7
pod 9 9 100.0
total 92 102 90.2


line stmt bran cond sub pod time code
1             package Farly::IPv4::Range;
2            
3 19     19   22050 use 5.008008;
  19         66  
  19         788  
4 19     19   104 use strict;
  19         39  
  19         627  
5 19     19   107 use warnings;
  19         34  
  19         514  
6 19     19   108 use Carp;
  19         32  
  19         1470  
7 19     19   716 use Farly::IPv4::Address;
  19         37  
  19         568  
8             require Farly::IPv4::Network;
9 19     19   104 use Farly::IPv4::Object;
  19         34  
  19         15611  
10            
11             our @ISA = qw(Farly::IPv4::Object);
12             our $VERSION = '0.26';
13            
14             sub new {
15 13     13 1 54 my ( $class, $first, $last ) = @_;
16            
17 13         42 my $self = {
18             FIRST => undef, #::IPv4::Address
19             LAST => undef, #::IPv4::Address
20             };
21 13         35 bless( $self, $class );
22            
23 13 100       67 if ( defined $last ) {
    50          
24 1         5 $self->_init( $first, $last );
25             }
26             elsif ( defined $first ) {
27 12         93 my ( $f, $l ) = split( /-|\s+/, $first );
28 12         41 $self->_init( $f, $l );
29             }
30             else {
31 0         0 confess "first last address range required";
32             }
33            
34 13         38 return $self;
35             }
36            
37             sub _init {
38 13     13   25 my ( $self, $first, $last ) = @_;
39            
40 13         99 $self->{FIRST} = Farly::IPv4::Address->new($first);
41 13         260 $self->{LAST} = Farly::IPv4::Address->new($last);
42            
43 13 50       39 confess "First must be less than last"
44             if ( $self->first() > $self->last() );
45             }
46            
47             sub first {
48 53     53 1 741 return $_[0]->{FIRST}->address();
49             }
50            
51             sub last {
52 39     39 1 136 return $_[0]->{LAST}->address();
53             }
54            
55             sub as_string {
56 8     8 1 400 my ($self) = @_;
57 8         51 return join( " ", $self->{FIRST}->as_string(), $self->{LAST}->as_string() );
58             }
59            
60             sub adjacent {
61 1     1 1 2 my ( $self, $other ) = @_;
62 1 50       3 if ( ( $self->last() + 1 ) == $other->first() ) {
63 1         6 return 1;
64             }
65 0         0 return 0;
66             }
67            
68             sub start {
69 1     1 1 10 return $_[0]->{FIRST};
70             }
71            
72             sub end {
73 1     1 1 4 return $_[0]->{LAST};
74             }
75            
76             sub as_network {
77 1     1 1 2 my ($self) = @_;
78 1         14 my $first = $self->first();
79 1         3 my $last = $self->last();
80 1         2 my @list;
81             my $mask;
82 1         1 my $host_mask = 4294967295; #0XFFFFFFFF
83            
84             #start from the first address in the range
85 1         4 while ( $first < $last ) {
86            
87             # start from the /32 mask and work downwards
88 4         5 my $current_mask = $host_mask;
89            
90             # check if the current mask results in first being a network number
91 4         7 while ( $first == ( $first & $current_mask ) ) {
92            
93             # if the current mask is still in the range try a bigger mask
94 10         11 my $inverse_mask = ~$current_mask & $host_mask;
95 10 50       27 if ( ( $first + $inverse_mask ) <= $last ) {
96 10         10 $mask = $current_mask;
97 10         17 $current_mask = ( $current_mask << 1 ) & $host_mask;
98             }
99             else {
100 0         0 last;
101             }
102             }
103            
104 4 100       7 if ( $mask == 4294967295 ) {
105 1         4 push @list, Farly::IPv4::Address->new($first);
106             }
107             else {
108 3         18 push @list, Farly::IPv4::Network->new("$first $mask");
109             }
110            
111 4         7 $first = $first + ( ~$mask & $host_mask ) + 1;
112            
113 4 100       17 if ( $first == $last ) {
114 1         5 push @list, Farly::IPv4::Address->new($first);
115             }
116            
117             }
118            
119 1         5 return @list;
120             }
121            
122             sub iter {
123 0     0 1   my @iter = ( Farly::IPv4::Range->new( $_[0]->first(), $_[0]->last() ) );
124 0           return @iter;
125             }
126            
127             1;
128             __END__