File Coverage

blib/lib/Net/DNS/Match.pm
Criterion Covered Total %
statement 68 69 98.5
branch 22 24 91.6
condition n/a
subroutine 8 8 100.0
pod 0 3 0.0
total 98 104 94.2


line stmt bran cond sub pod time code
1             package Net::DNS::Match;
2              
3 1     1   24098 use 5.008008;
  1         4  
  1         43  
4 1     1   6 use strict;
  1         2  
  1         37  
5 1     1   13 use warnings;
  1         7  
  1         1000  
6              
7             require Exporter;
8              
9             our @ISA = qw(Exporter);
10              
11             # Items to export into callers namespace by default. Note: do not export
12             # names by default without a very good reason. Use EXPORT_OK instead.
13             # Do not simply export all your public functions/methods/constants.
14              
15             # This allows declaration use Net::DNS::Match ':all';
16             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
17             # will save memory.
18             our %EXPORT_TAGS = ( 'all' => [ qw(
19            
20             ) ] );
21              
22             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
23              
24             our @EXPORT = qw(
25            
26             );
27              
28             our $VERSION = '0.05';
29             $VERSION = eval $VERSION;
30              
31             # Preloaded methods go here.
32              
33             sub new {
34 9     9 0 20 my $class = shift;
35 9         10 my $args = shift;
36            
37 9         13 my $self = {};
38 9         13 bless($self,$class);
39            
40 9         34 return $self;
41             }
42              
43             sub add {
44 1     1 0 649 my $self = shift;
45 1         2 my $array = shift;
46            
47 1 50       6 $array = [ $array ] unless(ref($array) eq 'ARRAY');
48            
49             # sort this first, make sure the top level fqdn's come first.
50             # in the event anyone puts in both test.example.com, test2.example.com AND example.com
51             # this should make sure the top-level 'example.com' makes it in first, and the rest are
52             # rejected
53 1         6 @{$array} = sort { length $a <=> length $b } @$array;
  1         4  
  9         13  
54            
55 1         4 foreach (@$array){
56 5         12 $self->_add($_,$_);
57             }
58             }
59              
60             sub _add {
61 11     11   12 my $self = shift;
62 11         14 my $string = shift;
63 11         8 my $data = shift;
64            
65 11         30 my @bits = split('\.',$string);
66 11         13 my $tld = $bits[$#bits];
67 11         13 pop(@bits);
68              
69 11         18 my $rest = join('.',@bits);
70            
71 11 100       32 $self->{'children'} = {} unless(defined($self->{'children'}));
72 11         14 my $children = $self->{'children'};
73            
74 11 100       21 unless(exists($children->{$tld})){
75 8         12 $children->{$tld} = Net::DNS::Match->new();
76             }
77            
78 11         14 my $child = $children->{$tld};
79 11 100       21 if($#bits > -1){
80             # recursive, unless we've already got a leaf that accounts for this
81             # node, then bypass it
82 7 100       32 $child->_add($rest,$data) unless($child->{'value'});
83             } else {
84 4         7 $child->{'data'} = $data;
85 4         6 $child->{'value'} = 1;
86             }
87              
88 11         25 return 1;
89             }
90              
91             sub match {
92 7     7 0 14 my $self = shift;
93 7         7 my $string = shift;
94            
95 7         14 my ($res,$data) = $self->_match($string);
96 7 100       17 return $string if($res);
97            
98 6         14 my @bits = split('\.',$string);
99 6 100       35 return 0 if($#bits < 2); # we're tld, no match, move on...
100            
101             # work our way back through the address
102 4         10 my $t = $bits[$#bits-1].'.'.$bits[$#bits];
103              
104 4         26 ($res,$data) = $self->_match($t);
105 4 100       22 return $data if($res);
106            
107             # pop the top-level
108 1         2 pop(@bits); pop(@bits);
  1         1  
109 1         3 @bits = reverse(@bits);
110 1         2 foreach my $b (@bits){
111 1         2 $t = $b.'.'.$t;
112 1         3 ($res,$data) = $self->_match($t);
113 1 50       6 return $data if($res);
114             }
115 0         0 return 0;
116             }
117              
118             sub _match {
119 30     30   33 my $self = shift;
120 30         29 my $string = shift;
121            
122 30         68 my @bits = split('\.',$string);
123 30         37 my $tld = $bits[$#bits];
124 30         30 my $size = $#bits;
125 30         31 pop(@bits);
126              
127 30         46 my $rest = join('.',@bits);
128            
129 30 100       60 $self->{'children'} = {} unless(defined($self->{'children'}));
130 30         33 my $children = $self->{'children'};
131            
132 30 100       64 return 0 unless(exists($children->{$tld}));
133 25 100       35 if($size == 0){
134 7         28 return ($children->{$tld}->{'value'},$children->{$tld}->{'data'});
135             } else {
136 18         40 return $children->{$tld}->_match($rest);
137             }
138             }
139              
140             1;
141             __END__