File Coverage

blib/lib/Data/BitStream/Base.pm
Criterion Covered Total %
statement 331 410 80.7
branch 135 210 64.2
condition 26 53 49.0
subroutine 48 55 87.2
pod 37 39 94.8
total 577 767 75.2


line stmt bran cond sub pod time code
1             package Data::BitStream::Base;
2 28     28   372573 use strict;
  28         84  
  28         1213  
3 28     28   195 use warnings;
  28         327  
  28         916  
4 28     28   159 use Carp;
  28         49  
  28         3276  
5             BEGIN {
6 28     28   68 $Data::BitStream::Base::AUTHORITY = 'cpan:DANAJ';
7 28         5937 $Data::BitStream::Base::VERSION = '0.08';
8             }
9              
10             our $CODEINFO = [ { package => __PACKAGE__,
11             name => 'Unary',
12             universal => 0,
13             params => 0,
14             encodesub => sub {shift->put_unary(@_)},
15             decodesub => sub {shift->get_unary(@_)},
16             },
17             { package => __PACKAGE__,
18             name => 'Unary1',
19             universal => 0,
20             params => 0,
21             encodesub => sub {shift->put_unary1(@_)},
22             decodesub => sub {shift->get_unary1(@_)},
23             },
24             { package => __PACKAGE__,
25             name => 'BinWord',
26             universal => 0,
27             params => 1,
28             encodesub => sub {shift->put_binword(@_)},
29             decodesub => sub {shift->get_binword(@_)},
30             },
31             ];
32              
33 28     28   196 use Moo::Role;
  28         62  
  28         208  
34 28     28   49133 use MooX::Types::MooseLike::Base qw/Int Bool Str ArrayRef/;
  28         190482  
  28         23644  
35              
36             # pos is ignored while writing
37             has 'pos' => (is => 'ro', writer => '_setpos', default => sub{0});
38             has 'len' => (is => 'ro', writer => '_setlen', default => sub{0});
39             has 'mode' => (is => 'rw', default => sub{'rdwr'});
40             has '_code_pos_array' => (is => 'rw',
41             isa => ArrayRef[Int],
42             default => sub {[]} );
43             has '_code_str_array' => (is => 'rw',
44             isa => ArrayRef[Str],
45             default => sub {[]} );
46              
47             has 'file' => (is => 'ro', writer => '_setfile');
48             has 'fheader' => (is => 'ro', writer => '_setfheader');
49             has 'fheaderlines' => (is => 'ro');
50              
51             has 'writing' => (is => 'ro', isa => Bool, writer => '_setwrite', default => sub {1});
52              
53             # Useful for testing, but time consuming. Not so bad now that all the test
54             # suites call put_* ~30 times with a list instead of per-value ~30,000 times.
55             # It still makes the test suite take about 20% longer.
56             #
57             # after '_setpos' => sub {
58             # my $self = shift;
59             # my $pos = $self->pos;
60             # my $len = $self->len;
61             # die "position must be >= 0" if $pos < 0;
62             # die "position must be <= length" if $pos > $len;
63             # $pos;
64             # };
65              
66             sub BUILD {
67 1648     1648 0 94401 my $self = shift;
68              
69             # Looks like some systems aren't setting these correctly via the default.
70             # I cannot reproduce the issue even with the same versions of Perl, Moo,
71             # and Class::XSAccessor. So, we'll set them here.
72 1648         8908 $self->_code_pos_array([]);
73 1648         201904 $self->_code_str_array([]);
74 1648         182312 $self->_setpos(0);
75 1648         5606 $self->_setlen(0);
76              
77             # Change mode to canonical form
78 1648         5491 my $curmode = $self->mode;
79 1648         2946 my $is_writing;
80 1648 50       16706 if ($curmode eq 'read') { $curmode = 'r'; }
  0 50       0  
    50          
    50          
    50          
    100          
    50          
81 0         0 elsif ($curmode eq 'readonly') { $curmode = 'ro'; }
82 0         0 elsif ($curmode eq 'write') { $curmode = 'w'; }
83 0         0 elsif ($curmode eq 'writeonly') { $curmode = 'wo'; }
84 0         0 elsif ($curmode eq 'readwrite') { $curmode = 'rw'; }
85 1647         3701 elsif ($curmode eq 'rdwr') { $curmode = 'rw'; }
86 0         0 elsif ($curmode eq 'append') { $curmode = 'a'; }
87 1648 100       10498 die "Unknown mode: $curmode" unless $curmode =~ /^(?:r|ro|w|wo|rw|a)$/;
88 1647         5058 $self->mode( $curmode );
89              
90             # Set writing based on mode
91 1647 50       14564 if ($curmode =~ /^ro?$/) { $is_writing = 0; }
  0 50       0  
    50          
    0          
92 0         0 elsif ($curmode =~ /^wo?$/) { $is_writing = 1; }
93 1647         4636 elsif ($curmode eq 'rw') { $is_writing = 1; }
94 0         0 elsif ($curmode eq 'a') { $is_writing = 0; }
95              
96 1647 50       4467 if ($is_writing) {
97 1647         7868 $self->_setwrite(1);
98 1647         140400 $self->write_open;
99             } else {
100 0         0 $self->_setwrite(0);
101 0         0 $self->read_open;
102             }
103              
104 1647 50       39579 $self->write_open if $curmode eq 'a';
105             # TODO: writeonly doesn't really work
106             }
107              
108             sub DEMOLISH {
109 1648     1648 0 2590995 my $self = shift;
110 1648 100       39203 $self->write_close if $self->writing;
111             }
112              
113             my $_host_word_size; # maxbits
114             my $_all_ones; # maxval
115              
116             BEGIN {
117 28     28   314 use Config;
  28         56  
  28         3296  
118 28 50 0 28   29980 $_host_word_size =
119             ( (defined $Config{'use64bitint'} && $Config{'use64bitint'} eq 'define')
120             || (defined $Config{'use64bitall'} && $Config{'use64bitall'} eq 'define')
121             || (defined $Config{'longsize'} && $Config{'longsize'} >= 8)
122             )
123             ? 64
124             : 32;
125 28     28   176 no Config;
  28         76  
  28         3382  
126              
127             # Check sanity of ~0
128 28         101920 my $notzero = ~0;
129 28 50       137 if ($_host_word_size == 32) {
130 0         0 die "Config says 32-bit Perl, but int is $notzero" if ~0 != 0xFFFFFFFF;
131             } else {
132 28         72 die "Config says 64-bit Perl, but int is $notzero" if ((~0 >> 16) >> 16) != 0xFFFFFFFF;
133             }
134              
135             # 64-bit seems broken in Perl 5.6.2 on the 32-bit system I have (and at
136             # least one CPAN Tester shows the same). Try:
137             # perl -e 'die if 18446744073709550593 == ~0'
138             # That inexplicably dies on 64-bit 5.6.2. It works fine on 5.8.0 and later.
139             #
140             # Direct method, pre-5.8.0 Perls.
141             # $_host_word_size = 32 if $] < 5.008;
142             # Detect the symptoms (should allow 5.6.2 on 64-bit O/S to work fine):
143 28 50 50     266 if ( ($_host_word_size == 64) && (18446744073709550592 == ~0) ) {
144 0         0 $_host_word_size = 32;
145             }
146              
147 28 50       150011 $_all_ones = ($_host_word_size == 32) ? 0xFFFFFFFF : ~0;
148             }
149             # Moo 1.000007 doesn't allow inheritance of 'use constant'.
150             #use constant maxbits => $_host_word_size;
151             #use constant maxval => $_all_ones;
152             # Use a sub with empty prototype (see perlsub documentation)
153 1105889     1105889 1 9807369 sub maxbits () { $_host_word_size } ## no critic (ProhibitSubroutinePrototypes)
154 92500     92500 1 250918 sub maxval () { $_all_ones } ## no critic (ProhibitSubroutinePrototypes)
155              
156             sub rewind {
157 30205     30205 1 823130 my $self = shift;
158 30205 100       79346 $self->error_stream_mode('rewind') if $self->writing;
159 30204         50125 $self->_setpos(0);
160 30204         62646 1;
161             }
162             sub skip {
163 77787     77787 1 105653 my $self = shift;
164 77787 100       218445 $self->error_stream_mode('skip') if $self->writing;
165 77786         100375 my $skip = shift;
166 77786         139660 my $pos = $self->pos;
167 77786         117010 my $len = $self->len;
168 77786         95925 my $newpos = $pos + $skip;
169 77786 100 66     379723 $self->error_off_stream('skip') if $newpos < 0 || $newpos > $len;
170 77776         173656 $self->_setpos($newpos);
171 77776         143452 1;
172             }
173             sub exhausted {
174 1     1 1 654 my $self = shift;
175 1 50       9 $self->error_stream_mode('exhausted') if $self->writing;
176 0         0 $self->pos >= $self->len;
177             }
178             sub erase {
179 20047     20047 1 139273 my $self = shift;
180 20047         44441 $self->_setlen(0);
181 20047         542352 $self->_setpos(0);
182             # Writing state is left unchanged
183             # You want an after method to handle the data
184             }
185             sub read_open {
186 0     0 1 0 my $self = shift;
187 0 0       0 $self->error_stream_mode('read') if $self->mode eq 'wo';
188 0 0       0 $self->write_close if $self->writing;
189 0         0 my $file = $self->file;
190 0 0       0 if (defined $file) {
191 0 0       0 open(my $fp, "<", $file) or die "Cannot open file '$file' for read: $!\n";
192 0         0 my $headerlines = $self->fheaderlines;
193 0 0       0 if (defined $headerlines) {
194             # Read in their header
195 0         0 my $header = '';
196 0         0 while ($headerlines-- > 0) {
197 0         0 $header .= <$fp>;
198             }
199 0         0 $self->_setfheader($header);
200             }
201 0         0 binmode $fp;
202             # Turn off file linking while calling from_raw
203 0         0 my $saved_mode = $self->mode;
204 0         0 $self->_setfile( undef );
205 0         0 $self->mode( 'rw' );
206 0         0 my $bits = <$fp>;
207             {
208 0         0 local $/;
  0         0  
209 0         0 $self->from_raw( <$fp>, $bits );
210             }
211 0         0 close $fp;
212             # link us back.
213 0         0 $self->_setfile( $file );
214 0         0 $self->mode( $saved_mode );
215             }
216 0         0 1;
217             }
218             sub write_open {
219 27146     27146 1 45147 my $self = shift;
220 27146 50       86544 $self->error_stream_mode('write') if $self->mode eq 'ro';
221 27146 100       74001 if (!$self->writing) {
222 25427         89968 $self->_setwrite(1);
223             # pos is now ignored
224             }
225 27146         2001097 1;
226             }
227             sub write_close {
228 27091     27091 1 37148 my $self = shift;
229 27091 100       67645 if ($self->writing) {
230 27075         90852 $self->_setwrite(0);
231 27075         2099796 $self->_setpos($self->len);
232              
233 27075         58985 my $file = $self->file;
234 27075 50       67980 if (defined $file) {
235 0 0       0 open(my $fp, ">", $file) or die "Cannot open file $file for write: $!\n";
236 0         0 my $header = $self->fheader;
237 0 0 0     0 print $fp $header, "\n" if defined $header && length($header) > 0;
238 0         0 binmode $fp;
239 0         0 print $fp $self->len, "\n";
240 0         0 print $fp $self->to_raw;
241 0         0 close $fp;
242             }
243             }
244 27091         48620 1;
245             }
246              
247              
248             ####### Error handling
249             #
250             # This section has two purposes:
251             # 1. enforce a common set of failure messages for all codes.
252             # 2. enable the position to be reset to the start of a code on an error.
253             #
254             # Number 2 is relatively complex since codes can be composed of other codes,
255             # and we want to back up to the start of the outermost code. We set up a stack
256             # of saved positions which can be used when an error occurs.
257             #
258             # If your code methods do not either call other codes or make multiple calls to
259             # read / skip, then there really is no extra effort. If they do, then it is
260             # important to call code_pos_start() before starting, code_pos_set() before
261             # each successive value, and code_pos_end() when done. What you get in return
262             # is not having to worry about how far you've read -- the position will be
263             # restored to the start of the outermost code.
264             #
265             # From the user's point of view, this means if they try to read a complicated
266             # code and it is invalid, the position is left unchanged, instead of some
267             # random distance forward in the stream.
268              
269             sub code_pos_start { # Starting a code
270 106285     106285 1 140606 my $self = shift;
271 106285         130558 my $name = shift;
272 106285         117143 push @{$self->_code_pos_array}, $self->pos;
  106285         368221  
273 106285         3438846 push @{$self->_code_str_array}, $name;
  106285         315865  
274             #print STDERR "error stack is ", join(",", @{$self->_code_str_array}), "\n";
275             }
276             sub code_pos_set { # Replace position
277 183272     183272 1 266145 my $self = shift;
278 183272         633020 $self->_code_pos_array->[-1] = $self->pos;
279             }
280             sub code_pos_end { # Remove position -- we're not in this code any more
281 106164     106164 1 139046 my $self = shift;
282 106164         112677 pop @{$self->_code_pos_array};
  106164         319243  
283 106164         14213778 pop @{$self->_code_str_array};
  106164         331417  
284             }
285             sub _code_restore_pos { # Returns string of code name
286 182     182   332 my $self = shift;
287             # Check that we aren't trying to restore a position while writing
288 182 50 66     993 if ($self->writing and @{$self->_code_pos_array}) {
  64         220  
289 0         0 confess "Found code position while error in writing: " . $self->_code_str_array->[0];
290             }
291             # Put position back to start of topmost code
292 182 100       4365 if (@{$self->_code_pos_array}) {
  182         597  
293 95         5069 $self->_setpos($self->_code_pos_array->[0]);
294 95         3177 @{$self->_code_pos_array} = ();
  95         304  
295             }
296 182         7761 my $codename = '';
297 182 100       239 if (@{$self->_code_str_array}) {
  182         1860  
298 95 50       3874 $codename = $self->_code_str_array->[0] if defined $self->_code_str_array->[0];
299 95         8302 @{$self->_code_str_array} = ();
  95         314  
300             }
301 182         6960 $codename;
302             }
303              
304             # This can be called after any code routines have been used, to verify they
305             # cleaned up after themselves. Failing this usually means someone died inside
306             # an eval, while being called by a code routine. It's also possible a broken
307             # code routine did a code_pos_start then returned without a matching end.
308             sub code_pos_is_set {
309 119     119 1 215643 my $self = shift;
310 119 50       562 return unless @{$self->_code_pos_array}; # return undef if nothing.
  119         762  
311              
312 0         0 my $text = join(",", @{$self->_code_str_array});
  0         0  
313 0         0 $text;
314             }
315              
316             sub error_off_stream {
317 57     57 1 87 my $self = shift;
318 57         81 my $skipping = shift;
319              
320             # Give the skip error only if we were not reading a code.
321 57 100 100     165 if ( (defined $skipping) && (@{$self->_code_pos_array} == 0) ) {
  10         45  
322 1         181 croak "skip off end of stream";
323             }
324              
325 56         601 my $codename = $self->_code_restore_pos();
326 56 100       261 $codename = " ($codename)" if $codename ne '';
327 56         18211 croak "read off end of stream$codename";
328             }
329             sub error_stream_mode {
330 10     10 1 16 my $self = shift;
331 10         17 my $type = shift;
332 10         21 my $codename = $self->_code_restore_pos();
333 10 50       26 $codename = " ($codename)" if $codename ne '';
334              
335 10 50 66     44 croak "write while stream opened readonly"
336             if ($type eq 'write') && ($self->mode eq 'ro');
337 10 50 66     41 croak "read while stream opened writeonly"
338             if ($type eq 'read') && ($self->mode eq 'wo');
339              
340 10 100       37 if ($self->writing) {
341 7 100       28 if ($type eq 'rewind') { croak "rewind while writing$codename"; }
  1 100       110  
    100          
    50          
342 4         424 elsif ($type eq 'read' ) { croak "read while writing$codename"; }
343 1         94 elsif ($type eq 'skip' ) { croak "skip while writing$codename"; }
344 1         114 elsif ($type eq 'exhausted') { croak "exhausted while writing$codename"; }
345             } else {
346 3 50       8 if ($type eq 'write' ) { croak "write while reading$codename"; }
  3         475  
347             }
348 0         0 croak "Mode error$codename: $type";
349             }
350             sub error_code {
351 116     116 1 192 my $self = shift;
352 116         178 my $type = shift;
353 116         146 my $text = shift;
354 116 100       1839 if ($type eq 'zeroval') { # Implied text
355 54         76 $type = 'value';
356 54         74 $text = 'value must be >= 0';
357             }
358 116 50       274 if ($type eq 'range') { # Range is given the value, the min, and the max
359 0         0 $type = 'value';
360 0 0       0 if (!defined $text) {
361 0         0 $text = 'value out of range';
362             } else {
363 0         0 my $min = shift;
364 0         0 my $max = shift;
365 0         0 $text = "value $text out of range";
366 0 0 0     0 $text .= " $min - $max" if defined $min && defined $max;
367             }
368             }
369 116         517 my $codename = $self->_code_restore_pos();
370 116         211 my $trailer = '';
371 116 100       390 $trailer .= " ($codename)" if $codename ne '';
372 116 100       1792 $trailer .= ": $text" if defined $text;
373 116 100       740 if ($type eq 'param') { croak "invalid parameters$trailer"; }
  17 100       1958  
    50          
    100          
    100          
    50          
    0          
374 54         10352 elsif ($type eq 'value') { croak "invalid value$trailer"; }
375 0         0 elsif ($type eq 'string') { croak "invalid string$trailer"; }
376 6         1093 elsif ($type eq 'base') { croak "code error: invalid base$trailer";}
  38         9381  
377             elsif ($type eq 'overflow'){croak "code error: overflow$trailer";}
378 1         157 elsif ($type eq 'short') { croak "short read$trailer"; }
379 0         0 elsif ($type eq 'assert') { confess "internal assert$trailer"; }
380 0         0 else { confess "Unknown error$trailer"; }
381             }
382              
383              
384             ####### Combination functions
385             sub erase_for_write {
386 20044     20044 1 209266 my $self = shift;
387 20044         611762 $self->erase;
388 20044 100       180430 $self->write_open if !$self->writing;
389             }
390             sub rewind_for_read {
391 29547     29547 1 143606 my $self = shift;
392 29547 100       101054 $self->write_close if $self->writing;
393 29547         71081 $self->rewind;
394             }
395              
396              
397             sub readahead {
398 6     6 1 3097 my $self = shift;
399 6         14 my $bits = shift;
400 6         24 $self->read($bits, 'readahead');
401             }
402             sub read { # You need to implement this.
403 0     0 1 0 confess "The read method has not been implemented!";
404             }
405             sub write { # You need to implement this.
406 0     0 1 0 confess "The write method has not been implemented!";
407             }
408              
409              
410             sub put_unary {
411 5916     5916 1 11683 my $self = shift;
412              
413 5916         10022 foreach my $val (@_) {
414 6290 50 33     26394 $self->error_code('zeroval') unless defined $val and $val >= 0;
415 6290 50       13333 warn "Trying to write large unary value ($val)" if $val > 10_000_000;
416              
417             # Since the write routine is allowed to take any number of bits when
418             # writing 0 and 1, this works, and is very fast.
419 6290         20700 $self->write($val+1, 1);
420              
421             # Alternate implementation, much slower for large values:
422             #
423             # if ($val < maxbits) {
424             # $self->write($val+1, 1);
425             # } else {
426             # my $nbits = $val % maxbits;
427             # my $nwords = ($val-$nbits) / maxbits;
428             # $self->write(maxbits, 0) for (1 .. $nwords);
429             # $self->write($nbits+1, 1);
430             # }
431             }
432 5916         14754 1;
433             }
434             sub get_unary { # You ought to override this.
435 33456     33456 1 79749 my $self = shift;
436 33456 50       93524 $self->error_stream_mode('read') if $self->writing;
437 33456         41674 my $count = shift;
438 33456 100       64508 if (!defined $count) { $count = 1; }
  33443 100       49646  
    100          
439 9         34 elsif ($count < 0) { $count = ~0; } # Get everything
440 2         7 elsif ($count == 0) { return; }
441              
442 33454         36311 my @vals;
443 33454         71650 $self->code_pos_start('Unary');
444 33454         1147454 while ($count-- > 0) {
445 33854         73233 $self->code_pos_set;
446 33854         994993 my $val = 0;
447              
448             # Simple code:
449             #
450             # my $maxval = $len - $pos - 1; # Maximum unary value in remaining space
451             # $val++ while ( ($val <= $maxval) && ($self->read(1) == 0) );
452             # die "read off end of stream" if $pos >= $len;
453             #
454             # Faster code, looks at 32 bits at a time. Still comparatively slow.
455              
456 33854         65009 my $word = $self->read(maxbits, 'readahead');
457 33854 100       72848 last unless defined $word;
458 33690         84187 while ($word == 0) {
459 8265         13386 $val += maxbits;
460 8265         11878 $self->skip(maxbits);
461 8265         13216 $word = $self->read(maxbits, 'readahead');
462             }
463 33690         58998 while (($word >> (maxbits-1) & 1) == 0) {
464 207425         223706 $val++;
465 207425         316588 $word <<= 1;
466             }
467 33690         56635 my $nbits = $val % maxbits;
468 33690         88014 $self->skip($nbits + 1);
469              
470 33690         102702 push @vals, $val;
471             }
472 33454         71681 $self->code_pos_end;
473 33454 100       1127446 wantarray ? @vals : $vals[-1];
474             }
475              
476             # Write unary as 1111.....0 instead of 0000.....1
477             sub put_unary1 {
478 8744     8744 1 19569 my $self = shift;
479              
480 8744         15514 foreach my $val (@_) {
481 9686 100 100     43040 $self->error_code('zeroval') unless defined $val and $val >= 0;
482 9684 50       20591 warn "Trying to write large unary value ($val)" if $val > 10_000_000;
483 9684 100       17549 if ($val < maxbits) {
484 8887         32870 $self->write($val+1, maxval() << 1);
485             } else {
486 797         1465 my $nbits = $val % maxbits;
487 797         1734 my $nwords = ($val-$nbits) / maxbits();
488 797         2316 $self->write(maxbits, maxval) for (1 .. $nwords);
489 797         2119 $self->write($nbits+1, maxval() << 1);
490             }
491             }
492 8742         25111 1;
493             }
494             sub get_unary1 { # You ought to override this.
495 8968     8968 1 19907 my $self = shift;
496 8968 50       23864 $self->error_stream_mode('read') if $self->writing;
497 8968         11898 my $count = shift;
498 8968 100       17983 if (!defined $count) { $count = 1; }
  8953 50       13142  
    0          
499 15         37 elsif ($count < 0) { $count = ~0; } # Get everything
500 0         0 elsif ($count == 0) { return; }
501              
502 8968         10525 my @vals;
503 8968         33111 $self->code_pos_start('Unary1');
504 8968         272467 while ($count-- > 0) {
505 9925         22361 $self->code_pos_set;
506 9925         325994 my $val = 0;
507              
508             # Simple code:
509             #
510             # my $maxval = $len - $pos - 1; # Maximum unary value in remaining space
511             # $val++ while ( ($val <= $maxval) && ($self->read(1) == 0) );
512             # die "read off end of stream" if $pos >= $len;
513             #
514             # Faster code, looks at 32 bits at a time. Still comparatively slow.
515              
516 9925         37738 my $word = $self->read(maxbits, 'readahead');
517 9925 100       27362 last unless defined $word;
518 9843         33705 while ($word == maxval) {
519 13011         23305 $val += maxbits;
520 13011         22836 $self->skip(maxbits);
521 13011         24233 $word = $self->read(maxbits, 'readahead');
522             }
523 9843         31575 while (($word >> (maxbits-1) & 1) != 0) {
524 140818         163790 $val++;
525 140818         246875 $word <<= 1;
526             }
527 9843         17234 my $nbits = $val % maxbits;
528 9843         25053 $self->skip($nbits + 1);
529              
530 9834         33009 push @vals, $val;
531             }
532 8959         19960 $self->code_pos_end;
533 8959 100       306343 wantarray ? @vals : $vals[-1];
534             }
535              
536             # binary values of given length
537             sub put_binword {
538 817     817 1 13748 my $self = shift;
539 817         1221 my $bits = shift;
540 817 50 33     3658 $self->error_code('param', "bits must be in range 0-" . maxbits)
541             if ($bits <= 0) || ($bits > maxbits);
542              
543 817         1562 foreach my $val (@_) {
544 3493 50 33     15146 $self->error_code('zeroval') unless defined $val and $val >= 0;
545 3493         9850 $self->write($bits, $val);
546             }
547 817         2435 1;
548             }
549             sub get_binword {
550 842     842 1 13428 my $self = shift;
551 842 50       2424 $self->error_stream_mode('read') if $self->writing;
552 842         1390 my $bits = shift;
553 842 100 100     3759 $self->error_code('param', "bits must be in range 0-" . maxbits)
554             if ($bits <= 0) || ($bits > maxbits);
555 839         1312 my $count = shift;
556 839 100       2200 if (!defined $count) { $count = 1; }
  815 50       1190  
    0          
557 24         91 elsif ($count < 0) { $count = ~0; } # Get everything
558 0         0 elsif ($count == 0) { return; }
559              
560 839         1221 my @vals;
561 839         2217 while ($count-- > 0) {
562 3539         9681 my $val = $self->read($bits);
563 3537 100       8121 last unless defined $val;
564 3513         12133 push @vals, $val;
565             }
566 837 100       4112 wantarray ? @vals : $vals[-1];
567             }
568              
569              
570             # Write one or more text binary strings (e.g. '10010')
571             sub put_string {
572 5064     5064 1 8377 my $self = shift;
573 5064 50       13610 $self->error_stream_mode('write') unless $self->writing;
574              
575 5064         8540 foreach my $str (@_) {
576 5064 50       11170 next unless defined $str;
577 5064 50       12021 $self->error_code('string') if $str =~ tr/01//c;
578 5064         7562 my $bits = length($str);
579 5064 50       12043 next unless $bits > 0;
580              
581 5064         5495 my $spos = 0;
582 5064         11223 while ($bits >= 32) {
583 3051         20126 $self->write(32, oct('0b' . substr($str, $spos, 32)));
584 3051         3749 $spos += 32;
585 3051         6704 $bits -= 32;
586             }
587 5064 100       12225 if ($bits > 0) {
588 4927         23845 $self->write($bits, oct('0b' . substr($str, $spos, $bits)));
589             }
590             }
591 5064         12408 1;
592             }
593             # Get a text binary string. Similar to read, but bits can be 0 - len.
594             sub read_string {
595 2880     2880 1 5145 my $self = shift;
596 2880 100       6954 $self->error_stream_mode('read') if $self->writing;
597 2879         3494 my $bits = shift;
598 2879 100 66     11615 $self->error_code('param', "bits must be >= 0") unless defined $bits && $bits >= 0;
599 2878 100       8732 $self->error_code('short') unless $bits <= ($self->len - $self->pos);
600 2877         3879 my $str = '';
601 2877         6451 while ($bits >= 32) {
602 1542         4697 $str .= unpack("B32", pack("N", $self->read(32)));
603 1542         3890 $bits -= 32;
604             }
605 2877 100       6257 if ($bits > 0) {
606 2782         11107 $str .= substr(unpack("B32", pack("N", $self->read($bits))), -$bits);
607             }
608 2877         9975 $str;
609             }
610              
611             # Conversion to and from strings of 0's and 1's. Note that the order is
612             # completely left to right based on what was written.
613              
614             sub to_string { # You should override this.
615 2873     2873 1 25400 my $self = shift;
616 2873         6799 $self->rewind_for_read;
617 2873         7295 $self->read_string($self->len);
618             }
619             sub from_string { # You should override this.
620 2866     2866 1 31919 my $self = shift;
621             #my $str = shift;
622             #my $bits = shift || length($str);
623 2866         14010 $self->erase_for_write;
624 2866         8068 $self->put_string($_[0]);
625 2866         6090 $self->rewind_for_read;
626             }
627              
628             # Conversion to and from binary. Note that the order is completely left to
629             # right based on what was written. This means it is an array of big-endian
630             # units. This implementation uses 32-bit words as the units.
631              
632             sub to_raw { # You ought to override this.
633 3     3 1 234 my $self = shift;
634 3         33 $self->rewind_for_read;
635 3         11 my $len = $self->len;
636 3         20 my $pos = $self->pos;
637 3         8 my $vec = '';
638 3         13 while ( ($pos+31) < $len ) {
639 1296         4703 $vec .= pack("N", $self->read(32));
640 1296         2963 $pos += 32;
641             }
642 3 50       19 if ($pos < $len) {
643 3         28 $vec .= pack("N", $self->read($len-$pos) << 32-($len-$pos));
644             }
645 3         28 $vec;
646             }
647             sub put_raw { # You ought to override this.
648 2     2 1 5 my $self = shift;
649 2 50       9 $self->error_stream_mode('write') unless $self->writing;
650              
651 2         6 my $vec = shift;
652 2   33     6 my $bits = shift || int((length($vec)+7)/8);
653              
654 2         4 my $vpos = 0;
655 2         8 while ($bits >= 32) {
656 1062         3318 $self->write(32, unpack("N", substr($vec, $vpos, 4)));
657 1062         1336 $vpos += 4;
658 1062         1994 $bits -= 32;
659             }
660 2 50       11 if ($bits > 0) {
661 2         10 my $nbytes = int(($bits+7)/8); # this many bytes left
662 2         5 my $pvec = substr($vec, $vpos, $nbytes); # extract the bytes
663 2         6 vec($pvec,33,1) = 0; # zero fill the 32-bit word
664 2         5 my $word = unpack("N", $pvec); # unpack the filled word
665 2         9 $word >>= (32-$bits); # shift data to lower bits
666 2         8 $self->write($bits, $word); # write data to stream
667             }
668 2         7 1;
669             }
670             sub from_raw {
671 5     5 1 17734 my $self = shift;
672 5         15 my $vec = shift;
673 5   33     30 my $bits = shift || int((length($vec)+7)/8);
674 5         23 $self->erase_for_write;
675 5         29 $self->put_raw($vec, $bits);
676 5         22 $self->rewind_for_read;
677             }
678              
679             # Conversion to and from your internal data. This can be in any form desired.
680             # This could be a little-endian array, or a byte stream, or a string, etc.
681             # The main point is that we can get a single chunk that can be saved off, and
682             # later can restore the stream. This should be efficient.
683              
684             sub to_store { # You ought to implement this.
685 3     3 1 19 my $self = shift;
686 3         16 $self->to_raw(@_);
687             }
688             sub from_store { # You ought to implement this.
689 3     3 1 26999 my $self = shift;
690 3         23 $self->from_raw(@_);
691             }
692              
693             # Takes a stream and inserts its contents into the current stream.
694             # Non-destructive to both streams.
695             sub put_stream {
696 6     6 1 28 my $self = shift;
697 6         10 my $source = shift;
698 6 50 33     59 return 0 unless defined $source && $source->can('to_string');
699              
700             # In an implementation, you could check if ref $source eq __PACKAGE__
701             # and do something special. BLVec / XS does this.
702              
703             # This is reasonably fast for most implementations.
704 6         19 $self->put_string($source->to_string);
705             # In theory this could be faster. Since all the implementations have custom
706             # string code, and none have custom raw code, it's currently slower.
707             # $self->put_raw($source->to_raw, $source->len);
708 6         17 1;
709             }
710              
711              
712              
713             # Helper class methods for other functions
714             sub _floorlog2 {
715 0     0     my $d = shift;
716 0           my $base = 0;
717 0           $base++ while ($d >>= 1);
718 0           $base;
719             }
720             sub _ceillog2 {
721 0     0     my $d = shift;
722 0           $d--;
723 0           my $base = 1;
724 0           $base++ while ($d >>= 1);
725 0           $base;
726             }
727             sub _bin_to_dec {
728 28     28   531 no warnings 'portable';
  28         68  
  28         5573  
729 0     0     oct '0b' . substr($_[1], 0, $_[0]);
730             }
731             sub _dec_to_bin {
732             # The following is typically fastest with 5.9.2 and later:
733             #
734             # scalar reverse unpack("b$bits",($bits>32) ? pack("Q>",$v) : pack("V",$v));
735             #
736             # With 5.9.2 and later on a 64-bit machine, this will work quickly:
737             #
738             # substr(unpack("B64", pack("Q>", $v)), -$bits);
739             #
740             # This is the best compromise that works with 5.8.x, BE/LE, and 32-bit:
741 0     0     my $bits = shift;
742 0           my $v = shift;
743 0 0         if ($bits > 32) {
744             # return substr(unpack("B64", pack("Q>", $v)), -$bits); # needs v5.9.2
745 0           return substr(unpack("B32", pack("N", $v>>32)), -($bits-32))
746             . unpack("B32", pack("N", $v));
747             } else {
748             # return substr(unpack("B32", pack("N", $v)), -$bits); # slower
749 0           return scalar reverse unpack("b$bits", pack("V", $v));
750             }
751             }
752              
753 28     28   191 no Moo::Role;
  28         65  
  28         391  
754             1;
755              
756              
757             # ABSTRACT: A Role implementing the API for Data::BitStream
758              
759             =pod
760              
761             =head1 NAME
762              
763             Data::BitStream::Base - A Role implementing the API for Data::BitStream
764              
765             =head1 SYNOPSIS
766              
767             use Moo;
768             with 'Data::BitStream::Base';
769              
770             =head1 DESCRIPTION
771              
772             A role written for L that provides the basic API, including
773             generic code for almost all functionality.
774              
775             This is used by particular implementations such as L
776             and L.
777              
778              
779              
780              
781             =head2 DATA
782              
783             =over 4
784              
785             =item B< pos >
786              
787             A read-only non-negative integer indicating the current position in a read
788             stream. It is advanced by C, C, and C methods, as well
789             as changed by C, C, C, and C methods.
790              
791             =item B< len >
792              
793             A read-only non-negative integer indicating the current length of the stream
794             in bits. It is advanced by C and C methods, as well as changed
795             by C and C methods.
796              
797             =item B< writing >
798              
799             A read-only boolean indicating whether the stream is open for writing or
800             reading. Methods for read such as
801             C, C, C, C, C, and C
802             are not allowed while writing. Methods for write such as
803             C and C
804             are not allowed while reading.
805              
806             The C and C methods will set writing to true.
807             The C and C methods will set writing to false.
808              
809             The read/write distinction allows implementations more freedom in internal
810             caching of data. For instance, they can gather writes into blocks. It also
811             can be helpful in catching mistakes such as reading from a target stream.
812              
813             =item B< mode >
814              
815             The stream mode. Especially useful when given a file. The mode may be one of
816              
817             r (read)
818             ro (readonly)
819             w (write)
820             wo (writeonly)
821             rdwr (readwrite)
822             a (append)
823              
824             =item B< file >
825              
826             The name of a file to read or write (depending on the mode).
827              
828             =item B< fheaderlines >
829              
830             Only applicible when reading a file. Indicates how many header lines exist
831             before the data.
832              
833             =item B< fheader >
834              
835             When writing a file, this is the header to write before the data.
836             When reading a file, this will be set to the header, if fheaderlines was given.
837              
838             =back
839              
840              
841              
842              
843             =head2 CLASS METHODS
844              
845             =over 4
846              
847             =item B< maxbits >
848              
849             Returns the number of bits in a word, which is the largest allowed size of
850             the C argument to C and C. This will be either 32 or 64.
851              
852             =item B< maxval >
853              
854             Returns the maximum value we can handle. This should be C< 2 ** maxbits - 1 >,
855             or C< 0xFFFF_FFFF > for 32-bit, and C< 0xFFFF_FFFF_FFFF_FFFF > for 64-bit.
856              
857             =back
858              
859              
860              
861              
862             =head2 OBJECT METHODS (I)
863              
864             These methods are only valid while the stream is in reading state.
865              
866             =over 4
867              
868             =item B< rewind >
869              
870             Moves the position to the stream beginning.
871              
872             =item B< exhausted >
873              
874             Returns true is the stream is at the end. Rarely used.
875              
876             =item B< read($bits [, 'readahead']) >
877              
878             Reads C<$bits> from the stream and returns the value.
879             C<$bits> must be between C<1> and C.
880              
881             Returns undef if the current position is at the end of the stream.
882              
883             Croaks with an off stream error if not enough bits are left in the stream.
884              
885             The position is advanced unless the second argument is the string 'readahead'.
886              
887             I: You have to implement this.
888              
889             =item B< readahead($bits>) >
890              
891             Identical to calling read with 'readahead' as the second argument.
892             Returns the value of the next C<$bits> bits (between C<1> and C).
893             Returns undef if the current position is at the end.
894             Allows reading past the end of the stream (fills with zeros as necessary).
895             Does not advance the position.
896              
897             =item B< skip($bits) >
898              
899             Advances the position C<$bits> bits.
900             Typically used in conjunction with C.
901              
902             =item B< get_unary([$count]) >
903              
904             Reads one or more values from the stream in C<0000...1> unary coding.
905             If C<$count> is C<1> or not supplied, a single value will be read.
906             If C<$count> is positive, that many values will be read.
907             If C<$count> is negative, values are read until the end of the stream.
908              
909             In list context this returns a list of all values read. In scalar context
910             it returns the last value read.
911              
912             I: You should have efficient code for this.
913              
914             =item B< get_unary1([$count]) >
915              
916             Like C, but using C<1111...0> unary coding. Less common.
917              
918             =item B< get_binword($bits, [$count]) >
919              
920             Reads one or more values from the stream as fixed-length binary numbers, each
921             using C<$bits> bits. The treatment of count and return values is identical to
922             C.
923              
924             =item B< read_string($bits) >
925              
926             Reads C<$bits> bits from the stream and returns them as a binary string, such
927             as '0011011'.
928              
929             =back
930              
931              
932              
933              
934             =head2 OBJECT METHODS (I)
935              
936             These methods are only valid while the stream is in writing state.
937              
938             =over 4
939              
940             =item B< write($bits, $value) >
941              
942             Writes C<$value> to the stream using C<$bits> bits.
943             C<$bits> must be between C<1> and C, unless C is 0 or 1, in
944             which case C may be larger than C.
945              
946             The stream length will be increased by C<$bits> bits.
947             Regardless of the contents of C<$value>, exactly C<$bits> bits will be used.
948             If C<$value> has more non-zero bits than C<$bits>, the lower bits are written.
949             In other words, C<$value> will be masked before writing.
950              
951             I: You have to implement this.
952              
953             =item B< put_unary(@values) >
954              
955             Writes the values to the stream in C<0000...1> unary coding.
956             Unary coding is only appropriate for relatively small numbers, as it uses
957             C<$value + 1> bits.
958              
959             I: You should have efficient code for this.
960              
961             =item B< put_unary1(@values) >
962              
963             Like C, but using C<1111...0> unary coding. Less common.
964              
965             =item B< put_binword($bits, @values) >
966              
967             Writes the values to the stream as fixed-length binary values. This is just
968             a loop inserting each value with C.
969              
970             =item B< put_string(@strings) >
971              
972             Takes one or more binary strings, such as '1001101', '001100', etc. and
973             writes them to the stream. The number of bits used for each value is equal
974             to the string length.
975              
976             =item B< put_raw($packed, [, $bits]) >
977             Writes the packed big-endian vector C<$packed> which has C<$bits> bits of data.
978             If C<$bits> is not present, then C will be used as the
979             byte-length. It is recommended that you include C<$bits>.
980              
981             =item B< put_stream($source_stream) >
982              
983             Writes the contents of C<$source_stream> to the stream. This is a helper
984             method that might be more efficient than doing it in one of the many other
985             possible ways. Some functionally equivalent methods:
986              
987             $self->put_string( $source_stream->to_string ); # The default for put_stream
988              
989             $self->put_raw( $source_stream->to_raw, $source_stream->len );
990              
991             my $bits = $source_stream->len;
992             $source_stream->rewind_for_read;
993             while ($bits > 0) {
994             my $wbits = ($bits >= 32) ? 32 : $bits;
995             $self->write($wbits, $source_stream->read($wbits));
996             $bits -= $wbits;
997             }
998              
999             =back
1000              
1001              
1002              
1003              
1004             =head2 OBJECT METHODS (I)
1005              
1006             These methods may be called at any time, and will adjust the state of the
1007             stream.
1008              
1009             =over 4
1010              
1011             =item B< to_string >
1012              
1013             Returns the stream as a binary string, e.g. '00110101'.
1014              
1015             =item B< to_raw >
1016              
1017             Returns the stream as packed big-endian data. This form is portable to
1018             any other implementation on any architecture.
1019              
1020             =item B< to_store >
1021              
1022             Returns the stream as some scalar holding the data in some implementation
1023             specific way. This may be portable or not, but it can always be read by
1024             the same implementation. It might be more efficient than the raw format.
1025              
1026              
1027             =item B< from_string($string) >
1028              
1029             The stream will be set to the binary string C<$string>.
1030              
1031             =item B< from_raw($packed [, $bits]) >
1032              
1033             The stream is set to the packed big-endian vector C<$packed> which has
1034             C<$bits> bits of data. If C<$bits> is not present, then C
1035             will be used as the byte-length. It is recommended that you include C<$bits>.
1036              
1037             =item B< from_store($blob [, $bits]) >
1038              
1039             Similar to C, but using the value returned by C.
1040              
1041             =back
1042              
1043              
1044              
1045              
1046             =head2 OBJECT METHODS (I)
1047              
1048             =over 4
1049              
1050             =item B< erase >
1051              
1052             Erases all the data, while the writing state is left unchanged. The position
1053             and length will both be 0 after this is finished.
1054              
1055             I: You need an 'after' method to actually erase the data.
1056              
1057             =item B< read_open >
1058              
1059             Reads the current input file, if one exists.
1060              
1061             =item B< write_open >
1062              
1063             Changes the state to writing with no other API-visible changes.
1064              
1065             =item B< write_close >
1066              
1067             Changes the state to reading, and the position is set to the end of the
1068             stream. No other API-visible changes happen.
1069              
1070             =item B< erase_for_write >
1071              
1072             A helper function that performs C followed by C.
1073              
1074             =item B< rewind_for_read >
1075              
1076             A helper function that performs C followed by C.
1077              
1078             =back
1079              
1080              
1081              
1082              
1083             =head2 INTERNAL METHODS
1084              
1085             These methods are used by roles.
1086             As a stream user you should not be using these.
1087              
1088             =over 4
1089              
1090             =item B< code_pos_start >
1091              
1092             =item B< code_pos_end >
1093              
1094             =item B< code_pos_set >
1095              
1096             Used to handle exceptions for codes that call other codes. Generally used
1097             in C< get_* > methods. The primary reasoning for this is that we want to
1098             unroll the stream location back to where the caller tried to read the code
1099             on an error. That way they can try again with a different code, or examine
1100             the bits that resulted in an incorrect code.
1101             C starts a new stack entry, C sets the start
1102             of the current code so we know where to go back to, and C
1103             indicates we're done so the code stack entry can be removed.
1104              
1105             =item B< code_pos_is_set >
1106              
1107             Returns the code stack or C if not in a code. This should always be
1108             C for users. If it is not, it means some code routine finished
1109             abnormally and didn't remove their error stack.
1110              
1111             =item B< error_off_stream >
1112              
1113             Croaks with a message about reading or skipping off the stream. If this
1114             happens inside a C method, it should indicate the outermost code that
1115             was used. The stream position is restored to the start of the outer code.
1116              
1117             =item B< error_stream_mode >
1118              
1119             Croaks with a message about the wrong mode being used. This is what happens
1120             when an attempt is made to write to a stream opened for reading, or read from
1121             a stream opened for writing.
1122              
1123             =item B< error_code >
1124              
1125             Central routine that captures code errors, including incorrect parameters,
1126             values out of range, overflows, range errors, etc. All errors cause a croak
1127             except assertions, which will confess (since they indicate a serious internal
1128             issue). Some additional information is also included if possible (e.g. the
1129             outermost code being used, the allowed range, the value, etc.).
1130              
1131             =back
1132              
1133              
1134              
1135              
1136             =head1 SEE ALSO
1137              
1138             =over 4
1139              
1140             =item L
1141              
1142             =item L
1143              
1144             =item L
1145              
1146             =back
1147              
1148             =head1 AUTHORS
1149              
1150             Dana Jacobsen Edana@acm.orgE
1151              
1152             =head1 COPYRIGHT
1153              
1154             Copyright 2011-2012 by Dana Jacobsen Edana@acm.orgE
1155              
1156             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
1157              
1158             =cut