| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package NetAddr::IP::LazyInit; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 33 |  |  | 33 |  | 154718 | use strict; | 
|  | 33 |  |  |  |  | 59 |  | 
|  | 33 |  |  |  |  | 1332 |  | 
| 4 | 33 |  |  | 33 |  | 157 | use warnings; | 
|  | 33 |  |  |  |  | 47 |  | 
|  | 33 |  |  |  |  | 1144 |  | 
| 5 | 33 |  |  | 33 |  | 20984 | use NetAddr::IP qw(Zero Zeros Ones V4mask V4net netlimit); | 
|  | 33 |  |  |  |  | 931749 |  | 
|  | 33 |  |  |  |  | 215 |  | 
| 6 | 33 |  |  | 33 |  | 5994 | use NetAddr::IP::Util; | 
|  | 33 |  |  |  |  | 57 |  | 
|  | 33 |  |  |  |  | 190 |  | 
| 7 | 33 |  |  | 33 |  | 2355 | use v5.10.1; | 
|  | 33 |  |  |  |  | 112 |  | 
|  | 33 |  |  |  |  | 36017 |  | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | our $VERSION = eval '0.7'; | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | =head1 NAME | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | NetAddr::IP::LazyInit - NetAddr::IP objects with deferred validation B | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | =head1 VERSION | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | 0.6 | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | use NetAddr::IP::LazyInit; | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | my $ip = new NetAddr::IP::LazyInit( '10.10.10.5' ); | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | This module is designed to quickly create objects that may become NetAddr::IP | 
| 28 |  |  |  |  |  |  | objects.  It accepts anything you pass to it without validation.  Once a | 
| 29 |  |  |  |  |  |  | method is called that requires operating on the value, the full NetAddr::IP | 
| 30 |  |  |  |  |  |  | object is constructed. | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | You can see from the benchmarks that once you need to instantiate NetAddr::IP | 
| 33 |  |  |  |  |  |  | the speed becomes worse than if you had not used this module.  What I mean is | 
| 34 |  |  |  |  |  |  | that this adds unneeded overhead if you intend to do IP operations on every | 
| 35 |  |  |  |  |  |  | object you create. | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | =head1 WARNING | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | Because validation is deferred, this module assumes you will B | 
| 41 |  |  |  |  |  |  | it valid data>. If you try to give it anything else, it will happily accept it | 
| 42 |  |  |  |  |  |  | and then die once it needs to inflate into a NetAddr::IP object. | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | =head1 CREDITS | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  | This module was inspired by discussion with  Jan Henning Thorsen, Ejhthorsen | 
| 48 |  |  |  |  |  |  | at cpan.orgE, and example code he provided.  The namespace and part of the | 
| 49 |  |  |  |  |  |  | documentation/source is inspired by DateTime::LazyInit by | 
| 50 |  |  |  |  |  |  | Rick Measham, Erickm@cpan.orgE | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | I didn't have to do much so I hate to take author credit, but I am providing | 
| 53 |  |  |  |  |  |  | the module, so complaints can go to me. | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | Robert Drake, Erdrake@cpan.orgE | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | =head1 TODO | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | If we could actually load NetAddr::IP objects in the background while nothing | 
| 60 |  |  |  |  |  |  | is going on that would be neat.  Or we could create shortcut methods when the | 
| 61 |  |  |  |  |  |  | user knows what type of input he has.  new_from_ipv4('ip','mask').  We might | 
| 62 |  |  |  |  |  |  | be able to use Socket to build the raw materials and bless a new NetAddr::IP | 
| 63 |  |  |  |  |  |  | object without going through it's validation. | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENSE | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | Copyright (C) 2014 by Robert Drake | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | This library is free software; you can redistribute it and/or modify | 
| 70 |  |  |  |  |  |  | it under the same terms as Perl itself, either Perl version 5.8.7 or, | 
| 71 |  |  |  |  |  |  | at your option, any later version of Perl 5 you may have available. | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | =cut | 
| 74 |  |  |  |  |  |  |  | 
| 75 |  |  |  |  |  |  | require Exporter; | 
| 76 |  |  |  |  |  |  | our @ISA = qw(Exporter); | 
| 77 |  |  |  |  |  |  | our @EXPORT_OK = qw(Compact Coalesce Zero Zeros Ones V4mask V4net netlimit); | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | =head1 METHODS | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | =head2 new | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | This replaces the NetAddr::IP->new method with a stub that stores the | 
| 84 |  |  |  |  |  |  | arguments supplied in a temporary variable and returns immediately.  No | 
| 85 |  |  |  |  |  |  | validation is performed. | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | Once you call a method that can't be handled by LazyInit, a full NetAddr::IP | 
| 88 |  |  |  |  |  |  | object is built and the request passed into that object. | 
| 89 |  |  |  |  |  |  |  | 
| 90 |  |  |  |  |  |  | my $ip = NetAddr::IP::LazyInit->new("127.0.0.1"); | 
| 91 |  |  |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | =cut | 
| 93 |  |  |  |  |  |  |  | 
| 94 | 1576 |  |  | 1576 | 1 | 6865163 | sub new { my $class = shift; bless {x=>[@_]}, $class } | 
|  | 1576 |  |  |  |  | 7653 |  | 
| 95 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | =head2 addr | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | Returns the IP address of the object.  If we can extract the IP as a string | 
| 99 |  |  |  |  |  |  | without converting to a real NetAddr::IP object, then we return that. | 
| 100 |  |  |  |  |  |  | Currently it only returns IPv6 strings in lower case, which may break your | 
| 101 |  |  |  |  |  |  | application if you aren't using the new standard. | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | my $ip = NetAddr::IP::LazyInit->new("127.0.0.1"); | 
| 104 |  |  |  |  |  |  | print $ip->addr; | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | =cut | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | sub addr { | 
| 109 | 4 |  |  | 4 | 1 | 8 | my $self = shift; | 
| 110 | 4 | 50 |  |  |  | 77 | if ($self->{x}->[0] =~ /^(.*?)(?:\/|$)/) { | 
| 111 | 4 |  |  |  |  | 22 | return lc($1); | 
| 112 |  |  |  |  |  |  | } else { | 
| 113 | 0 |  |  |  |  | 0 | return $self->inflate->addr; | 
| 114 |  |  |  |  |  |  | } | 
| 115 |  |  |  |  |  |  | } | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | =head2 mask | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | Returns the subnet mask of the object.  If the user used the two argument | 
| 120 |  |  |  |  |  |  | option then it returns the string they provided for the second argument. | 
| 121 |  |  |  |  |  |  | Otherwise this will inflate to build a real NetAddr::IP object and return the | 
| 122 |  |  |  |  |  |  | mask. | 
| 123 |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  | my $ip = NetAddr::IP::LazyInit->new("127.0.0.1", "255.255.255.0"); | 
| 125 |  |  |  |  |  |  | print $ip->mask; | 
| 126 |  |  |  |  |  |  |  | 
| 127 |  |  |  |  |  |  | =cut | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  | sub mask { | 
| 130 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 131 | 0 | 0 | 0 |  |  | 0 | if ($self->{x}->[1] && $self->{x}->[1] =~ /\D/) { | 
| 132 | 0 |  |  |  |  | 0 | return $self->{x}->[1]; | 
| 133 |  |  |  |  |  |  | } else { | 
| 134 | 0 |  |  |  |  | 0 | return $self->inflate->mask; | 
| 135 |  |  |  |  |  |  | } | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | # everything below here aren't ment for speed or for users to reference. | 
| 139 |  |  |  |  |  |  | # They're purely for compatibility with NetAddr::IP so that users can use this | 
| 140 |  |  |  |  |  |  | # module like the real one. | 
| 141 |  |  |  |  |  |  |  | 
| 142 | 0 |  |  | 0 | 0 | 0 | sub can { NetAddr::IP->can($_[1]); } | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | sub Compact { | 
| 145 | 11 |  |  | 11 | 0 | 10807654 | for (@_) { | 
| 146 | 14363 | 100 |  |  |  | 19360 | $_->inflate if (ref($_) eq 'NetAddr::IP::LazyInit'); | 
| 147 |  |  |  |  |  |  | } | 
| 148 | 11 |  |  |  |  | 409 | return NetAddr::IP::Compact(@_); | 
| 149 |  |  |  |  |  |  | } | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | sub Coalesce { | 
| 154 | 6 |  |  | 6 | 0 | 586343 | for (@_) { | 
| 155 | 4622 | 100 |  |  |  | 7470 | $_->inflate if (ref($_) eq 'NetAddr::IP::LazyInit'); | 
| 156 |  |  |  |  |  |  | } | 
| 157 | 6 |  |  |  |  | 93 | return NetAddr::IP::Coalesce(@_); | 
| 158 |  |  |  |  |  |  | } | 
| 159 |  |  |  |  |  |  |  | 
| 160 |  |  |  |  |  |  | sub import { | 
| 161 | 35 | 100 |  | 35 |  | 56501 | if (grep { $_ eq ':rfc3021' } @_) | 
|  | 46 |  |  |  |  | 224 |  | 
| 162 |  |  |  |  |  |  | { | 
| 163 | 1 |  |  |  |  | 2 | $NetAddr::IP::rfc3021 = 1; | 
| 164 | 1 |  |  |  |  | 3 | @_ = grep { $_ ne ':rfc3021' } @_; | 
|  | 1 |  |  |  |  | 5 |  | 
| 165 |  |  |  |  |  |  | } | 
| 166 | 35 | 100 |  |  |  | 64 | if (grep { $_ eq ':old_storable' } @_) { | 
|  | 45 |  |  |  |  | 302 |  | 
| 167 | 1 |  |  |  |  | 1 | @_ = grep { $_ ne ':old_storable' } @_; | 
|  | 2 |  |  |  |  | 4 |  | 
| 168 |  |  |  |  |  |  | } | 
| 169 | 35 | 100 |  |  |  | 64 | if (grep { $_ eq ':old_nth' } @_) | 
|  | 44 |  |  |  |  | 172 |  | 
| 170 |  |  |  |  |  |  | { | 
| 171 | 1 |  |  |  |  | 2 | $NetAddr::IP::Lite::Old_nth = 1; | 
| 172 | 1 |  |  |  |  | 3 | @_ = grep { $_ ne ':old_nth' } @_; | 
|  | 2 |  |  |  |  | 9 |  | 
| 173 |  |  |  |  |  |  | } | 
| 174 | 35 | 100 |  |  |  | 52 | if (grep { $_ eq ':lower' } @_) | 
|  | 43 |  |  |  |  | 120 |  | 
| 175 |  |  |  |  |  |  | { | 
| 176 | 1 |  |  |  |  | 5 | NetAddr::IP::Util::lower(); | 
| 177 | 1 |  |  |  |  | 9 | @_ = grep { $_ ne ':lower' } @_; | 
|  | 2 |  |  |  |  | 5 |  | 
| 178 |  |  |  |  |  |  | } | 
| 179 | 35 | 50 |  |  |  | 52 | if (grep { $_ eq ':upper' } @_) | 
|  | 42 |  |  |  |  | 115 |  | 
| 180 |  |  |  |  |  |  | { | 
| 181 | 0 |  |  |  |  | 0 | NetAddr::IP::Util::upper(); | 
| 182 | 0 |  |  |  |  | 0 | @_ = grep { $_ ne ':upper' } @_; | 
|  | 0 |  |  |  |  | 0 |  | 
| 183 |  |  |  |  |  |  | } | 
| 184 |  |  |  |  |  |  |  | 
| 185 | 35 |  |  |  |  | 29110 | NetAddr::IP::LazyInit->export_to_level(1, @_); | 
| 186 |  |  |  |  |  |  | } | 
| 187 |  |  |  |  |  |  |  | 
| 188 |  |  |  |  |  |  | # need to support everything that NetAddr::IP does | 
| 189 |  |  |  |  |  |  | use overload ( | 
| 190 | 3 |  |  | 3 |  | 101 | '@{}'   => sub { return [ $_[0]->inflate->hostenum ]; }, | 
| 191 | 151 |  |  | 151 |  | 5796 | '""'    => sub { return $_[0]->inflate->cidr() }, | 
| 192 | 12 |  |  | 12 |  | 60 | '<=>'   => sub { inflate_args_and_run(\&NetAddr::IP::Lite::comp_addr_mask, @_); }, | 
| 193 | 0 |  |  | 0 |  | 0 | 'cmp'   => sub { inflate_args_and_run(\&NetAddr::IP::Lite::comp_addr_mask, @_); }, | 
| 194 | 1 |  |  | 1 |  | 8 | '++'    => sub { inflate_args_and_run(\&NetAddr::IP::Lite::plusplus, @_); }, | 
| 195 | 1 |  |  | 1 |  | 12 | '+'     => sub { inflate_args_and_run(\&NetAddr::IP::Lite::plus, @_); }, | 
| 196 | 0 |  |  | 0 |  | 0 | '--'    => sub { inflate_args_and_run(\&NetAddr::IP::Lite::minusminus, @_); }, | 
| 197 | 0 |  |  | 0 |  | 0 | '-'     => sub { inflate_args_and_run(\&NetAddr::IP::Lite::minus, @_); }, | 
| 198 | 0 |  |  | 0 |  | 0 | '='     => sub { inflate_args_and_run(\&NetAddr::IP::Lite::copy, @_); }, | 
| 199 |  |  |  |  |  |  | '=='    => sub { | 
| 200 | 0 |  |  | 0 |  | 0 | my $a = $_[0]; | 
| 201 | 0 | 0 |  |  |  | 0 | $a->inflate if ref($_[0]) =~ /NetAddr::IP::LazyInit/; | 
| 202 | 0 |  |  |  |  | 0 | my $b = $_[1]; | 
| 203 | 0 | 0 |  |  |  | 0 | $b->inflate if ref($_[1]) =~ /NetAddr::IP::LazyInit/; | 
| 204 | 0 |  |  |  |  | 0 | return ($a eq $b); | 
| 205 |  |  |  |  |  |  | }, | 
| 206 |  |  |  |  |  |  | '!='    => sub { | 
| 207 | 0 |  |  | 0 |  | 0 | my $a = $_[0]; | 
| 208 | 0 | 0 |  |  |  | 0 | $a->inflate if ref($_[0]) eq 'NetAddr::IP::LazyInit'; | 
| 209 | 0 |  |  |  |  | 0 | my $b = $_[1]; | 
| 210 | 0 | 0 |  |  |  | 0 | $b->inflate if ref($_[1]) eq 'NetAddr::IP::LazyInit'; | 
| 211 | 0 |  |  |  |  | 0 | return ($a ne $b); | 
| 212 |  |  |  |  |  |  | }, | 
| 213 |  |  |  |  |  |  | 'ne'    => sub { | 
| 214 | 0 |  |  | 0 |  | 0 | my $a = $_[0]; | 
| 215 | 0 | 0 |  |  |  | 0 | $a->inflate if ref($_[0]) eq 'NetAddr::IP::LazyInit'; | 
| 216 | 0 |  |  |  |  | 0 | my $b = $_[1]; | 
| 217 | 0 | 0 |  |  |  | 0 | $b->inflate if ref($_[1]) eq 'NetAddr::IP::LazyInit'; | 
| 218 | 0 |  |  |  |  | 0 | return ($a ne $b); | 
| 219 |  |  |  |  |  |  | }, | 
| 220 |  |  |  |  |  |  | 'eq'    => sub { | 
| 221 | 2 |  |  | 2 |  | 1019 | my $a = $_[0]; | 
| 222 | 2 | 50 |  |  |  | 10 | $a->inflate if ref($_[0]) eq 'NetAddr::IP::LazyInit'; | 
| 223 | 2 |  |  |  |  | 3 | my $b = $_[1]; | 
| 224 | 2 | 50 |  |  |  | 6 | $b->inflate if ref($_[1]) eq 'NetAddr::IP::LazyInit'; | 
| 225 | 2 |  |  |  |  | 8 | return ($a eq $b); | 
| 226 |  |  |  |  |  |  | }, | 
| 227 | 9 | 100 |  | 9 |  | 82 | '>'     => sub { return &comp_addr_mask > 0 ? 1 : 0; }, | 
| 228 | 0 | 0 |  | 0 |  | 0 | '<'     => sub { return &comp_addr_mask < 0 ? 1 : 0; }, | 
| 229 | 0 | 0 |  | 0 |  | 0 | '>='    => sub { return &comp_addr_mask < 0 ? 0 : 1; }, | 
| 230 | 0 | 0 |  | 0 |  | 0 | '<='    => sub { return &comp_addr_mask > 0 ? 0 : 1; }, | 
| 231 |  |  |  |  |  |  |  | 
| 232 | 33 |  |  | 33 |  | 219 | ); | 
|  | 33 |  |  |  |  | 58 |  | 
|  | 33 |  |  |  |  | 990 |  | 
| 233 |  |  |  |  |  |  |  | 
| 234 |  |  |  |  |  |  | sub comp_addr_mask { | 
| 235 | 9 |  |  | 9 | 0 | 18 | return inflate_args_and_run(\&NetAddr::IP::Lite::comp_addr_mask, @_); | 
| 236 |  |  |  |  |  |  | } | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | sub inflate_args_and_run { | 
| 239 | 23 |  |  | 23 | 0 | 24 | my $func = shift; | 
| 240 | 23 | 50 |  |  |  | 84 | $_[0]->inflate if ref($_[0]) eq 'NetAddr::IP::LazyInit'; | 
| 241 | 23 | 100 |  |  |  | 74 | $_[1]->inflate if ref($_[1]) eq 'NetAddr::IP::LazyInit'; | 
| 242 | 23 |  |  |  |  | 28 | return &{$func}(@_); | 
|  | 23 |  |  |  |  | 63 |  | 
| 243 |  |  |  |  |  |  | } | 
| 244 |  |  |  |  |  |  |  | 
| 245 |  |  |  |  |  |  | sub AUTOLOAD { | 
| 246 | 321 |  |  | 321 |  | 120995 | my $self = shift; | 
| 247 | 321 |  |  |  |  | 566 | my $obj = NetAddr::IP->new(@{ $self->{x} }); | 
|  | 321 |  |  |  |  | 2484 |  | 
| 248 | 321 |  |  |  |  | 45873 | %$self = %$obj; | 
| 249 | 321 |  |  |  |  | 864 | bless $self, 'NetAddr::IP'; | 
| 250 | 321 |  |  |  |  | 1666 | our $AUTOLOAD =~ /::(\w+)$/; | 
| 251 | 321 |  |  |  |  | 5463 | return $self->$1(@_); | 
| 252 |  |  |  |  |  |  | } | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | sub inflate { | 
| 255 | 1253 |  |  | 1253 | 0 | 1353 | my $self = shift; | 
| 256 | 1253 |  |  |  |  | 1053 | my $method = shift; | 
| 257 | 1253 |  |  |  |  | 1100 | my $obj = NetAddr::IP->new(@{ $self->{x} }); | 
|  | 1253 |  |  |  |  | 4221 |  | 
| 258 | 1253 |  |  |  |  | 117639 | %$self = %$obj; | 
| 259 | 1253 |  |  |  |  | 2216 | bless $self, 'NetAddr::IP'; | 
| 260 | 1253 | 50 |  |  |  | 4222 | return $method ? $self->method( @_ ) : $self; | 
| 261 |  |  |  |  |  |  | } | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | 1; |