File Coverage

blib/lib/Algorithm/InversionList.pm
Criterion Covered Total %
statement 36 36 100.0
branch 9 12 75.0
condition 1 3 33.3
subroutine 5 5 100.0
pod 0 2 0.0
total 51 58 87.9


line stmt bran cond sub pod time code
1             package Algorithm::InversionList;
2              
3 1     1   6743 use 5.006;
  1         4  
  1         39  
4 1     1   5 use strict;
  1         2  
  1         27  
5 1     1   4 use warnings;
  1         13  
  1         388  
6              
7             require Exporter;
8              
9             our @ISA = qw(Exporter);
10              
11             our @EXPORT = qw(
12             invlist data_from_invlist
13             );
14             our $VERSION = '0.03';
15              
16             sub invlist
17             {
18 4     4 0 497 my $string = shift @_;
19              
20             # we need a valid string
21 4 50       12 return undef unless defined $string;
22              
23             # handle trivial case of 0-length string
24 4 100       13 return [] unless length $string;
25              
26             # this is suboptimal, we eventually want to do things in multiples of 8 (on byte boundaries)
27             # $length is length in bits, we avoid b* because it will create a list 8 times larger than C*
28 3         1883 my @unpacked = unpack("C*", $string);
29 3         274 my $length = scalar @unpacked * 8;
30 3         9 my $current = vec($string, 0, 1);
31 3         4 my $new;
32             my @list;
33              
34 3 100       12 push @list, 0 if $current;
35              
36 3         10 foreach my $offset (0..$length)
37             {
38 128131         116704 $new = vec($string, $offset, 1);
39 128131 100       181769 if ($new != $current)
40             {
41 16107         17950 push @list, $offset;
42             }
43 128131         118270 $current = $new;
44             }
45              
46 3 50 33     46 push @list, $length unless exists $list[-1] && $list[-1] == $length;
47              
48 3         334 return \@list;
49             }
50              
51             sub data_from_invlist
52             {
53 4     4 0 358 my $out = ''; # start with a blank string
54 4         5 my $append = 0; # we're appending '0' bits first
55 4         7 my $list = shift @_;
56              
57 4 50       11 return undef unless defined $list;
58              
59 4         5 my $start_offset = 0;
60 4         11 foreach my $end_offset (@$list) # for each inversion list value
61             {
62 16111         18774 foreach my $offset ($start_offset .. $end_offset-1)
63             {
64 128128         218599 vec($out, $offset, 1) = $append;
65             }
66              
67 16111         15870 $append++; # 0 => 1, 1 => 2
68 16111         13522 $append %= 2; # 2 => 0, 1 => 1
69 16111         21285 $start_offset = $end_offset;
70             }
71              
72 4         59 return $out; # return the data
73             }
74              
75             1;
76             __END__