File Coverage

blib/lib/Net/CIDR/Lookup/Tie.pm
Criterion Covered Total %
statement 23 45 51.1
branch 1 4 25.0
condition n/a
subroutine 8 15 53.3
pod n/a
total 32 64 50.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Net::CIDR::Lookup::Tie
4              
5             =head1 DESCRIPTION
6              
7             This is a L interface to L, see there for
8             details.
9              
10             The tied hash accepts net blocks as keys in the same syntax as
11             C's C or C and stores arbitrary (with the
12             exception of C) scalar values under these. The same coalescing as in
13             C takes place, so if you add any number of different keys
14             you may end up with a hash containing I keys if any mergers took place.
15              
16             Of course you can retrieve the corresponding net block's value for any key that
17             is I within that block, so the number of possible lookup keys is
18             usually far greater than that of explicitly stored key/value pairs.
19              
20             =head1 SYNOPSIS
21              
22             use Net::CIDR::Lookup::Tie;
23              
24             tie my %t, 'Net::CIDR::Lookup::Tie';
25             $t{'192.168.42.0/24'} = 1; # Add first network
26             $t{'192.168.43.0/24'} = 1; # Automatic coalescing to a /23
27             $t{'192.168.41.0/24'} = 2; # Stays separate due to different value
28              
29             print $t{'192.168.42.100'}; # prints "1"
30              
31             foreach(keys %h) { ... } # Do anything you'd do with a regular hash
32              
33             =head1 METHODS
34              
35             =cut
36              
37             package Net::CIDR::Lookup::Tie;
38              
39 2     2   88068 use strict;
  2         4  
  2         89  
40 2     2   7 use warnings;
  2         3  
  2         49  
41 2     2   6 use Carp;
  2         3  
  2         231  
42 2     2   773 use Net::CIDR::Lookup;
  2         4  
  2         74  
43              
44 2     2   49 use version 0.77; our $VERSION = version->declare('v1.0.0');
  2         82  
  2         15  
45              
46             sub TIEHASH { ## no critic (Subroutines::RequireArgUnpacking)
47 3     3   4311 my $class = shift;
48 3         13 bless { tree => Net::CIDR::Lookup->new(@_) }, $class;
49             }
50              
51             =head2 STORE
52              
53             Stores a value under a given key
54              
55             =cut
56              
57             sub STORE { ## no critic (Subroutines::RequireArgUnpacking)
58 4     4   286 my $self = shift;
59 4         6 undef $self->{keys};
60 4 50       50 if($_[0] =~ /-/) {
61 0         0 $self->{tree}->add_range(@_);
62             } else {
63 4         14 $self->{tree}->add(@_);
64             }
65             }
66              
67             =head2 FETCH
68              
69             Fetches the value stored under a given key
70              
71             =cut
72              
73             sub FETCH {
74 3     3   444 my ($self, $key) = @_;
75 3         9 $self->{tree}->lookup($key);
76             }
77            
78             =head2 FIRSTKEY
79              
80             Gets the first key in the hash. Used for iteration with each()
81              
82             =cut
83              
84             sub FIRSTKEY {
85 0     0     my $self = shift;
86 0           $self->_updkeys;
87 0           each %{$self->{keys}};
  0            
88             }
89              
90             =head2 NEXTKEY
91              
92             Gets the next key from the hash. Used for iteration with each()
93              
94             =cut
95              
96             sub NEXTKEY {
97 0     0     each %{shift->{keys}};
  0            
98             }
99              
100             =head2 EXISTS
101              
102             Tests if a key is in the hash. Also returns true for blocks or addresses
103             contained within a block that was actually stored.
104              
105             =cut
106              
107             sub EXISTS {
108 0     0     my ($self, $key) = @_;
109 0           $self->_updkeys;
110 0           exists $self->{keys}{$key};
111             }
112              
113             =head2 DELETE
114              
115             Delete a key from the hash. Note that the same restrictions as for Net::CIDR::Lookup
116             regarding netblock splitting apply!
117              
118             =cut
119              
120             sub DELETE {
121 0     0     carp('Deletions are not supported by tied ' . __PACKAGE__ . ' objects yet!');
122             }
123              
124             =head2 CLEAR
125              
126             Deletes all keys and their values.
127              
128             =cut
129              
130             sub CLEAR {
131 0     0     my $self = shift;
132 0           $self->{tree}->clear;
133             }
134              
135             =head2 SCALAR
136              
137             Returns the number of keys in the hash
138              
139             =cut
140              
141             sub SCALAR {
142 0     0     my $self = shift;
143 0           $self->_updkeys;
144 0           scalar keys %{$self->{keys}};
  0            
145             }
146              
147             =head2 _updkeys
148              
149             Private method to update the internal key cache used for iteration
150              
151             =cut
152              
153             sub _updkeys {
154 0     0     my $self = shift;
155              
156 0 0         if(defined $self->{keys}) {
157 0           keys %{$self->{keys}}; # Call in void context to reset
  0            
158             } else {
159 0           $self->{keys} = $self->{tree}->to_hash; # Recreate hash
160             }
161             }
162             1;