File Coverage

lib/NetObj/IPv4Address.pm
Criterion Covered Total %
statement 47 47 100.0
branch 12 12 100.0
condition n/a
subroutine 16 16 100.0
pod 2 3 66.6
total 77 78 98.7


line stmt bran cond sub pod time code
1 5     5   66602 use strict;
  5         10  
  5         135  
2 5     5   14 use warnings FATAL => 'all';
  5         5  
  5         148  
3 5     5   66 use 5.014;
  5         15  
  5         179  
4             package NetObj::IPv4Address;
5             $NetObj::IPv4Address::VERSION = '1.0';
6             # ABSTRACT: represent a IPv4 address
7              
8 5     5   12631 use Moo;
  5         59130  
  5         19  
9 5     5   4687 use Carp;
  5         7  
  5         255  
10 5     5   1908 use List::MoreUtils qw( all );
  5         33369  
  5         28  
11              
12             sub _to_binary {
13             my ($ipaddr) = @_;
14              
15             my @octets = split(qr{\.}, $ipaddr);
16             return unless @octets == 4;
17             return unless all {
18             ($_ =~ m{\A \d+ \Z}xms) and ($_ >=0) and ($_ <= 255);
19             } @octets;
20              
21             return pack('CCCC', @octets);
22             }
23              
24 5     5   4041 use namespace::clean;
  5         35188  
  5         27  
25              
26             sub is_valid {
27 13     13 1 2108 my ($ipaddr) = @_;
28 13 100       43 croak 'NetObj::IPv4Adress::is_valid is a class method only'
29             if ref($ipaddr) eq __PACKAGE__;
30              
31 12         18 return !! _to_binary($ipaddr);
32             }
33              
34             has binary => (
35             is => 'ro',
36             );
37              
38             sub BUILDARGS {
39 36     36 0 9454 my ($class, $ip, @args) = @_;
40 36 100       76 croak 'no IPv4 address given' unless defined($ip);
41 35 100       81 croak 'too many arguments in constructor for ' . __PACKAGE__ if @args;
42              
43 34 100       198 return { binary => $ip->binary() } if ref($ip) eq __PACKAGE__;
44              
45 27 100       64 $ip = _to_binary($ip) unless length($ip) == 4;
46 27 100       96 croak 'invalid IPv4 address' unless $ip;
47              
48 19         285 return { binary => $ip };
49             }
50              
51             sub to_string {
52 26     26 1 83 my ($self) = @_;
53              
54 26         136 return join('.', unpack('CCCC', $self->binary()));
55             }
56              
57 5     5   5643 use overload q("") => sub {shift->to_string};
  5     22   3280  
  5         32  
  22         100  
58              
59             use overload q(<=>) => sub {
60 10     10   1330 my ($a, $b) = @_;
61 10         208 return ($a->binary() cmp NetObj::IPv4Address->new($b)->binary());
62 5     5   360 };
  5         38  
  5         20  
63              
64 5     5   277 use overload q(cmp) => sub { my ($a, $b) = @_; return $a <=> $b; };
  5     5   6  
  5         30  
  5         1466  
  5         10  
65              
66             1;
67              
68             __END__
69              
70             =pod
71              
72             =encoding UTF-8
73              
74             =head1 NAME
75              
76             NetObj::IPv4Address - represent a IPv4 address
77              
78             =head1 VERSION
79              
80             version 1.0
81              
82             =head1 SYNOPSIS
83              
84             use NetObj::IPv4Address;
85              
86             # constructor
87             my $ip1 = NetObj::IPv4Address->new('127.0.0.1');
88              
89             # convert to string
90             $ip1->to_string(); # "127.0.0.1"
91             "$ip1" ; # "127.0.0.1" by implicit stringification
92              
93             # comparison, numerically and stringwise
94             my $ip2 = NetObj::IPv4Address->new('192.168.0.1');
95             $ip1 == $ip1; # true
96             $ip1 == $ip2; # false
97             $ip1 != $ip2; # true
98             $ip1 eq $ip1; # true
99             $ip1 eq $ip2; # false
100             $ip1 ne $ip2; # true
101              
102             # test for validity
103             NetObj::IPv4Address::is_valid('127.0.0.1'); # true
104             NetObj::IPv4Address::is_valid('1.2.3.4.5'); # false
105              
106             # construct from raw binary IPv4 address (4 bytes)
107             my $ip2 = NetObj::IPv4Address->new("\x7f\x00\x00\x01"); # 127.0.0.1
108              
109             =head1 DESCRIPTION
110              
111             NetObj::IPv4Address represents IPv4 addresses.
112              
113             NetObj::IPv4Address is implemented as a Moose style object class (using Moo).
114              
115             =head1 METHODS
116              
117             =head2 is_valid
118              
119             The class method C<NetObj::IPv4Address::is_valid> tests for the validity of a
120             IPv4 address represented by a string. It does not throw an exception but
121             returns false for an invalid and true for a valid IPv4 address.
122              
123             If called on an object it does throw an exception.
124              
125             =head2 new
126              
127             The constructor expects exactly one argument representing an IPv4 address as a
128             string in the usual form of 4 decimal numbers between 0 and 255 separated by
129             dots.
130              
131             Raw 4 byte IPv4 addresses are supported.
132              
133             It throws an exception for invalid IPv4 addresses.
134              
135             =head2 to_string
136              
137             The method C<to_string> returns the canonical string representation of the IPv4
138             address as dotted decimal octets.
139              
140             Implicit stringification in string context is supported.
141              
142             =head2 binary
143              
144             The C<binary> method returns the raw 4 bytes of the IPv4 address.
145              
146             =for Pod::Coverage BUILDARGS
147              
148             =head1 AUTHOR
149              
150             Elmar S. Heeb <elmar@heebs.ch>
151              
152             =head1 COPYRIGHT AND LICENSE
153              
154             This software is Copyright (c) 2015 by Elmar S. Heeb.
155              
156             This is free software, licensed under:
157              
158             The GNU General Public License, Version 3, June 2007
159              
160             =cut