File Coverage

blib/lib/Mail/Verp.pm
Criterion Covered Total %
statement 44 56 78.5
branch 11 18 61.1
condition 3 9 33.3
subroutine 8 8 100.0
pod 4 4 100.0
total 70 95 73.6


line stmt bran cond sub pod time code
1             package Mail::Verp;
2              
3 1     1   7184 use 5.000;
  1         4  
  1         47  
4 1     1   7 use strict;
  1         2  
  1         36  
5              
6 1     1   7 use Carp;
  1         20  
  1         96  
7              
8 1     1   5 use vars qw($VERSION @ENCODE_MAP @DECODE_MAP $DEFAULT_SEPARATOR $SEPARATOR);
  1         3  
  1         954  
9             $VERSION = '0.06';
10              
11             my @chars = qw(@ : % ! - [ ]);
12              
13             @ENCODE_MAP = map { quotemeta($_), sprintf '%.2X', ord($_) } ('+', @chars);
14             @DECODE_MAP = map { sprintf('%.2X', ord($_)), $_ } (@chars, '+');
15              
16              
17             $DEFAULT_SEPARATOR = '-'; #used as a constant
18             $SEPARATOR = $DEFAULT_SEPARATOR; #used by class methods. Can be changed.
19              
20             sub separator {
21 129     129 1 4331 my $self = shift;
22            
23             #called as class or instance object?
24 129 100       286 my $var = ref($self) ? \$self->{separator} : \$SEPARATOR;
25            
26 129         163 my $value = $$var;
27              
28 129 100       240 if (@_){
29 49         66 $$var = shift;
30             }
31              
32 129         325 return $value;
33             }
34              
35             sub new
36             {
37 1     1 1 81 my $self = shift;
38 1   33     11 $self = bless { separator => $DEFAULT_SEPARATOR, @_ }, ref($self) || $self;
39 1         14 $self->separator($self->{separator});
40 1         3 return $self;
41             }
42              
43             sub encode
44             {
45 24     24 1 107 my $self = shift;
46 24         27 my $sender = shift;
47 24         25 my $recipient = shift;
48            
49 24 50       44 unless ($sender){
50 0         0 carp "Missing sender address";
51 0         0 return;
52             }
53              
54 24 50       40 unless ($recipient){
55 0         0 carp "Missing recipient address";
56 0         0 return;
57             }
58              
59 24         126 my ($slocal, $sdomain) = $sender =~ m/(.+)\@([^\@]+)$/;
60              
61 24 50 33     113 unless ($slocal && $sdomain){
62 0         0 carp "Cannot parse sender address [$sender]";
63 0         0 return;
64             }
65              
66 24         103 my ($rlocal, $rdomain) = $recipient =~ m/(.+)\@([^\@]+)$/;
67              
68 24 50 33     100 unless ($rlocal && $rdomain){
69 0         0 carp "Cannot parse recipient address [$recipient]";
70 0         0 return;
71             }
72              
73 24         59 for (my $i = 0; $i < @ENCODE_MAP; $i += 2) {
74 192         405 for my $t ($rlocal, $rdomain){
75 384         2109 $t =~ s/$ENCODE_MAP[$i]/+$ENCODE_MAP[$i + 1]/g;
76             }
77             }
78              
79 24         55 return join('', $slocal, $self->separator, $rlocal, '=', $rdomain, '@', $sdomain);
80             }
81              
82             sub decode
83             {
84 48     48 1 1339 my $self = shift;
85 48         58 my $address = shift;
86              
87 48 50       85 unless ($address){
88 0         0 carp "Missing encoded address";
89 0         0 return;
90             }
91              
92 48         87 my $separator = $self->separator;
93            
94 48 50       653 if (my ($slocal, $rlocal, $rdomain, $sdomain) =
95             $address =~ m/^(.+?)\Q${separator}\E(.+)=([^=\@]+)\@(.+)/){
96            
97             # warn "$address $slocal $rlocal $rdomain $sdomain\n";
98              
99 48         124 for (my $i = 0; $i < @DECODE_MAP; $i += 2) {
100 384         466 for my $t ($rlocal, $rdomain){
101 768         4730 $t =~ s/\+$DECODE_MAP[$i]/$DECODE_MAP[$i + 1]/ig;
102             }
103             }
104              
105 48 50       257 return (qq[$slocal\@$sdomain], qq[$rlocal\@$rdomain]) if wantarray;
106 0           return qq[$rlocal\@$rdomain];
107             }
108             else {
109 0           return $address;
110             }
111             }
112              
113              
114             1;
115             __END__