File Coverage

blib/lib/Bit/Manip/PP.pm
Criterion Covered Total %
statement 77 79 97.4
branch 35 36 97.2
condition 6 6 100.0
subroutine 16 17 94.1
pod 9 9 100.0
total 143 147 97.2


line stmt bran cond sub pod time code
1             package Bit::Manip::PP;
2              
3 12     12   67749 use warnings;
  12         30  
  12         390  
4 12     12   69 use strict;
  12         25  
  12         443  
5              
6             our $VERSION = '1.07';
7              
8 12     12   71 use Exporter;
  12         27  
  12         13776  
9             our @ISA = qw(Exporter);
10              
11             our @EXPORT_OK = qw(
12             bit_get
13             bit_set
14             bit_clr
15             bit_toggle
16             bit_tog
17             bit_on
18             bit_off
19             bit_bin
20             bit_count
21             bit_mask
22             );
23              
24             our %EXPORT_TAGS;
25             $EXPORT_TAGS{all} = [@EXPORT_OK];
26              
27             sub _ref {
28 247 100   247   5162 shift if @_ == 2;
29 247 100 100     1433 if ($_[0] !~ /^\d+$/ && ref $_[0] ne 'SCALAR'){
30 3         17 die "your data must either be an integer or a SCALAR reference\n";
31             }
32              
33 244 100       533 if (ref $_[0]){
34 30 100       44 if (${ $_[0] } !~ /^\d+/){
  30         124  
35 1         7 die "data reference must contain only an integer\n";
36             }
37 29         80 return 1;
38             }
39 214         503 return 0;
40             }
41             sub bit_bin {
42 1024     1024 1 492153 my ($data) = @_;
43 1024         6005 return sprintf("%b", $data);
44             }
45             sub bit_count {
46 110     110 1 1043 my ($n, $set) = @_;
47              
48 110 100 100     791 if (! defined $n || $n !~ /^\d+/){
49 2         12 die "bit_count() requires an integer param\n";
50             }
51              
52 108         445 my $bits = sprintf("%b", $n);
53 108         184 my $bit_count;
54              
55 108 100       236 if ($set){
56 15         35 $bit_count = $bits =~ tr/1/1/;
57             }
58             else {
59 93         149 $bit_count = length($bits);
60             }
61              
62 108         334 return $bit_count;
63             }
64             sub bit_mask {
65 77     77 1 302 my ($bits, $lsb) = @_;
66 77         348 return (2 ** $bits - 1) << $lsb;
67             }
68             sub bit_get {
69 21     21 1 10899 my ($data, $msb, $lsb) = @_;
70              
71 21 100       50 $lsb = 0 if ! defined $lsb;
72              
73 21         53 _check_msb($msb);
74 20         26 $msb++; # need to start from 1 here
75              
76 20         46 _check_lsb($lsb, $msb);
77              
78 18         55 return ($data & (2**$msb-1)) >> $lsb;
79             }
80             sub bit_set {
81 63     63 1 27546 my ($data, $lsb, $bits, $value) = @_;
82              
83 63 100       188 if (@_ != 4){
84 2         17 die "bit_set() requires four params\n";
85             }
86              
87 61         165 _check_value($value);
88              
89 61         132 my $value_bits = bit_count($value, 0);
90 61 100       149 if ($value_bits != $bits){
91 14         26 $value_bits = $bits;
92             }
93 61         122 my $mask = bit_mask($value_bits, $lsb);
94              
95 61 100       135 if (_ref($data)){
96 2         9 $$data = ($$data & ~($mask)) | ($value << $lsb);
97 2         8 return 0;
98             }
99             else {
100 59         140 $data = ($data & ~($mask)) | ($value << $lsb);
101 59         311 return $data;
102             }
103             }
104             sub bit_clr {
105 26     26 1 11748 my ($data, $lsb, $nbits) = @_;
106 26         49 return bit_set($data, $lsb, $nbits, 0);
107             }
108              
109             *bit_tog = \&bit_toggle;
110              
111             sub bit_toggle {
112 104     104 1 56713 my ($data, $bit) = @_;
113              
114 104 50       223 if (_ref($data)){
115 0         0 $$data ^= 1 << $bit;
116 0         0 return 0;
117             }
118             else {
119 104         353 return $data ^= 1 << $bit;
120             }
121             }
122             sub bit_on {
123 40     40 1 16849 my ($data, $bit) = @_;
124              
125 40 100       75 if (_ref($data)){
126 16         30 $$data |= 1 << $bit;
127 16         26 return 0;
128             }
129             else {
130 24         61 return $data |= 1 << $bit;
131             }
132             }
133             sub bit_off {
134 32     32 1 15381 my ($data, $bit) = @_;
135              
136 32 100       64 if (_ref($data)){
137 8         16 $$data &= ~(1 << $bit);
138 8         15 return 0;
139             }
140             else {
141 24         79 return $data &= ~(1 << $bit);
142             }
143             }
144             sub _check_msb {
145 21     21   39 my ($msb) = @_;
146 21 100       51 if ($msb < 0){
147 1         7 die("\$msb param can not be negative\n");
148             }
149             }
150             sub _check_lsb {
151 20     20   36 my ($lsb, $msb) = @_;
152              
153 20 100       36 if ($lsb < 0){
154 1         4 die "\$lsb param can't be negative\n";
155             }
156 19 100       41 if (($lsb + 1) > $msb){
157 1         6 die "\$lsb param must be less than or equal to \$msb\n";
158             }
159             }
160             sub _check_value {
161 62 100   62   250 shift if @_ > 1;
162 62         118 my ($val) = @_;
163 62 100       146 if ($val < 0){
164 1         5 die "\$value param must be zero or greater\n";
165             }
166             }
167       0     sub _vim{};
168              
169             1;
170             __END__