File Coverage

blib/lib/Data/ParseBinary/Stream/Bit.pm
Criterion Covered Total %
statement 63 73 86.3
branch 13 18 72.2
condition n/a
subroutine 13 17 76.4
pod n/a
total 89 108 82.4


line stmt bran cond sub pod time code
1 5     5   23 use strict;
  5         10  
  5         151  
2 5     5   24 use warnings;
  5         7  
  5         5980  
3            
4             package Data::ParseBinary::Stream::BitReader;
5             our @ISA = qw{Data::ParseBinary::Stream::Reader Data::ParseBinary::Stream::WrapperBase};
6            
7             __PACKAGE__->_registerStreamType("Bit");
8            
9             sub new {
10 32     32   50 my ($class, $byteStream) = @_;
11 32         127 my $self = bless { buffer => '' }, $class;
12 32         131 $self->_warping($byteStream);
13 32         125 return $self;
14             }
15            
16             sub ReadBytes {
17 2     2   5 my ($self, $count) = @_;
18 2         23 return $self->_readBytesForBitStream($count);
19             }
20            
21             sub ReadBits {
22 129     129   176 my ($self, $bitcount) = @_;
23 129         181 my $current = $self->{buffer};
24 129         181 my $moreBitsNeeded = $bitcount - length($current);
25 129 100       241 $moreBitsNeeded = 0 if $moreBitsNeeded < 0;
26 129 100       307 my $moreBytesNeeded = int($moreBitsNeeded / 8) + ($moreBitsNeeded % 8 ? 1 : 0);
27             #print "BitStream: $bitcount bits requested, $moreBytesNeeded bytes read\n";
28 129         364 my $string = $self->{ss}->ReadBytes($moreBytesNeeded);
29 129         276 $current .= unpack "B*", $string;
30 129         239 my $data = substr($current, 0, $bitcount, '');
31 129         199 $self->{buffer} = $current;
32 129         340 return $data;
33             }
34            
35             sub tell {
36 0     0   0 my $self = shift;
37             #die "A bit stream is not seekable";
38 0 0       0 if ($self->{buffer}) {
39 0         0 return "Bit ". (8 - length($self->{buffer}))
40             } else {
41 0         0 return "Bit 0";
42             }
43             }
44            
45             sub seek {
46 0     0   0 my ($self, $newpos) = @_;
47 0         0 die "A bit stream is not seekable";
48             }
49            
50 19     19   68 sub isBitStream { return 1 };
51            
52            
53             package Data::ParseBinary::Stream::BitWriter;
54             our @ISA = qw{Data::ParseBinary::Stream::Writer Data::ParseBinary::Stream::WrapperBase};
55            
56             __PACKAGE__->_registerStreamType("Bit");
57            
58             sub new {
59 31     31   56 my ($class, $byteStream) = @_;
60 31         135 my $self = bless { buffer => '' }, $class;
61 31         118 $self->_warping($byteStream);
62 31         119 return $self;
63             }
64            
65             sub WriteBytes {
66 2     2   6 my ($self, $data) = @_;
67 2         18 return $self->_writeBytesForBitStream($data);
68             }
69            
70             sub WriteBits {
71 166     166   264 my ($self, $bitdata) = @_;
72 166         228 my $current = $self->{buffer};
73 166         243 my $new_buffer = $current . $bitdata;
74 166         273 my $numof_bytesToWrite = int(length($new_buffer) / 8);
75 166         466 my $bytesToWrite = substr($new_buffer, 0, $numof_bytesToWrite * 8, '');
76 166         390 my $binaryToWrite = pack "B".($numof_bytesToWrite * 8), $bytesToWrite;
77 166         236 $self->{buffer} = $new_buffer;
78 166         481 return $self->{ss}->WriteBytes($binaryToWrite);
79             }
80            
81             sub Flush {
82 36     36   42 my $self = shift;
83 36         71 my $write_size = (-length($self->{buffer})) % 8;
84 36         105 $self->WriteBits('0'x$write_size);
85 36         122 return $self->{ss}->Flush();
86             }
87            
88             sub tell {
89 0     0   0 my $self = shift;
90 0         0 return "Bit ". length($self->{buffer});
91             #die "A bit stream is not seekable";
92             }
93            
94             sub seek {
95 0     0   0 my ($self, $newpos) = @_;
96 0         0 die "A bit stream is not seekable";
97             }
98            
99 24     24   79 sub isBitStream { return 1 };
100            
101             package Data::ParseBinary::Stream::ReversedBitStreamReader;
102             our @ISA = qw{Data::ParseBinary::Stream::BitReader};
103            
104             __PACKAGE__->_registerStreamType("ReversedBit");
105            
106             sub ReadBits {
107 6     6   8 my ($self, $bitcount) = @_;
108 6         10 my $current = $self->{buffer};
109 6         7 my $moreBitsNeeded = $bitcount - length($current);
110 6 100       14 if ($moreBitsNeeded > 0) {
111 4 50       27 my $moreBytesNeeded = int($moreBitsNeeded / 8) + ($moreBitsNeeded % 8 ? 1 : 0);
112 4         13 my $string = $self->{ss}->ReadBytes($moreBytesNeeded);
113 4 50       12 $string = join '', reverse split '', $string if $moreBytesNeeded > 1;
114 4         14 $current = unpack("B*", $string) . $current;
115             }
116 6         14 my $data = substr($current, -$bitcount, $bitcount, '');
117 6 100       18 $data = join '', reverse split '', $data if length($data) > 1;
118 6         14 $self->{buffer} = $current;
119 6         16 return $data;
120             }
121            
122             package Data::ParseBinary::Stream::ReversedBitStreamWriter;
123             our @ISA = qw{Data::ParseBinary::Stream::BitWriter};
124            
125             __PACKAGE__->_registerStreamType("ReversedBit");
126            
127             sub WriteBits {
128 8     8   11 my ($self, $bitdata) = @_;
129 8 100       30 $bitdata = join '', reverse split '', $bitdata if length($bitdata) > 1;
130 8         17 $self->{buffer} = $bitdata . $self->{buffer};
131 8         15 my $numof_bytesToWrite = int(length($self->{buffer}) / 8);
132 8         10 my $num_of_bits_to_cut = $numof_bytesToWrite * 8;
133 8         13 my $bytesToWrite = substr($self->{buffer}, -$num_of_bits_to_cut, $num_of_bits_to_cut, '');
134 8         18 my $binaryToWrite = pack "B".($numof_bytesToWrite * 8), $bytesToWrite;
135 8 50       14 $binaryToWrite = join '', reverse split '', $binaryToWrite if $numof_bytesToWrite > 1;
136 8         32 return $self->{ss}->WriteBytes($binaryToWrite);
137             }
138            
139             1;