File Coverage

blib/lib/WWW/Form/UrlEncoded/PP.pm
Criterion Covered Total %
statement 67 67 100.0
branch 32 34 94.1
condition 14 18 77.7
subroutine 9 9 100.0
pod 0 5 0.0
total 122 133 91.7


line stmt bran cond sub pod time code
1             package WWW::Form::UrlEncoded::PP;
2              
3 7     7   164423 use strict;
  7         37  
  7         170  
4 7     7   28 use warnings;
  7         13  
  7         160  
5 7     7   29 use base qw/Exporter/;
  7         10  
  7         6102  
6              
7             our @EXPORT_OK = qw/parse_urlencoded parse_urlencoded_arrayref build_urlencoded build_urlencoded_utf8/;
8              
9             our $DECODE = qr/%([0-9a-fA-F]{2})/;
10             our %DecodeMap;
11             our %EncodeMap;
12             for my $num ( 0 .. 255 ) {
13             my $h = sprintf "%02X", $num;
14             my $chr = chr $num;
15             $DecodeMap{ lc $h } = $chr; #%aa
16             $DecodeMap{ uc $h } = $chr; #%AA
17             $DecodeMap{ ucfirst lc $h } = $chr; #%Aa
18             $DecodeMap{ lcfirst uc $h } = $chr; #%aA
19             $EncodeMap{$chr} = '%'. uc $h;
20             }
21             $EncodeMap{" "} = '+';
22              
23             sub parse_urlencoded {
24 130     130 0 22236 my @params;
25 130 100       294 return @params unless defined $_[0];
26 126         441 for my $pair ( split( /[&;] ?/, $_[0], -1 ) ) {
27 240         325 $pair =~ y/\+/\x20/;
28 240         508 my ($key, $val) = split /=/, $pair, 2;
29 240         359 for ($key, $val) {
30 480 100       699 if ( ! defined $_ ) {
31 42         53 push @params, '';
32 42         64 next;
33             }
34 438         929 s/$DECODE/$DecodeMap{$1}/gs;
35 438         798 push @params, $_;
36             }
37             }
38              
39 126         446 return @params;
40             }
41              
42             sub parse_urlencoded_arrayref {
43 86     86 0 46146 [parse_urlencoded(@_)];
44             }
45              
46             our $NEED_UPGRADE = 0;
47             sub build_urlencoded {
48 67 100   67 0 25719 return "" unless @_;
49 65         94 my $uri = '';
50 65         71 my $delim = '&';
51 65 100 100     286 if ( ref $_[0] && ref $_[0] eq 'ARRAY') {
    100 66        
52 16         20 my @args = @{$_[0]};
  16         35  
53 16 100       35 $delim = $_[1] if defined $_[1];
54 16 100       37 utf8::encode($delim) if $NEED_UPGRADE;
55 16         29 while ( @args ) {
56 24         34 my $k = shift @args;
57 24         28 my $v = shift @args;
58 24 100 66     56 if ( ref $v && ref $v eq 'ARRAY') {
59 6         16 $uri .= url_encode($k) . '='. url_encode($_) . $delim for @$v;
60             }
61             else {
62 18         30 $uri .= url_encode($k) . '='. url_encode($v) . $delim
63             }
64             }
65             }
66             elsif ( ref $_[0] && ref $_[0] eq 'HASH') {
67 28 100       50 $delim = $_[1] if defined $_[1];
68 28 100       61 utf8::encode($delim) if $NEED_UPGRADE;
69 28         36 while ( my ($k,$v) = each %{$_[0]} ) {
  76         201  
70 48 100 66     127 if ( ref $v && ref $v eq 'ARRAY') {
71 46         90 $uri .= url_encode($k) . '='. url_encode($_) . $delim for @$v;
72             }
73             else {
74 2         5 $uri .= url_encode($k) . '='. url_encode($v) . $delim
75             }
76             }
77             }
78             else {
79 21 100 100     63 if ( @_ > 2 && @_ % 2 ) {
80 6         10 $delim = pop @_;
81 6 50       11 utf8::encode($delim) if $NEED_UPGRADE;
82             }
83 21         39 while ( @_ ) {
84 30         37 my $k = shift @_;
85 30         36 my $v = shift @_;
86 30 100 66     62 if ( ref $v && ref $v eq 'ARRAY') {
87 2         7 $uri .= url_encode($k) . '='. url_encode($_) . $delim for @$v;
88             }
89             else {
90 28         44 $uri .= url_encode($k) . '='. url_encode($v) . $delim
91             }
92             }
93             }
94 65         133 substr($uri,-1*length($delim),length($delim),"");
95 65         171 $uri;
96             }
97              
98             sub build_urlencoded_utf8 {
99 16     16 0 29 local $NEED_UPGRADE = 1;
100 16         26 my $uri = build_urlencoded(@_);
101 16         56 $uri;
102             }
103              
104             sub url_encode {
105 392 100   392 0 627 return '' unless defined $_[0];
106 362         430 my $t = shift;
107 362 100       578 utf8::encode($t) if $NEED_UPGRADE;
108             {
109 7     7   3504 use bytes;
  7         86  
  7         29  
  362         373  
110 362         573 $t =~ s!([^A-Za-z0-9\-\._~])!
111 48 50       156 join '',@EncodeMap{exists $EncodeMap{$1} ? ($1) : (split //,$1)}
112             !gsxe;
113             }
114 362         735 return $t;
115             }
116              
117             1;
118              
119             __END__