File Coverage

blib/lib/Protocol/HTTP2/Huffman.pm
Criterion Covered Total %
statement 28 28 100.0
branch 4 6 66.6
condition n/a
subroutine 6 6 100.0
pod 0 2 0.0
total 38 42 90.4


line stmt bran cond sub pod time code
1             package Protocol::HTTP2::Huffman;
2 13     13   20497 use strict;
  13         15  
  13         282  
3 13     13   37 use warnings;
  13         15  
  13         228  
4 13     13   4219 use Protocol::HTTP2::HuffmanCodes;
  13         19  
  13         1473  
5 13     13   2961 use Protocol::HTTP2::Trace qw(tracer);
  13         16  
  13         3673  
6             our ( %hcodes, %rhcodes, $hre );
7             require Exporter;
8             our @ISA = qw(Exporter);
9             our @EXPORT = qw(huffman_encode huffman_decode);
10              
11             # Memory unefficient algorithm (well suited for short strings)
12              
13             sub huffman_encode {
14 80     80 0 8228 my $s = shift;
15 80         7920 my $ret = my $bin = '';
16 80         8025 for my $i ( 0 .. length($s) - 1 ) {
17 1403         17222 $bin .= $hcodes{ ord( substr $s, $i, 1 ) };
18             }
19 80 100       8111 $bin .= substr( $hcodes{256}, 0, 8 - length($bin) % 8 ) if length($bin) % 8;
20 80         16035 return $ret . pack( 'B*', $bin );
21             }
22              
23             sub huffman_decode {
24 67     67 0 7705 my $s = shift;
25 67         7370 my $bin = unpack( 'B*', $s );
26              
27 67         7205 my $c = 0;
28 67         8345 $s = pack 'C*', map { $c += length; $rhcodes{$_} } ( $bin =~ /$hre/g );
  1349         154526  
  1349         310546  
29 67 50       7703 tracer->warning(
30             sprintf(
31             "malformed data in string at position %i, " . " length: %i",
32             $c, length($bin)
33             )
34             ) if length($bin) - $c > 8;
35             tracer->warning(
36             sprintf "no huffman code 256 at the end of encoded string '%s': %s\n",
37             substr( $s, 0, 30 ),
38             substr( $bin, $c )
39 67 50       7545 ) if $hcodes{256} !~ /^@{[ substr($bin, $c) ]}/;
  67         15025  
40 67         14460 return $s;
41             }
42              
43             1;