File Coverage

blib/lib/AnyEvent/Util/idna.pl
Criterion Covered Total %
statement 74 74 100.0
branch 17 20 85.0
condition 3 5 60.0
subroutine 8 8 100.0
pod 2 3 66.6
total 104 110 94.5


line stmt bran cond sub pod time code
1             # based on RFC 3492
2              
3 1     1   6 use AnyEvent (); BEGIN { AnyEvent::common_sense }
  1     1   2  
  1         22  
  1         4  
4 1     1   5 use Carp ();
  1         2  
  1         10  
5 1     1   4 use List::Util ();
  1         2  
  1         80  
6 1     1   592 use integer;
  1         13  
  1         6  
7              
8             sub pyc_base () { 36 }
9             sub pyc_tmin () { 1 }
10             sub pyc_tmax () { 26 }
11             sub pyc_initial_bias () { 72 }
12             sub pyc_initial_n () { 128 }
13              
14             sub pyc_digits () { "abcdefghijklmnopqrstuvwxyz0123456789" }
15              
16             sub pyc_adapt($$$) {
17 12     12 0 21 my ($delta, $numpoints, $firsttime) = @_;
18              
19 12 100       25 $delta = $firsttime ? $delta / 700 : $delta >> 1;
20 12         14 $delta += $delta / $numpoints;
21              
22 12         13 my $k;
23              
24 12         20 while ($delta > (pyc_base - pyc_tmin) * pyc_tmax / 2) {
25 6         7 $delta /= pyc_base - pyc_tmin;
26 6         9 $k += pyc_base;
27             }
28              
29 12         18 $k + $delta * (pyc_base - pyc_tmin + 1) / ($delta + 38)
30             }
31              
32             sub punycode_encode($) {
33 5     5 1 392 my ($input) = @_;
34              
35 5         12 my ($n, $bias, $delta) = (pyc_initial_n, pyc_initial_bias);
36              
37 5         13 (my $output = $input) =~ y/\x00-\x7f//cd;
38 5         13 my $h = my $b = length $output;
39              
40 5         14 my @input = split '', $input;
41              
42 5 100 66     23 $output .= "-" if $b && $h < @input;
43              
44 5         14 while ($h < @input) {
45 9         22 my $m = List::Util::min grep { $_ >= $n } map ord, @input;
  25         99  
46              
47 9 50       24 $m - $n <= (0x7fffffff - $delta) / ($h + 1)
48             or Carp::croak "punycode_encode: overflow in punycode delta encoding";
49 9         15 $delta += ($m - $n) * ($h + 1);
50 9         11 $n = $m;
51              
52 9         14 for my $i (@input) {
53 25         27 my $c = ord $i;
54 25 100 50     41 ++$delta < 0x7fffffff
55             or Carp::croak "punycode_encode: overflow in punycode delta encoding"
56             if $c < $n;
57              
58 25 100       40 if ($c == $n) {
59 9         15 my ($q, $k) = ($delta, pyc_base);
60              
61 9         11 while () {
62 29         47 my $t = List::Util::min pyc_tmax, List::Util::max pyc_tmin, $k - $bias;
63              
64 29 100       46 last if $q < $t;
65              
66 20         36 $output .= substr pyc_digits, $t + (($q - $t) % (pyc_base - $t)), 1;
67              
68 20         27 $q = ($q - $t) / (pyc_base - $t);
69 20         20 $k += pyc_base;
70             }
71              
72 9         15 $output .= substr pyc_digits, $q, 1;
73              
74 9         17 $bias = pyc_adapt $delta, $h + 1, $h == $b;
75              
76 9         11 $delta = 0;
77 9         11 ++$h;
78             }
79             }
80              
81 9         11 ++$delta;
82 9         13 ++$n;
83             }
84              
85             $output
86 5         17 }
87              
88             sub punycode_decode($) {
89 2     2 1 113 my ($input) = @_;
90              
91 2         4 my ($n, $bias, $i) = (pyc_initial_n, pyc_initial_bias);
92 2         3 my $output;
93              
94 2 100       13 if ($input =~ /^(.*?)-([^-]*)$/x) {
95 1         3 $output = $1;
96 1         30 $input = $2;
97              
98 1 50       6 $output =~ /[^\x00-\x7f]/
99             and Carp::croak "punycode_decode: malformed punycode";
100             }
101              
102 2         4 while (length $input) {
103 3         5 my $oldi = $i;
104 3         4 my $w = 1;
105              
106 3         3 for (my $k = pyc_base; ; $k += pyc_base) {
107 9 50       19 (my $digit = index pyc_digits, substr $input, 0, 1, "")
108             >= 0
109             or Carp::croak "punycode_decode: malformed punycode";
110            
111 9         11 $i += $digit * $w;
112            
113 9         15 my $t = List::Util::max pyc_tmin, List::Util::min pyc_tmax, $k - $bias;
114 9 100       17 last if $digit < $t;
115              
116 6         7 $w *= pyc_base - $t;
117             }
118              
119 3         4 my $outlen = 1 + length $output;
120 3         5 $bias = pyc_adapt $i - $oldi, $outlen, $oldi == 0;
121              
122 3         5 $n += $i / $outlen;
123 3         3 $i %= $outlen;
124              
125 3         11 substr $output, $i, 0, chr $n;
126 3         6 ++$i;
127             }
128              
129             $output
130 2         5 }
131              
132             1