File Coverage

blib/lib/Data/BitStream/Code/EvenRodeh.pm
Criterion Covered Total %
statement 59 60 98.3
branch 19 24 79.1
condition 3 3 100.0
subroutine 9 9 100.0
pod 2 2 100.0
total 92 98 93.8


line stmt bran cond sub pod time code
1             package Data::BitStream::Code::EvenRodeh;
2 28     28   21828 use strict;
  28         60  
  28         1005  
3 28     28   159 use warnings;
  28         53  
  28         1341  
4             BEGIN {
5 28     28   83 $Data::BitStream::Code::EvenRodeh::AUTHORITY = 'cpan:DANAJ';
6 28         7147 $Data::BitStream::Code::EvenRodeh::VERSION = '0.08';
7             }
8              
9             our $CODEINFO = { package => __PACKAGE__,
10             name => 'EvenRodeh',
11             universal => 1,
12             params => 0,
13             encodesub => sub {shift->put_evenrodeh(@_)},
14             decodesub => sub {shift->get_evenrodeh(@_)}, };
15              
16             sub _floorlog2_er {
17 11513     11513   13444 my $d = shift;
18 11513         12023 my $base = 0;
19 11513         92198 $base++ while ($d >>= 1);
20 11513         18427 $base;
21             }
22             sub _dec_to_bin_er {
23 11513     11513   11947 my $bits = shift;
24 11513         11613 my $val = shift;
25 11513 100       19725 if ($bits > 32) {
26 885         5021 return substr(unpack("B32", pack("N", $val>>32)), -($bits-32))
27             . unpack("B32", pack("N", $val));
28             } else {
29             #return substr(unpack("B32", pack("N", $val)), -$bits);
30 10628         55397 return scalar reverse unpack("b$bits", pack("V", $val));
31             }
32             }
33              
34 28     28   168 use Moo::Role;
  28         68  
  28         220  
35             requires qw(read write put_string);
36              
37             # Even-Rodeh code
38             #
39             # Similar in many ways to the Elias Omega code. Very rarely used code.
40              
41             sub put_evenrodeh {
42 4311     4311 1 24451 my $self = shift;
43              
44 4311         7296 foreach my $val (@_) {
45 6987 100 100     30271 $self->error_code('zeroval') unless defined $val and $val >= 0;
46 6985 100       39818 if ($val <= 3) {
47 2622         7228 $self->write(3, $val);
48             } else {
49 4363         6384 my $str = '0';
50 4363         5182 my $v = $val;
51 4363         4912 do {
52 11513         20151 my $base = _floorlog2_er($v)+1;
53 11513         19275 $str = _dec_to_bin_er($base, $v) . $str;
54 11513         40096 $v = $base;
55             } while ($v > 3);
56 4363         14730 $self->put_string($str);
57             }
58             }
59 4309         11447 1;
60             }
61              
62             sub get_evenrodeh {
63 4354     4354 1 23958 my $self = shift;
64 4354         5459 my $count = shift;
65 4354 100       8262 if (!defined $count) { $count = 1; }
  4330 50       5665  
    0          
66 24         55 elsif ($count < 0) { $count = ~0; } # Get everything
67 0         0 elsif ($count == 0) { return; }
68              
69 4354         4900 my @vals;
70 4354         11756 my $maxbits = $self->maxbits;
71 4354         11565 $self->code_pos_start('EvenRodeh');
72 4354         120029 while ($count-- > 0) {
73 7054         18332 $self->code_pos_set;
74              
75 7054         218623 my $val = $self->read(3);
76 7054 100       23137 last unless defined $val;
77              
78 7005 100       14021 if ($val > 3) {
79 4377         4712 my $first_bit;
80 4377         12102 while ($first_bit = $self->read(1)) {
81 7166 100       15111 $self->error_code('overflow') if ($val-1) > $maxbits;
82 7162         19199 my $next = $self->read($val-1);
83 7162 50       15488 $self->error_off_stream unless defined $next;
84 7162         21808 $val = (1 << ($val-1)) | $next;
85             }
86 4373 50       9330 $self->error_off_stream unless defined $first_bit;
87             }
88 7001         19342 push @vals, $val;
89             }
90 4350         11666 $self->code_pos_end;
91 4350 100       147943 wantarray ? @vals : $vals[-1];
92             }
93 28     28   21651 no Moo::Role;
  28         60  
  28         248  
94             1;
95              
96             # ABSTRACT: A Role implementing Even-Rodeh codes
97              
98             =pod
99              
100             =head1 NAME
101              
102             Data::BitStream::Code::EvenRodeh - A Role implementing Even-Rodeh codes
103              
104             =head1 VERSION
105              
106             version 0.08
107              
108             =head1 DESCRIPTION
109              
110             A role written for L that provides get and set methods for
111             the Even-Rodeh codes. The role applies to a stream object.
112              
113             =head1 METHODS
114              
115             =head2 Provided Object Methods
116              
117             =over 4
118              
119             =item B< put_evenrodeh($value) >
120              
121             =item B< put_evenrodeh(@values) >
122              
123             Insert one or more values as Even-Rodeh codes. Returns 1.
124              
125             =item B< get_evenrodeh() >
126              
127             =item B< get_evenrodeh($count) >
128              
129             Decode one or more Even-Rodeh codes from the stream. If count is omitted,
130             one value will be read. If count is negative, values will be read until
131             the end of the stream is reached. In scalar context it returns the last
132             code read; in array context it returns an array of all codes read.
133              
134             =back
135              
136             =head2 Required Methods
137              
138             =over 4
139              
140             =item B< read >
141              
142             =item B< write >
143              
144             =item B< put_string >
145              
146             These methods are required for the role.
147              
148             =back
149              
150             =head1 SEE ALSO
151              
152             =over 4
153              
154             =item S. Even, M. Rodeh, "Economical Encoding of Commas Between Strings", Comm ACM, Vol 21, No 4, pp 315-317, April 1978.
155              
156             =item Peter Fenwick, "Punctured Elias Codes for variable-length coding of the integers", Technical Report 137, Department of Computer Science, University of Auckland, December 1996
157              
158             =back
159              
160             =head1 AUTHORS
161              
162             Dana Jacobsen
163              
164             =head1 COPYRIGHT
165              
166             Copyright 2011 by Dana Jacobsen
167              
168             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
169              
170             =cut