0
|
1 package BitVector;
|
|
2 #
|
|
3 # $RCSfile: BitVector.pm,v $
|
|
4 # $Date: 2015/02/28 20:47:02 $
|
|
5 # $Revision: 1.32 $
|
|
6 #
|
|
7 # Author: Manish Sud <msud@san.rr.com>
|
|
8 #
|
|
9 # Copyright (C) 2015 Manish Sud. All rights reserved.
|
|
10 #
|
|
11 # This file is part of MayaChemTools.
|
|
12 #
|
|
13 # MayaChemTools is free software; you can redistribute it and/or modify it under
|
|
14 # the terms of the GNU Lesser General Public License as published by the Free
|
|
15 # Software Foundation; either version 3 of the License, or (at your option) any
|
|
16 # later version.
|
|
17 #
|
|
18 # MayaChemTools is distributed in the hope that it will be useful, but without
|
|
19 # any warranty; without even the implied warranty of merchantability of fitness
|
|
20 # for a particular purpose. See the GNU Lesser General Public License for more
|
|
21 # details.
|
|
22 #
|
|
23 # You should have received a copy of the GNU Lesser General Public License
|
|
24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
|
|
25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
|
|
26 # Boston, MA, 02111-1307, USA.
|
|
27 #
|
|
28
|
|
29 use strict;
|
|
30 use Carp;
|
|
31 use Exporter;
|
|
32 use Scalar::Util ();
|
|
33 use TextUtil ();
|
|
34 use ConversionsUtil ();
|
|
35 use MathUtil;
|
|
36
|
|
37 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
|
|
38
|
|
39 @ISA = qw(Exporter);
|
|
40 @EXPORT = qw(IsBitVector);
|
|
41 @EXPORT_OK = qw(NewFromBinaryString NewFromDecimalString NewFromHexadecimalString NewFromOctalString NewFromRawBinaryString);
|
|
42
|
|
43 %EXPORT_TAGS = (all => [@EXPORT, @EXPORT_OK]);
|
|
44
|
|
45 # Setup class variables...
|
|
46 my($ClassName, $ValueFormat, $ValueBitOrder);
|
|
47 _InitializeClass();
|
|
48
|
|
49 #
|
|
50 # Overload bitwise and some logical operators...
|
|
51 #
|
|
52 # 'fallback' is set to 'false' to raise exception for all other operators.
|
|
53 #
|
|
54 use overload '""' => 'StringifyBitVector',
|
|
55 '&' => '_BitVectorAndOperator',
|
|
56 '|' => '_BitVectorOrOperator',
|
|
57 '^' => '_BitVectorExclusiveOrOperator',
|
|
58
|
|
59 '~' => '_BitVectorNegationOperator',
|
|
60
|
|
61 '==' => '_BitVectorEqualOperator',
|
|
62 '!=' => '_BitVectorNotEqualOperator',
|
|
63
|
|
64 'fallback' => undef;
|
|
65
|
|
66 # Class constructor...
|
|
67 #
|
|
68 sub new {
|
|
69 my($Class, $Size) = @_;
|
|
70
|
|
71 # Initialize object...
|
|
72 my $This = {};
|
|
73 bless $This, ref($Class) || $Class;
|
|
74 $This->_InitializeBitVector($Size);
|
|
75
|
|
76 return $This;
|
|
77 }
|
|
78
|
|
79 # Initialize object data...
|
|
80 #
|
|
81 # Note:
|
|
82 # . Perl pack function used to initialize vector automatically sets its size to
|
|
83 # nearest power of 2 value.
|
|
84 #
|
|
85 sub _InitializeBitVector {
|
|
86 my($This, $Size) = @_;
|
|
87
|
|
88 if (!defined $Size) {
|
|
89 croak "Error: ${ClassName}->new: BitVector object instantiated without specifying its size ...";
|
|
90 }
|
|
91 if ($Size <=0) {
|
|
92 croak "Error: ${ClassName}->new: Bit vector size, $Size, must be a positive integer...";
|
|
93 }
|
|
94
|
|
95 # Initialize vector with zeros...
|
|
96 $This->{BitValues} = pack("b*", "0" x $Size);
|
|
97
|
|
98 # Size to automatically set to nearest power of 2 by Perl pack function. So use the length
|
|
99 # of packed vector to set size...
|
|
100 $This->{Size} = length($This->GetBitsAsBinaryString());
|
|
101
|
|
102 return $This;
|
|
103 }
|
|
104
|
|
105 # Initialize class ...
|
|
106 sub _InitializeClass {
|
|
107 #Class name...
|
|
108 $ClassName = __PACKAGE__;
|
|
109
|
|
110 # Print format for bit vectore values...
|
|
111 $ValueFormat = "Binary";
|
|
112
|
|
113 # Bit ordering for printing bit vector value strings. Default is to print lowest bit of each
|
|
114 # byte on the left.
|
|
115 #
|
|
116 # Internally, bits are stored in ascending order using Perl vec function. Regardless
|
|
117 # of machine order, big-endian or little-endian, vec function always considers first
|
|
118 # string byte as the lowest byte and first bit within each byte as the lowest bit.
|
|
119 #
|
|
120 # Possible values: Ascending or Descending
|
|
121 #
|
|
122 $ValueBitOrder = 'Ascending';
|
|
123 }
|
|
124
|
|
125 # Create a new bit vector using binary string. This functionality can be
|
|
126 # either invoked as a class function or an object method.
|
|
127 #
|
|
128 # The size of bit vector is automatically set to reflect the string.
|
|
129 #
|
|
130 sub NewFromBinaryString ($;$) {
|
|
131 my($FirstParameter, $SecondParameter, $ThirdParameter) = @_;
|
|
132
|
|
133 if (_IsBitVector($FirstParameter)) {
|
|
134 return _NewBitVectorFromString('Binary', $SecondParameter, $ThirdParameter);
|
|
135 }
|
|
136 else {
|
|
137 return _NewBitVectorFromString( 'Binary', $FirstParameter, $SecondParameter);
|
|
138 }
|
|
139 }
|
|
140
|
|
141 # Create a new bit vector using hexadecimal string. This functionality can be
|
|
142 # either invoked as a class function or an object method.
|
|
143 #
|
|
144 # The size of bit vector is automatically set to reflect the string.
|
|
145 #
|
|
146 sub NewFromHexadecimalString ($;$) {
|
|
147 my($FirstParameter, $SecondParameter, $ThirdParameter) = @_;
|
|
148
|
|
149 if (_IsBitVector($FirstParameter)) {
|
|
150 return _NewBitVectorFromString('Hexadecimal', $SecondParameter, $ThirdParameter);
|
|
151 }
|
|
152 else {
|
|
153 return _NewBitVectorFromString( 'Hexadecimal', $FirstParameter, $SecondParameter);
|
|
154 }
|
|
155 }
|
|
156
|
|
157 # Create a new bit vector using octal string. This functionality can be
|
|
158 # either invoked as a class function or an object method.
|
|
159 #
|
|
160 # The size of bit vector is automatically set to reflect the string.
|
|
161 #
|
|
162 sub NewFromOctalString ($;$) {
|
|
163 my($FirstParameter, $SecondParameter, $ThirdParameter) = @_;
|
|
164
|
|
165 if (_IsBitVector($FirstParameter)) {
|
|
166 return _NewBitVectorFromString('Octal', $SecondParameter, $ThirdParameter);
|
|
167 }
|
|
168 else {
|
|
169 return _NewBitVectorFromString( 'Octal', $FirstParameter, $SecondParameter);
|
|
170 }
|
|
171 }
|
|
172
|
|
173 # Create a new bit vector using decimal string. This functionality can be
|
|
174 # either invoked as a class function or an object method.
|
|
175 #
|
|
176 # The size of bit vector is automatically set to reflect the string.
|
|
177 #
|
|
178 sub NewFromDecimalString ($;$) {
|
|
179 my($FirstParameter, $SecondParameter, $ThirdParameter) = @_;
|
|
180
|
|
181 if (_IsBitVector($FirstParameter)) {
|
|
182 return _NewBitVectorFromString('Decimal', $SecondParameter, $ThirdParameter);
|
|
183 }
|
|
184 else {
|
|
185 return _NewBitVectorFromString( 'Decimal', $FirstParameter, $SecondParameter);
|
|
186 }
|
|
187 }
|
|
188
|
|
189 # Create a new bit vector using raw binary string. This functionality can be
|
|
190 # either invoked as a class function or an object method.
|
|
191 #
|
|
192 # The size of bit vector is automatically set to reflect the string.
|
|
193 #
|
|
194 sub NewFromRawBinaryString ($;$) {
|
|
195 my($FirstParameter, $SecondParameter, $ThirdParameter) = @_;
|
|
196
|
|
197 if (_IsBitVector($FirstParameter)) {
|
|
198 return _NewBitVectorFromString('RawBinary', $SecondParameter, $ThirdParameter);
|
|
199 }
|
|
200 else {
|
|
201 return _NewBitVectorFromString( 'RawBinary', $FirstParameter, $SecondParameter);
|
|
202 }
|
|
203 }
|
|
204
|
|
205 # Create a new bit vector from a string...
|
|
206 #
|
|
207 sub _NewBitVectorFromString ($$;$) {
|
|
208 my($Format, $String, $BitOrder) = @_;
|
|
209 my($Size, $BitVector);
|
|
210
|
|
211 $Size = _CalculateStringSizeInBits($Format, $String);
|
|
212
|
|
213 $BitVector = new BitVector($Size);
|
|
214 $BitVector->_SetBitsAsString($Format, $String, $BitOrder);
|
|
215
|
|
216 return $BitVector;
|
|
217 }
|
|
218
|
|
219 # Copy bit vector...
|
|
220 sub Copy {
|
|
221 my($This) = @_;
|
|
222 my($BitVector);
|
|
223
|
|
224 # Make a new bit vector...
|
|
225 $BitVector = (ref $This)->new($This->{Size});
|
|
226
|
|
227 # Copy bit values...
|
|
228 $BitVector->{BitValues} = $This->{BitValues};
|
|
229
|
|
230 # Copy value format for stringification...
|
|
231 if (exists $This->{ValueFormat}) {
|
|
232 $BitVector->{ValueFormat} = $This->{ValueFormat};
|
|
233 }
|
|
234 # Copy value bit order for stringification...
|
|
235 if (exists $This->{ValueBitOrder}) {
|
|
236 $BitVector->{ValueBitOrder} = $This->{ValueBitOrder};
|
|
237 }
|
|
238 return $BitVector;
|
|
239 }
|
|
240
|
|
241 # Reverse bit values in bit vector...
|
|
242 sub Reverse {
|
|
243 my($This) = @_;
|
|
244 my($BitNum, $ReverseBitNum, $BitValue, $ReverseBitValue);
|
|
245
|
|
246 $BitNum = 0; $ReverseBitNum = $This->{Size} - 1;
|
|
247
|
|
248 while ($BitNum < $ReverseBitNum) {
|
|
249 $BitValue = $This->_GetBitValue($BitNum);
|
|
250 $ReverseBitValue = $This->_GetBitValue($ReverseBitNum);
|
|
251
|
|
252 $This->_SetBitValue($BitNum, $ReverseBitValue);
|
|
253 $This->_SetBitValue($ReverseBitNum, $BitValue);
|
|
254
|
|
255 $BitNum++; $ReverseBitNum--;
|
|
256 }
|
|
257 return $This;
|
|
258 }
|
|
259
|
|
260 # Is it a bit vector object?
|
|
261 sub IsBitVector ($) {
|
|
262 my($Object) = @_;
|
|
263
|
|
264 return _IsBitVector($Object);
|
|
265 }
|
|
266
|
|
267 # Get size...
|
|
268 sub GetSize {
|
|
269 my($This) = @_;
|
|
270
|
|
271 return $This->{Size};
|
|
272 }
|
|
273
|
|
274 # Set a bit...
|
|
275 #
|
|
276 sub SetBit {
|
|
277 my($This, $BitNum, $SkipCheck) = @_;
|
|
278
|
|
279 # Just set it...
|
|
280 if ($SkipCheck) {
|
|
281 return $This->_SetBitValue($BitNum, 1);
|
|
282 }
|
|
283
|
|
284 # Check and set...
|
|
285 $This->_ValidateBitNumber("SetBit", $BitNum);
|
|
286
|
|
287 return $This->_SetBitValue($BitNum, 1);
|
|
288 }
|
|
289
|
|
290 # Set arbitrary bits specified as a list of bit numbers...
|
|
291 #
|
|
292 sub SetBits {
|
|
293 my($This, @BitNums) = @_;
|
|
294 my($BitNum);
|
|
295
|
|
296 for $BitNum (@BitNums) {
|
|
297 $This->SetBit($BitNum);
|
|
298 }
|
|
299 return $This;
|
|
300 }
|
|
301
|
|
302 # Set bits in a specified range...
|
|
303 #
|
|
304 sub SetBitsRange {
|
|
305 my($This, $MinBitNum, $MaxBitNum) = @_;
|
|
306 my($BitNum);
|
|
307
|
|
308 $This->_ValidateBitNumber("SetBitsRange", $MinBitNum);
|
|
309 $This->_ValidateBitNumber("SetBitsRange", $MaxBitNum);
|
|
310
|
|
311 for $BitNum ($MinBitNum .. $MaxBitNum) {
|
|
312 $This->_SetBitValue($BitNum, 1);
|
|
313 }
|
|
314 return $This;
|
|
315 }
|
|
316
|
|
317 # Set all bits...
|
|
318 #
|
|
319 sub SetAllBits {
|
|
320 my($This) = @_;
|
|
321
|
|
322 $This->{BitValues} = pack("b*", "1" x $This->{Size});
|
|
323 }
|
|
324
|
|
325 # Clear a bit...
|
|
326 #
|
|
327 sub ClearBit {
|
|
328 my($This, $BitNum) = @_;
|
|
329
|
|
330 $This->_ValidateBitNumber("ClearBit", $BitNum);
|
|
331
|
|
332 return $This->_SetBitValue($BitNum, 0);
|
|
333 }
|
|
334
|
|
335 # Clear arbitrary bits specified as a list of bit numbers...
|
|
336 #
|
|
337 sub ClearBits {
|
|
338 my($This, @BitNums) = @_;
|
|
339 my($BitNum);
|
|
340
|
|
341 for $BitNum (@BitNums) {
|
|
342 $This->ClearBit($BitNum);
|
|
343 }
|
|
344 return $This;
|
|
345 }
|
|
346
|
|
347 # Clear bits in a specified range...
|
|
348 #
|
|
349 sub ClearBitsRange {
|
|
350 my($This, $MinBitNum, $MaxBitNum) = @_;
|
|
351 my($BitNum);
|
|
352
|
|
353 $This->_ValidateBitNumber("ClearBitsRange", $MinBitNum);
|
|
354 $This->_ValidateBitNumber("ClearBitsRange", $MaxBitNum);
|
|
355
|
|
356 for $BitNum ($MinBitNum .. $MaxBitNum) {
|
|
357 $This->_SetBitValue($BitNum, 0);
|
|
358 }
|
|
359 return $This;
|
|
360 }
|
|
361
|
|
362 # Clear all bits...
|
|
363 #
|
|
364 sub ClearAllBits {
|
|
365 my($This) = @_;
|
|
366
|
|
367 $This->{BitValues} = pack("b*", "0" x $This->{Size});
|
|
368
|
|
369 return $This;
|
|
370 }
|
|
371
|
|
372 # Set or clear bit...
|
|
373 #
|
|
374 sub SetBitValue {
|
|
375 my($This, $BitNum, $BitValue) = @_;
|
|
376
|
|
377 BITVALUE: {
|
|
378 if ($BitValue == 1) { return $This->SetBit($BitNum); last BITVALUE; }
|
|
379 if ($BitValue == 0) { return $This->ClearBit($BitNum); last BITVALUE; }
|
|
380 croak "Error: ${ClassName}->SetBit: Specified bit value, $BitValue, must be 0 or 1...";
|
|
381 }
|
|
382 return $This;
|
|
383 }
|
|
384
|
|
385 # Flip bit value...
|
|
386 #
|
|
387 sub FlipBit {
|
|
388 my($This, $BitNum) = @_;
|
|
389
|
|
390 $This->_ValidateBitNumber("FlipBit", $BitNum);
|
|
391 return $This->_FlipBit($BitNum);
|
|
392 }
|
|
393
|
|
394 # Flip arbitrary bits specified as a list of bit numbers...
|
|
395 #
|
|
396 sub FlipBits {
|
|
397 my($This, @BitNums) = @_;
|
|
398 my($BitNum);
|
|
399
|
|
400 for $BitNum (@BitNums) {
|
|
401 $This->FlipBit();
|
|
402 }
|
|
403 return $This;
|
|
404 }
|
|
405
|
|
406 # Flip bit value in a specified bit range...
|
|
407 #
|
|
408 sub FlipBitsRange {
|
|
409 my($This, $MinBitNum, $MaxBitNum) = @_;
|
|
410 my($BitNum);
|
|
411
|
|
412 $This->_ValidateBitNumber("FlipBitsRange", $MinBitNum);
|
|
413 $This->_ValidateBitNumber("FlipBitsRange", $MaxBitNum);
|
|
414
|
|
415 for $BitNum ($MinBitNum .. $MaxBitNum) {
|
|
416 $This->_FlipBit();
|
|
417 }
|
|
418 return $This;
|
|
419 }
|
|
420
|
|
421 # Flip all bit valus...
|
|
422 #
|
|
423 sub FlipAllBits {
|
|
424 my($This) = @_;
|
|
425
|
|
426 return $This->FlipBits(0, ($This->{Size} - 1));
|
|
427 }
|
|
428
|
|
429 # Flip bit value...
|
|
430 sub _FlipBit {
|
|
431 my($This, $BitNum) = @_;
|
|
432
|
|
433 if ($This->_GetBitValue($BitNum)) {
|
|
434 return $This->_SetBitValue($BitNum, 0);
|
|
435 }
|
|
436 else {
|
|
437 return $This->_SetBitValue($BitNum, 1);
|
|
438 }
|
|
439 }
|
|
440
|
|
441 # Get bit value...
|
|
442 #
|
|
443 sub GetBit {
|
|
444 my($This, $BitNum) = @_;
|
|
445
|
|
446 $This->_ValidateBitNumber("GetBit", $BitNum);
|
|
447
|
|
448 return $This->_GetBitValue($BitNum);
|
|
449 }
|
|
450
|
|
451 # Is a specific bit set?
|
|
452 #
|
|
453 sub IsBitSet {
|
|
454 my($This, $BitNum) = @_;
|
|
455
|
|
456 if (!(defined($BitNum) && ($BitNum >= 0) && ($BitNum < $This->{Size}))) {
|
|
457 return undef;
|
|
458 }
|
|
459
|
|
460 return $This->_GetBitValue($BitNum) ? 1 : 0;
|
|
461 }
|
|
462
|
|
463 # Is a specific bit clear?
|
|
464 #
|
|
465 sub IsBitClear {
|
|
466 my($This, $BitNum) = @_;
|
|
467
|
|
468 if (!(defined($BitNum) && ($BitNum >= 0) && ($BitNum < $This->{Size}))) {
|
|
469 return undef;
|
|
470 }
|
|
471
|
|
472 return $This->_GetBitValue($BitNum) ? 0 : 1;
|
|
473 }
|
|
474
|
|
475 # Get number of set bits...
|
|
476 #
|
|
477 sub GetNumOfSetBits {
|
|
478 my($This) = @_;
|
|
479
|
|
480 return unpack("%b*", $This->{BitValues});
|
|
481 }
|
|
482
|
|
483 # Get number of clear bits...
|
|
484 #
|
|
485 sub GetNumOfClearBits {
|
|
486 my($This) = @_;
|
|
487
|
|
488 return ($This->{Size} - $This->GetNumOfSetBits());
|
|
489 }
|
|
490
|
|
491 # Get density of set bits...
|
|
492 #
|
|
493 sub GetDensityOfSetBits {
|
|
494 my($This) = @_;
|
|
495
|
|
496 return $This->{Size} ? ($This->GetNumOfSetBits()/$This->{Size}) : 0;
|
|
497 }
|
|
498
|
|
499 # Get density of clear bits...
|
|
500 #
|
|
501 sub GetDensityOfClearBits {
|
|
502 my($This) = @_;
|
|
503
|
|
504 return $This->GetNumOfClearBits()/$This->{Size};
|
|
505 }
|
|
506
|
|
507 # Convert internal bit values stored using Perl vec function with first string byte
|
|
508 # as the lowest byte and first bit within each byte as the lowest bit into a binary
|
|
509 # string with ascending or descending bit order within each byte. The internal
|
|
510 # bit order corresponds to ascending bit order within each byte.
|
|
511 #
|
|
512 sub GetBitsAsBinaryString {
|
|
513 my($This, $BitOrder) = @_;
|
|
514
|
|
515 return $This->_GetBitsAsString('Binary', $BitOrder);
|
|
516 }
|
|
517
|
|
518 # Convert internal bit values stored using Perl vec function with first string byte
|
|
519 # as the lowest byte and first bit within each byte as the lowest bit into a hexadecimal
|
|
520 # string with ascending or descending bit order within each byte. The internal
|
|
521 # bit order corresponds to ascending bit order within each byte.
|
|
522 #
|
|
523 #
|
|
524 sub GetBitsAsHexadecimalString {
|
|
525 my($This, $BitOrder) = @_;
|
|
526
|
|
527 return $This->_GetBitsAsString('Hexadecimal', $BitOrder);
|
|
528 }
|
|
529
|
|
530 # Convert bit values into a octal string value...
|
|
531 #
|
|
532 sub GetBitsAsOctalString {
|
|
533 my($This, $BitOrder) = @_;
|
|
534
|
|
535 return $This->_GetBitsAsString('Octal', $BitOrder);
|
|
536 }
|
|
537
|
|
538 # Convert bit values into a decimal string value...
|
|
539 #
|
|
540 sub GetBitsAsDecimalString {
|
|
541 my($This, $BitOrder) = @_;
|
|
542
|
|
543 return $This->_GetBitsAsString('Decimal', $BitOrder);
|
|
544 }
|
|
545
|
|
546 # Return packed bit values which also contains nonprintable characters...
|
|
547 #
|
|
548 sub GetBitsAsRawBinaryString {
|
|
549 my($This) = @_;
|
|
550
|
|
551 return $This->_GetBitsAsString('RawBinary');
|
|
552 }
|
|
553
|
|
554 # Convert internal bit values stored using Perl vec function with first string byte
|
|
555 # as the lowest byte and first bit within each byte as the lowest bit into a
|
|
556 # string with ascending or descending bit order within each byte. The internal
|
|
557 # bit order corresponds to ascending bit order within each byte.
|
|
558 #
|
|
559 #
|
|
560 sub _GetBitsAsString {
|
|
561 my($This, $Format, $BitOrder) = @_;
|
|
562 my($BinaryTemplate, $HexadecimalTemplate);
|
|
563
|
|
564 ($BinaryTemplate, $HexadecimalTemplate) = $This->_SetupBitsPackUnpackTemplate($BitOrder);
|
|
565
|
|
566 FORMAT : {
|
|
567 if ($Format =~ /^(Hexadecimal|Hex|HexadecimalString)$/i) { return unpack($HexadecimalTemplate, $This->{BitValues}); last FORMAT; }
|
|
568 if ($Format =~ /^(Octal|Oct|OctalString)$/i) { return ConversionsUtil::HexadecimalToOctal(unpack($HexadecimalTemplate, $This->{BitValues})); last FORMAT; }
|
|
569 if ($Format =~ /^(Decimal|Dec|DecimalString)$/i) { return ConversionsUtil::HexadecimalToDecimal(unpack($HexadecimalTemplate, $This->{BitValues})); last FORMAT; }
|
|
570 if ($Format =~ /^(Binary|Bin|BinaryString)$/i) { return unpack($BinaryTemplate, $This->{BitValues}); last FORMAT; }
|
|
571 if ($Format =~ /^(RawBinary|RawBin|RawBinaryString)$/i) { return $This->{BitValues}; last FORMAT; }
|
|
572 croak "Error: ${ClassName}->_GetBitsAsString: Specified bit vector string format, $Format, is not supported. Value values: Binary, Bin, BinaryString, Hexdecimal, Hex, HexadecimalString, Decimal, Dec, DecimalString, Octal, Oct, OctalString, RawBinary, RawBin, RawBinaryString...";
|
|
573 }
|
|
574 }
|
|
575
|
|
576 # Setup templates to unpack bits...
|
|
577 #
|
|
578 sub _SetupBitsPackUnpackTemplate {
|
|
579 my($This, $BitOrder) = @_;
|
|
580 my($BinaryTemplate, $HexadecimalTemplate);
|
|
581
|
|
582 $BitOrder = (defined($BitOrder) && $BitOrder) ? $BitOrder : 'Ascending';
|
|
583
|
|
584 if ($BitOrder =~ /^Ascending$/i) {
|
|
585 $BinaryTemplate = "b*";
|
|
586 $HexadecimalTemplate = "h*";
|
|
587 }
|
|
588 elsif ($BitOrder =~ /^Descending$/i) {
|
|
589 $BinaryTemplate = "B*";
|
|
590 $HexadecimalTemplate = "H*";
|
|
591 }
|
|
592 else {
|
|
593 croak "Warning: ${ClassName}::_SetupBitsPackUnpackTemplate: Specified bit order value, $BitOrder, is not supported. Supported values: Ascending, Descending...";
|
|
594 }
|
|
595 return ($BinaryTemplate, $HexadecimalTemplate);
|
|
596 }
|
|
597
|
|
598 # Set bit values using hexadecimal string. The initial size of bit vector is not changed.
|
|
599 #
|
|
600 sub SetBitsAsHexadecimalString {
|
|
601 my($This, $Hexadecimal, $BitOrder) = @_;
|
|
602
|
|
603 if ($Hexadecimal =~ /^0x/i) {
|
|
604 $Hexadecimal =~ s/^0x//i;
|
|
605 }
|
|
606 return $This->_SetBitsAsString('Hexadecimal', $Hexadecimal, $BitOrder);
|
|
607 }
|
|
608
|
|
609 # Set bit values using octal string. The initial size of bit vector is not changed.
|
|
610 #
|
|
611 sub SetBitsAsOctalString {
|
|
612 my($This, $Octal, $BitOrder) = @_;
|
|
613
|
|
614 if ($Octal =~ /^0/i) {
|
|
615 $Octal =~ s/^0//i;
|
|
616 }
|
|
617 return $This->_SetBitsAsString('Octal', $Octal, $BitOrder);
|
|
618 }
|
|
619
|
|
620 # Set bit values using a decimal number. The initial size of bit vector is not changed.
|
|
621 #
|
|
622 sub SetBitsAsDecimalString {
|
|
623 my($This, $Decimal, $BitOrder) = @_;
|
|
624
|
|
625 if (!TextUtil::IsPositiveInteger($Decimal)) {
|
|
626 croak "Error: ${ClassName}->SetBitsAsDecimalString: Specified decimal value, $Decimal, must be a positive integer...";
|
|
627 }
|
|
628 if ($Decimal =~ /[+]/) {
|
|
629 $Decimal =~ s/[+]//;
|
|
630 }
|
|
631 return $This->_SetBitsAsString('Decimal', $Decimal, $BitOrder);
|
|
632 }
|
|
633
|
|
634 # Set bit values using hexadecimal string. The initial size of bit vector is not changed.
|
|
635 #
|
|
636 sub SetBitsAsBinaryString {
|
|
637 my($This, $Binary, $BitOrder) = @_;
|
|
638
|
|
639 if ($Binary =~ /^0b/i) {
|
|
640 $Binary =~ s/^0b//i;
|
|
641 }
|
|
642 return $This->_SetBitsAsString('Binary', $Binary, $BitOrder);
|
|
643 }
|
|
644
|
|
645 # Set bit values using packed binary string. The size of bit vector is changed to reflect
|
|
646 # the input raw string...
|
|
647 #
|
|
648 sub SetBitsAsRawBinaryString {
|
|
649 my($This, $RawBinary) = @_;
|
|
650
|
|
651 return $This->_SetBitsAsString('RawBinary', $RawBinary);
|
|
652 }
|
|
653
|
|
654 # Set bits using string in a specified format. This size of bit vector is not changed except for
|
|
655 # RawBinary string type...
|
|
656 #
|
|
657 sub _SetBitsAsString {
|
|
658 my($This, $Format, $String, $BitOrder) = @_;
|
|
659 my($Size, $BinaryTemplate, $HexadecimalTemplate);
|
|
660
|
|
661 ($BinaryTemplate, $HexadecimalTemplate) = $This->_SetupBitsPackUnpackTemplate($BitOrder);
|
|
662
|
|
663 $Size = $This->{Size};
|
|
664 FORMAT : {
|
|
665 if ($Format =~ /^(Hexadecimal|Hex|HexadecimalString)$/i) { $This->{BitValues} = pack($HexadecimalTemplate, $String); last FORMAT; }
|
|
666 if ($Format =~ /^(Octal|Oct|OctalString)$/i) { vec($This->{BitValues}, 0, $Size) = ConversionsUtil::OctalToDecimal($String); last FORMAT; }
|
|
667 if ($Format =~ /^(Decimal|Dec|DecimalString)$/i) { vec($This->{BitValues}, 0, $Size) = $String; last FORMAT; }
|
|
668 if ($Format =~ /^(Binary|Bin|BinaryString)$/i) { $This->{BitValues} = pack($BinaryTemplate, $String); last FORMAT; }
|
|
669 if ($Format =~ /^(RawBinary|RawBin|RawBinaryString)$/i) { $This->{BitValues} = $String; last FORMAT; }
|
|
670 croak "Error: ${ClassName}->_SetBitsAsString: Specified bit vector string format, $Format, is not supported. Value values: Binary, Bin, BinaryString, Hexdecimal, Hex, HexadecimalString, Decimal, Dec, DecimalString, Octal, Oct, OctalString, RawBinary, RawBin, RawBinaryString...";
|
|
671 }
|
|
672
|
|
673 # Set size using packed string...
|
|
674 $Size = length($This->GetBitsAsBinaryString());
|
|
675 if ($Size <=0) {
|
|
676 croak "Error: ${ClassName}->_SetBitsAsString: Bit vector size, $Size, must be a positive integer...";
|
|
677 }
|
|
678 $This->{Size} = $Size;
|
|
679
|
|
680 return $This;
|
|
681 }
|
|
682
|
|
683 # Calculate string size in bits...
|
|
684 #
|
|
685 sub _CalculateStringSizeInBits ($$;$) {
|
|
686 my($FirstParameter, $SecondParameter, $ThisParameter) = @_;
|
|
687 my($This, $Format, $String, $Size);
|
|
688
|
|
689 if ((@_ == 3) && (_IsBitVector($FirstParameter))) {
|
|
690 ($This, $Format, $String) = ($FirstParameter, $SecondParameter, $ThisParameter);
|
|
691 }
|
|
692 else {
|
|
693 ($This, $Format, $String) = (undef, $FirstParameter, $SecondParameter);
|
|
694 }
|
|
695
|
|
696 FORMAT : {
|
|
697 if ($Format =~ /^(Hexadecimal|Hex|HexadecimalString)$/i) { $Size = length($String) * 4; last FORMAT; }
|
|
698 if ($Format =~ /^(Octal|Oct|OctalString)$/i) { $Size = length($String) * 3; last FORMAT; }
|
|
699 if ($Format =~ /^(Decimal|Dec|DecimalString)$/i) { $Size = length(ConversionsUtil::DecimalToHexadecimal($String)) * 4; last FORMAT; }
|
|
700 if ($Format =~ /^(Binary|Bin|BinaryString)$/i) { $Size = length($String); last FORMAT; }
|
|
701 if ($Format =~ /^(RawBinary|RawBin|RawBinaryString)$/i) { $Size = length(unpack("B*", $String)); last FORMAT; }
|
|
702 croak "Error: ${ClassName}::_CalculateStringSizeInBits: Specified bit vector string format, $Format, is not supported. Value values: Binary, Bin, BinaryString, Hexdecimal, Hex, HexadecimalString, Decimal, Dec, DecimalString, Octal, Oct, OctalString, RawBinary, RawBin, RawBinaryString...";
|
|
703 }
|
|
704 return $Size;
|
|
705 }
|
|
706
|
|
707 # Set bit value using Perl vec function with bit numbers going from left to right.
|
|
708 # First bit number corresponds to 0.
|
|
709 #
|
|
710 sub _SetBitValue {
|
|
711 my($This, $BitNum, $BitValue) = @_;
|
|
712 my($Offset, $Width);
|
|
713
|
|
714 $Offset = $BitNum;
|
|
715 $Width = 1;
|
|
716
|
|
717 vec($This->{BitValues}, $Offset, $Width) = $BitValue;
|
|
718
|
|
719 return $This;
|
|
720 }
|
|
721
|
|
722 # Get bit value Perl vec function with bit numbers going from left to right.
|
|
723 # First bit number corresponds to 0.
|
|
724 #
|
|
725 sub _GetBitValue {
|
|
726 my($This, $BitNum) = @_;
|
|
727 my($Offset, $Width, $BitValue);
|
|
728
|
|
729 $Offset = $BitNum;
|
|
730 $Width = 1;
|
|
731
|
|
732 $BitValue = vec($This->{BitValues}, $Offset, $Width);
|
|
733
|
|
734 return $BitValue;
|
|
735 }
|
|
736
|
|
737 # Check to make sure it's a valid bit number...
|
|
738 #
|
|
739 sub _ValidateBitNumber {
|
|
740 my($This, $CallerName, $BitNum) = @_;
|
|
741
|
|
742 if (!defined $BitNum) {
|
|
743 croak "Error: ${ClassName}->${CallerName}: Bit number is not defined...";
|
|
744 }
|
|
745 if ($BitNum < 0) {
|
|
746 croak "Error: ${ClassName}->${CallerName}: Bit number value, $BitNum, must be >= 0 ...";
|
|
747 }
|
|
748 if ($BitNum >= $This->{Size}) {
|
|
749 croak "Error: ${ClassName}->${CallerName}: Bit number number value, $BitNum, must be less than the size of bit vector, ", $This->{Size}, "...";
|
|
750 }
|
|
751
|
|
752 return $This;
|
|
753 }
|
|
754
|
|
755 # Set bit values print format for an individual object or the whole class...
|
|
756 #
|
|
757 sub SetBitValuePrintFormat ($;$) {
|
|
758 my($FirstParameter, $SecondParameter) = @_;
|
|
759
|
|
760 if ((@_ == 2) && (_IsBitVector($FirstParameter))) {
|
|
761 # Set bit values print format for the specific object...
|
|
762 my($This, $ValuePrintFormat) = ($FirstParameter, $SecondParameter);
|
|
763
|
|
764 if (!_ValidateBitValuePrintFormat($ValuePrintFormat)) {
|
|
765 return;
|
|
766 }
|
|
767
|
|
768 $This->{ValueFormat} = $ValuePrintFormat;
|
|
769 }
|
|
770 else {
|
|
771 # Set value print format for the class...
|
|
772 my($ValuePrintFormat) = ($FirstParameter);
|
|
773
|
|
774 if (!_ValidateBitValuePrintFormat($ValuePrintFormat)) {
|
|
775 return;
|
|
776 }
|
|
777
|
|
778 $ValueFormat = $ValuePrintFormat;
|
|
779 }
|
|
780 }
|
|
781
|
|
782 # Set bit values bit order for an individual object or the whole class...
|
|
783 #
|
|
784 sub SetBitValueBitOrder ($;$) {
|
|
785 my($FirstParameter, $SecondParameter) = @_;
|
|
786
|
|
787 if ((@_ == 2) && (_IsBitVector($FirstParameter))) {
|
|
788 # Set bit value bit order for the specific object...
|
|
789 my($This, $BitOrder) = ($FirstParameter, $SecondParameter);
|
|
790
|
|
791 if (!_ValidateBitValueBitOrder($BitOrder)) {
|
|
792 return;
|
|
793 }
|
|
794
|
|
795 $This->{ValueBitOrder} = $BitOrder;
|
|
796 }
|
|
797 else {
|
|
798 # Set bit value bit order for the class...
|
|
799 my($BitOrder) = ($FirstParameter);
|
|
800
|
|
801 if (!_ValidateBitValueBitOrder($BitOrder)) {
|
|
802 return;
|
|
803 }
|
|
804
|
|
805 $ValueBitOrder = $BitOrder;
|
|
806 }
|
|
807 }
|
|
808
|
|
809 # Validate print format for bit values...
|
|
810 sub _ValidateBitValueBitOrder {
|
|
811 my($BitOrder) = @_;
|
|
812
|
|
813 if ($BitOrder !~ /^(Ascending|Descending)$/i) {
|
|
814 carp "Warning: ${ClassName}::_ValidateBitValueBitOrder: Specified bit order value, $BitOrder, is not supported. Supported values: Ascending, Descending...";
|
|
815 return 0;
|
|
816 }
|
|
817 return 1;
|
|
818 }
|
|
819
|
|
820 # Validate print format for bit values...
|
|
821 sub _ValidateBitValuePrintFormat {
|
|
822 my($ValuePrintFormat) = @_;
|
|
823
|
|
824 if ($ValuePrintFormat !~ /^(Binary|Bin||BinaryString|Hexadecimal|Hex||HexadecimalString|Decimal|Dec||DecimalString|Octal|Oct||OctalString|RawBinary|RawBin|RawBinaryString)$/i) {
|
|
825 carp "Warning: ${ClassName}::_ValidateBitValuePrintFormat: Specified bit vector print format value, $ValuePrintFormat, is not supported. Supported values: Binary, Bin, BinaryString, Hexdecimal, Hex, HexadecimalString, Decimal, Dec, DecimalString, Octal, Oct, OctalString, RawBinary, RawBin, RawBinaryString...";
|
|
826 return 0;
|
|
827 }
|
|
828 return 1;
|
|
829 }
|
|
830
|
|
831 # Bitwise AND operation for BitVectors...
|
|
832 #
|
|
833 sub _BitVectorAndOperator {
|
|
834 my($This, $Other, $OrderFlipped, $OtherIsBitVector, $ErrorMsg, $CheckBitVectorSizes);
|
|
835
|
|
836 $ErrorMsg = "_BitVectorAndOperator: Bitwise AND oparation failed";
|
|
837 $CheckBitVectorSizes = 1;
|
|
838 ($This, $Other, $OrderFlipped, $OtherIsBitVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckBitVectorSizes);
|
|
839
|
|
840 if (!$OtherIsBitVector) {
|
|
841 if ($OrderFlipped) {
|
|
842 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a bit vector...";
|
|
843 }
|
|
844 }
|
|
845 my($BitVector);
|
|
846 $BitVector = (ref $This)->new($This->{Size});
|
|
847 $BitVector->{BitValues} = $This->{BitValues} & $Other->{BitValues};
|
|
848
|
|
849 return $BitVector;
|
|
850 }
|
|
851
|
|
852 # Bitwise OR operation for BitVectors...
|
|
853 #
|
|
854 sub _BitVectorOrOperator {
|
|
855 my($This, $Other, $OrderFlipped, $OtherIsBitVector, $ErrorMsg, $CheckBitVectorSizes);
|
|
856
|
|
857 $ErrorMsg = "_BitVectorAndOperator: Bitwise OR oparation failed";
|
|
858 $CheckBitVectorSizes = 1;
|
|
859 ($This, $Other, $OrderFlipped, $OtherIsBitVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckBitVectorSizes);
|
|
860
|
|
861 if (!$OtherIsBitVector) {
|
|
862 if ($OrderFlipped) {
|
|
863 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a bit vector...";
|
|
864 }
|
|
865 }
|
|
866 my($BitVector);
|
|
867 $BitVector = (ref $This)->new($This->{Size});
|
|
868 $BitVector->{BitValues} = $This->{BitValues} | $Other->{BitValues};
|
|
869
|
|
870 return $BitVector;
|
|
871 }
|
|
872
|
|
873 # Bitwise XOR operation for BitVectors...
|
|
874 #
|
|
875 sub _BitVectorExclusiveOrOperator {
|
|
876 my($This, $Other, $OrderFlipped, $OtherIsBitVector, $ErrorMsg, $CheckBitVectorSizes);
|
|
877
|
|
878 $ErrorMsg = "_BitVectorAndOperator: Bitwise XOR oparation failed";
|
|
879 $CheckBitVectorSizes = 1;
|
|
880 ($This, $Other, $OrderFlipped, $OtherIsBitVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckBitVectorSizes);
|
|
881
|
|
882 if (!$OtherIsBitVector) {
|
|
883 if ($OrderFlipped) {
|
|
884 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a bit vector...";
|
|
885 }
|
|
886 }
|
|
887 my($BitVector);
|
|
888 $BitVector = (ref $This)->new($This->{Size});
|
|
889 $BitVector->{BitValues} = $This->{BitValues} ^ $Other->{BitValues};
|
|
890
|
|
891 return $BitVector;
|
|
892 }
|
|
893
|
|
894 # Bitwise negation operation for BitVectors...
|
|
895 #
|
|
896 sub _BitVectorNegationOperator {
|
|
897 my($This, $Other, $OrderFlipped, $OtherIsBitVector, $ErrorMsg, $CheckBitVectorSizes);
|
|
898
|
|
899 $ErrorMsg = "_BitVectorAndOperator: Bitwise negation oparation failed";
|
|
900 $CheckBitVectorSizes = 1;
|
|
901 ($This, $Other, $OrderFlipped, $OtherIsBitVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckBitVectorSizes);
|
|
902
|
|
903 my($BitVector);
|
|
904 $BitVector = (ref $This)->new($This->{Size});
|
|
905 $BitVector->{BitValues} = ~ $This->{BitValues};
|
|
906
|
|
907 return $BitVector;
|
|
908 }
|
|
909
|
|
910 # Bit vector equla operator. Two bit vectors are considered equal assuming their size
|
|
911 # is same and bits are on at the same positions...
|
|
912 #
|
|
913 sub _BitVectorEqualOperator {
|
|
914 my($This, $Other, $OrderFlipped, $OtherIsBitVector, $ErrorMsg, $CheckBitVectorSizes);
|
|
915
|
|
916 $ErrorMsg = "_BitVectorEqualOperator: BitVector == oparation failed";
|
|
917 $CheckBitVectorSizes = 0;
|
|
918 ($This, $Other, $OrderFlipped, $OtherIsBitVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckBitVectorSizes);
|
|
919
|
|
920 if (!$OtherIsBitVector) {
|
|
921 if ($OrderFlipped) {
|
|
922 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a bit vector...";
|
|
923 }
|
|
924 }
|
|
925 if ($This->GetSize() != $Other->GetSize()) {
|
|
926 return 0;
|
|
927 }
|
|
928 if ($This->GetNumOfSetBits() != $Other->GetNumOfSetBits()) {
|
|
929 return 0;
|
|
930 }
|
|
931 # Check number of On bits only in This vector. It must be zero for vectors to be equal...
|
|
932 my($BitVector);
|
|
933 $BitVector = $This & ~$Other;
|
|
934
|
|
935 return $BitVector->GetNumOfSetBits() ? 0 : 1;
|
|
936 }
|
|
937
|
|
938 # Bit vector not equal operator. Two bit vectors are considered not equal when their size
|
|
939 # is different or bits are on at the same positions...
|
|
940 #
|
|
941 sub _BitVectorNotEqualOperator {
|
|
942 my($This, $Other, $OrderFlipped, $OtherIsBitVector, $ErrorMsg, $CheckBitVectorSizes);
|
|
943
|
|
944 $ErrorMsg = "_BitVectorEqualOperator: BitVector != oparation failed";
|
|
945 $CheckBitVectorSizes = 0;
|
|
946 ($This, $Other, $OrderFlipped, $OtherIsBitVector) = _ProcessOverloadedOperatorParameters($ErrorMsg, @_, $CheckBitVectorSizes);
|
|
947
|
|
948 if (!$OtherIsBitVector) {
|
|
949 if ($OrderFlipped) {
|
|
950 croak "Error: ${ClassName}->${ErrorMsg}: First object must be a bit vector...";
|
|
951 }
|
|
952 }
|
|
953 if ($This->GetSize() != $Other->GetSize()) {
|
|
954 return 1;
|
|
955 }
|
|
956 if ($This->GetNumOfSetBits() != $Other->GetNumOfSetBits()) {
|
|
957 return 1;
|
|
958 }
|
|
959 # Check number of On bits only in This vector. It must be zero for vectors to be equal...
|
|
960 my($BitVector);
|
|
961 $BitVector = $This & ~$Other;
|
|
962
|
|
963 return $BitVector->GetNumOfSetBits() ? 1 : 0;
|
|
964 }
|
|
965
|
|
966 # Process parameters passed to overloaded operators...
|
|
967 #
|
|
968 # For uninary operators, $SecondParameter is not defined.
|
|
969 sub _ProcessOverloadedOperatorParameters {
|
|
970 my($ErrorMsg, $FirstParameter, $SecondParameter, $ParametersOrderStatus, $CheckBitVectorSizesStatus) = @_;
|
|
971 my($This, $Other, $OrderFlipped, $OtherIsBitVector, $CheckBitVectorSizes);
|
|
972
|
|
973 ($This, $Other) = ($FirstParameter, $SecondParameter);
|
|
974 $OrderFlipped = (defined($ParametersOrderStatus) && $ParametersOrderStatus) ? 1 : 0;
|
|
975 $CheckBitVectorSizes = (defined $CheckBitVectorSizesStatus) ? $CheckBitVectorSizesStatus : 1;
|
|
976
|
|
977 _ValidateBitVector($ErrorMsg, $This);
|
|
978
|
|
979 $OtherIsBitVector = 0;
|
|
980 if (defined($Other) && (ref $Other)) {
|
|
981 # Make sure $Other is a vector...
|
|
982 _ValidateBitVector($ErrorMsg, $Other);
|
|
983 if ($CheckBitVectorSizes) {
|
|
984 _ValidateBitVectorSizesAreEqual($ErrorMsg, $This, $Other);
|
|
985 }
|
|
986 $OtherIsBitVector = 1;
|
|
987 }
|
|
988 return ($This, $Other, $OrderFlipped, $OtherIsBitVector);
|
|
989 }
|
|
990
|
|
991 # Is it a bit vector object?
|
|
992 sub _IsBitVector {
|
|
993 my($Object) = @_;
|
|
994
|
|
995 return (Scalar::Util::blessed($Object) && $Object->isa($ClassName)) ? 1 : 0;
|
|
996 }
|
|
997
|
|
998 # Make sure it's a bit vector reference...
|
|
999 sub _ValidateBitVector {
|
|
1000 my($ErrorMsg, $Vector) = @_;
|
|
1001
|
|
1002 if (!_IsBitVector($Vector)) {
|
|
1003 croak "Error: ${ClassName}->${ErrorMsg}: Object must be a bit vector...";
|
|
1004 }
|
|
1005 }
|
|
1006
|
|
1007 # Make sure size of the two bit vectors are equal...
|
|
1008 sub _ValidateBitVectorSizesAreEqual {
|
|
1009 my($ErrorMsg, $BitVector1, $BitVector2) = @_;
|
|
1010
|
|
1011 if ($BitVector1->GetSize() != $BitVector2->GetSize()) {
|
|
1012 croak "Error: ${ClassName}->${ErrorMsg}: Size of the bit vectors must be same...";
|
|
1013 }
|
|
1014 }
|
|
1015
|
|
1016 # Return a string containing vector values...
|
|
1017 sub StringifyBitVector {
|
|
1018 my($This) = @_;
|
|
1019 my($BitVectorString, $PrintFormat, $BitOrder, $BitsValue);
|
|
1020
|
|
1021 $PrintFormat = (exists $This->{ValueFormat}) ? $This->{ValueFormat} : $ValueFormat;
|
|
1022 $BitOrder = (exists $This->{ValueBitOrder}) ? $This->{ValueBitOrder} : $ValueBitOrder;
|
|
1023 $BitVectorString = '';
|
|
1024
|
|
1025 FORMAT: {
|
|
1026 if ($PrintFormat =~ /^(Hexadecimal|Hex|HexadecimalString)$/i) { $BitsValue = $This->_GetBitsAsString('Hexadecimal', $BitOrder); last FORMAT; }
|
|
1027 if ($PrintFormat =~ /^(Octal|Oct|OctalString)$/i) { $BitsValue = $This->_GetBitsAsString('Octal', $BitOrder); last FORMAT; }
|
|
1028 if ($PrintFormat =~ /^(Decimal|Dec|DecimalString)$/i) { $BitsValue = $This->_GetBitsAsString('Decimal', $BitOrder); last FORMAT; }
|
|
1029 if ($PrintFormat =~ /^(RawBinary|RawBin|RawBinaryString)$/i) { $BitsValue = $This->_GetBitsAsString('RawBinary'); last FORMAT; }
|
|
1030 # Default is bninary format...
|
|
1031 $BitsValue = $This->_GetBitsAsString('Binary', $BitOrder);
|
|
1032 }
|
|
1033 $BitVectorString = "<Size: ". $This->GetSize() . ";BitOrder: $BitOrder; Value: " . $BitsValue . ">";
|
|
1034
|
|
1035 return $BitVectorString;
|
|
1036 }
|
|
1037
|
|
1038 1;
|
|
1039
|
|
1040 __END__
|
|
1041
|
|
1042 =head1 NAME
|
|
1043
|
|
1044 BitVector
|
|
1045
|
|
1046 =head1 SYNOPSIS
|
|
1047
|
|
1048 use BitVector;
|
|
1049
|
|
1050 use BitVector ();
|
|
1051
|
|
1052 use BitVector qw(:all);
|
|
1053
|
|
1054 =head1 DESCRIPTION
|
|
1055
|
|
1056 B<BitVector> class provides the following methods:
|
|
1057
|
|
1058 new, ClearAllBits, ClearBit, ClearBits, ClearBitsRange, Copy, FlipAllBits,
|
|
1059 FlipBit, FlipBits, FlipBitsRange, GetBit, GetBitsAsBinaryString,
|
|
1060 GetBitsAsDecimalString, GetBitsAsHexadecimalString, GetBitsAsOctalString,
|
|
1061 GetBitsAsRawBinaryString, GetDensityOfClearBits, GetDensityOfSetBits,
|
|
1062 GetNumOfClearBits, GetNumOfSetBits, GetSize, IsBitClear, IsBitSet, IsBitVector,
|
|
1063 NewFromBinaryString, NewFromDecimalString, NewFromHexadecimalString,
|
|
1064 NewFromOctalString, NewFromRawBinaryString, Reverse, SetAllBits, SetBit,
|
|
1065 SetBitValue, SetBitValueBitOrder, SetBitValuePrintFormat, SetBits,
|
|
1066 SetBitsAsBinaryString, SetBitsAsDecimalString, SetBitsAsHexadecimalString,
|
|
1067 SetBitsAsOctalString, SetBitsAsRawBinaryString, SetBitsRange, StringifyBitVector
|
|
1068
|
|
1069 The following methods can also be used as functions:
|
|
1070
|
|
1071 IsBitVector, NewFromBinaryString, NewFromDecimalString, NewFromHexadecimalString,
|
|
1072 NewFromOctalString, NewFromRawBinaryString
|
|
1073
|
|
1074 The following operators are overloaded:
|
|
1075
|
|
1076 "" & | ^ ~ == !=
|
|
1077
|
|
1078 Internally, bits are stored in ascending order using Perl vec function. Regardless
|
|
1079 of machine order, big-endian or little-endian, vec function always considers first
|
|
1080 string byte as the lowest byte and first bit within each byte as the lowest bit.
|
|
1081
|
|
1082 Things to keep in mind:
|
|
1083
|
|
1084 o Bit numbers range from 0 to (Size - 1).
|
|
1085 o Bit data retieval methods provide options to data in ascending or
|
|
1086 descending bit order. Default is ascending bit order.
|
|
1087 o Stringyfy method provides an option to print data in ascending or
|
|
1088 descending bit order. Default is ascending bit order.
|
|
1089
|
|
1090 =head2 METHODS
|
|
1091
|
|
1092 =over 4
|
|
1093
|
|
1094 =item B<new>
|
|
1095
|
|
1096 $NewBitVector = new BitVector($Size);
|
|
1097
|
|
1098 Create a new I<BitVector> object of size I<Size> and return newly created
|
|
1099 B<BitVector>. Bit numbers range from 0 to 1 less than I<Size>.
|
|
1100
|
|
1101 =item B<ClearAllBits>
|
|
1102
|
|
1103 $BitVector->ClearAllBits();
|
|
1104
|
|
1105 Set all bit values to 0 in I<BitVector> object and return I<BitVector>.
|
|
1106
|
|
1107 =item B<ClearBit>
|
|
1108
|
|
1109 $BitVector->ClearBit($BitNum);
|
|
1110
|
|
1111 Set specified bit number I<BitNum> to 0 in I<BitVector> object and return I<BitVector>.
|
|
1112
|
|
1113 =item B<ClearBits>
|
|
1114
|
|
1115 $BitVector->ClearBits(@BitNums);
|
|
1116
|
|
1117 Set specified bit numbers I<BitNums> to 0 in I<BitVector> object and return I<BitVector>.
|
|
1118
|
|
1119 =item B<ClearBitsRange>
|
|
1120
|
|
1121 $BitVector->ClearBitsRange($MinBitNum, $MaxBitNum);
|
|
1122
|
|
1123 Set specified bit numbers between I<MinBitNum> and I<MaxBitNum> to 0 in I<BitVector>
|
|
1124 object and return I<BitVector>.
|
|
1125
|
|
1126 =item B<Copy>
|
|
1127
|
|
1128 $NewBitVector = $BitVector->Copy();
|
|
1129
|
|
1130 Copy I<BitVector> and its associated data to a new B<BitVector> and return a new
|
|
1131 B<BitVector>.
|
|
1132
|
|
1133 =item B<FlipAllBits>
|
|
1134
|
|
1135 $BitVector->FlipAllBits();
|
|
1136
|
|
1137 Flip values of all bits in I<BitVector> and its associated data to a new B<BitVector> and return
|
|
1138 I<BitVector>.
|
|
1139
|
|
1140 =item B<FlipBit>
|
|
1141
|
|
1142 $BitVector->FlipBit($BitNum);
|
|
1143
|
|
1144 Flip value of specified I<BitNum> of in I<BitVector> and return I<BitVector>.
|
|
1145
|
|
1146 =item B<FlipBits>
|
|
1147
|
|
1148 $BitVector->FlipBits(@BitNums);
|
|
1149
|
|
1150 Flip values of specified bit numbers I<BitNums> in I<BitVector> object and return I<BitVector>.
|
|
1151
|
|
1152 =item B<FlipBitsRange>
|
|
1153
|
|
1154 $BitVector->FlipBitsRange($MinBitNum, $MaxBitNum);
|
|
1155
|
|
1156 Flip values of specified bit numbers between I<MinBitNum> and I<MaxBitNum> in I<BitVector>
|
|
1157 object and return I<BitVector>.
|
|
1158
|
|
1159 =item B<GetBit>
|
|
1160
|
|
1161 $BitValue = $BitVector->GetBit($BitNum);
|
|
1162
|
|
1163 Returns value of bit number I<BitNum> in I<BitVector> object.
|
|
1164
|
|
1165 =item B<GetBitsAsBinaryString>
|
|
1166
|
|
1167 $BitString = $BitVector->GetBitsAsBinaryString([$BitOrder]);
|
|
1168
|
|
1169 Returns values of bits in I<BitVector> as an ascii bit string containing 0s and 1s.
|
|
1170
|
|
1171 Default I<BitOrder> is I<Ascending> bit order which corresponds to first bit in each
|
|
1172 byte as the loweset bit as opposed to the higest bit.
|
|
1173
|
|
1174 =item B<GetBitsAsDecimalString>
|
|
1175
|
|
1176 $BitString = $BitVector->GetBitsAsDecimalString([$BitOrder]);
|
|
1177
|
|
1178 Returns values of bits in I<BitVector> as a decimal bit string containing values from 0 to
|
|
1179 9.
|
|
1180
|
|
1181 Default I<BitOrder> is I<Ascending> bit order which corresponds to first bit in each
|
|
1182 byte as the loweset bit as opposed to the higest bit.
|
|
1183
|
|
1184 =item B<GetBitsAsHexadecimalString>
|
|
1185
|
|
1186 $BitString = $BitVector->GetBitsAsHexadecimalString([$BitOrder]);
|
|
1187
|
|
1188 Returns values of bits in I<BitVector> as a hexadecimal bit string containing values from 0 to 9
|
|
1189 and a to f.
|
|
1190
|
|
1191 Default I<BitOrder> is I<Ascending> bit order which corresponds to first bit in each
|
|
1192 byte as the loweset bit as opposed to the higest bit.
|
|
1193
|
|
1194 =item B<GetBitsAsOctalString>
|
|
1195
|
|
1196 $BitString = $BitVector->GetBitsAsOctalString([$BitOrder]);
|
|
1197
|
|
1198 Returns values of bits in I<BitVector> as an octal bit string containing values form 0 to
|
|
1199 7.
|
|
1200
|
|
1201 Default I<BitOrder> is I<Ascending> bit order which corresponds to first bit in each
|
|
1202 byte as the loweset bit as opposed to the higest bit.
|
|
1203
|
|
1204 =item B<GetBitsAsRawBinaryString>
|
|
1205
|
|
1206 $BitString = $BitVector->GetBitsAsRawBinaryString();
|
|
1207
|
|
1208 Returns values of bits in I<BitVector> as an string corresponding to packed bit values
|
|
1209 used by Perl vec function without perfoming any unpacking.
|
|
1210
|
|
1211 =item B<GetDensityOfClearBits>
|
|
1212
|
|
1213 $ClearBitsDensity = $BitVector->GetDensityOfClearBits();
|
|
1214
|
|
1215 Returns density of clear bits in I<BitVector> which corresponds to number of bits set to 0
|
|
1216 I<BitVector> divided by its size.
|
|
1217
|
|
1218 =item B<GetDensityOfSetBits>
|
|
1219
|
|
1220 $SetBitsDensity = $BitVector->GetDensityOfSetBits();
|
|
1221
|
|
1222 Returns density of set bits in I<BitVector> which corresponds to number of bits set to 1 in
|
|
1223 I<BitVector> divided by its size.
|
|
1224
|
|
1225 =item B<GetNumOfClearBits>
|
|
1226
|
|
1227 $NumOfClearBits = $BitVector->GetNumOfClearBits();
|
|
1228
|
|
1229 Returns number of bits set to 0 in I<BitVector>.
|
|
1230
|
|
1231 =item B<GetNumOfSetBits>
|
|
1232
|
|
1233 $NumOfSetBits = $BitVector->GetNumOfSetBits();
|
|
1234
|
|
1235 Returns number of bits set to 1 in I<BitVector>.
|
|
1236
|
|
1237 =item B<GetSize>
|
|
1238
|
|
1239 $Size = $BitVector->GetSize();
|
|
1240
|
|
1241 Returns size of I<BitVector>.
|
|
1242
|
|
1243 =item B<IsBitClear>
|
|
1244
|
|
1245 $Status = $BitVector->IsBitClear();
|
|
1246
|
|
1247 Returns 1 or 0 based on whether I<BitNum> is set to 0 in I<BitVector>.
|
|
1248
|
|
1249 =item B<IsBitSet>
|
|
1250
|
|
1251 $Status = $BitVector->IsBitSet($BitNum);
|
|
1252
|
|
1253 Returns 1 or 0 based on whether I<BitNum> is set to 1 in I<BitVector>.
|
|
1254
|
|
1255 =item B<IsBitVector>
|
|
1256
|
|
1257 $Status = BitVector::IsBitVector($Object);
|
|
1258
|
|
1259 Returns 1 or 0 based on whether I<Object> is a B<BitVector> object.
|
|
1260
|
|
1261 =item B<NewFromBinaryString>
|
|
1262
|
|
1263 $NewBitVector = BitVector::NewFromBinaryString($BinaryString,
|
|
1264 [$BitOrder]);
|
|
1265 $NewBitVector = $BitVector->NewFromBinaryString($BinaryString,
|
|
1266 [$BitOrder]);
|
|
1267
|
|
1268 Creates a new I<BitVector> using I<BinaryString> and returns new B<BitVector> object.
|
|
1269
|
|
1270 Default I<BitOrder> is I<Ascending> bit order which corresponds to first bit in each
|
|
1271 byte as the loweset bit as opposed to the higest bit.
|
|
1272
|
|
1273 =item B<NewFromDecimalString>
|
|
1274
|
|
1275 $NewBitVector = BitVector::NewFromDecimalString($DecimalString,
|
|
1276 [$BitOrder]);
|
|
1277 $NewBitVector = $BitVector->NewFromDecimalString($DecimalString,
|
|
1278 [$BitOrder]);
|
|
1279
|
|
1280 Creates a new I<BitVector> using I<DecimalString> and returns new B<BitVector> object.
|
|
1281
|
|
1282 Default I<BitOrder> is I<Ascending> bit order which corresponds to first bit in each
|
|
1283 byte as the loweset bit as opposed to the higest bit.
|
|
1284
|
|
1285 =item B<NewFromHexadecimalString>
|
|
1286
|
|
1287 $NewBitVector = BitVector::NewFromHexadecimalString(
|
|
1288 $HexadecimalString, [$BitOrder]);
|
|
1289 $NewBitVector = $BitVector->NewFromHexadecimalString(
|
|
1290 $HexadecimalString, [$BitOrder]);
|
|
1291
|
|
1292 Creates a new I<BitVector> using I<HexadecimalString> and returns new B<BitVector> object.
|
|
1293
|
|
1294 Default I<BitOrder> is I<Ascending> bit order which corresponds to first bit in each
|
|
1295 byte as the loweset bit as opposed to the higest bit.
|
|
1296
|
|
1297 =item B<NewFromOctalString>
|
|
1298
|
|
1299 $NewBitVector = BitVector::NewFromOctalString($OctalString, [$BitOrder]);
|
|
1300 $NewBitVector = $BitVector->NewFromOctalString($OctalString, [$BitOrder]);
|
|
1301
|
|
1302 Creates a new I<BitVector> using I<OctalString> and returns new B<BitVector> object.
|
|
1303
|
|
1304 Default I<BitOrder> is I<Ascending> bit order which corresponds to first bit in each
|
|
1305 byte as the loweset bit as opposed to the higest bit.
|
|
1306
|
|
1307 =item B<NewFromRawBinaryString>
|
|
1308
|
|
1309 $NewBitVector = BitVector::NewFromRawBinaryString(
|
|
1310 $RawBinaryString);
|
|
1311 $NewBitVector = $BitVector->NewFromRawBinaryString(
|
|
1312 $RawBinaryString);
|
|
1313
|
|
1314 Creates a new I<BitVector> using I<RawBinaryString> and returns new B<BitVector> object.
|
|
1315
|
|
1316 =item B<Reverse>
|
|
1317
|
|
1318 $BitVector->Reverse();
|
|
1319
|
|
1320 Reverses values of bits in I<BitVector> and returns I<BitVector>. First bit number ends up with
|
|
1321 value of last bit number.
|
|
1322
|
|
1323 =item B<SetAllBits>
|
|
1324
|
|
1325 $BitVector->SetAllBits();
|
|
1326
|
|
1327 Sets values of all bits in I<BitVector> to 1 and returns I<BitVector>.
|
|
1328
|
|
1329 =item B<SetBit>
|
|
1330
|
|
1331 $BitVector->SetBit($BitNum);
|
|
1332
|
|
1333 Sets value of I<BitNum> to 1 in I<BitVector> and returns I<BitVector>.
|
|
1334
|
|
1335 =item B<SetBitValue>
|
|
1336
|
|
1337 $BitVector->SetBitValue($BitNum, $BitValue);
|
|
1338
|
|
1339 Sets value of I<BitNum> to I<BitValue> in I<BitVector> and returns I<BitVector>.
|
|
1340
|
|
1341 =item B<SetBitValueBitOrder>
|
|
1342
|
|
1343 BitVector::SetBitValueBitOrder($BitOrder);
|
|
1344 $BitVector->SetBitValueBitOrder($BitOrder);
|
|
1345
|
|
1346 Set bit order for printing B<BitVector> values during stringification of B<BitVector> object.
|
|
1347 Possible bit order values: I<Ascending or Descending>.
|
|
1348
|
|
1349 Bit order can be set for either an individual B<BitVector> object or the class. Default is
|
|
1350 to print bits in each byte in I<Asscending> bit order.
|
|
1351
|
|
1352 Internally, bits are stored in I<Ascending> bit order using Perl vec function. Regardless
|
|
1353 of machine order, big-endian or little-endian, vec function always considers first
|
|
1354 string byte as the lowest byte and first bit within each byte as the lowest bit.
|
|
1355
|
|
1356 =item B<SetBitValuePrintFormat>
|
|
1357
|
|
1358 BitVector::SetBitValuePrintFormat($PrintValueFormat);
|
|
1359 $BitVector->SetBitValuePrintFormat($PrintValueFormat);
|
|
1360
|
|
1361 Set bit values print format for printing B<BitVector> values during stringification of B<BitVector>
|
|
1362 object. Possible print format values: I<Binary, Bin, Hexadecimal, Hex, Decimal, Dec, Octal,
|
|
1363 Oct, RawBinary, RawBin>. Default: I<Binary>.
|
|
1364
|
|
1365 Bit values print format can be set for either an individual B<BitVector> object or the class.
|
|
1366
|
|
1367 =item B<SetBits>
|
|
1368
|
|
1369 $BitVector->SetBits(@BitNums);
|
|
1370
|
|
1371 Set specified bit numbers I<BitNums> to 1 in I<BitVector> object and return I<BitVector>.
|
|
1372
|
|
1373 =item B<SetBitsAsBinaryString>
|
|
1374
|
|
1375 $BitVector->SetBitsAsBinaryString($BinaryString);
|
|
1376
|
|
1377 Set bit values in I<BitVector> using specified I<BinaryString> and return I<BitVector>. The
|
|
1378 size of I<BitVector> is not changed.
|
|
1379
|
|
1380 =item B<SetBitsAsDecimalString>
|
|
1381
|
|
1382 $BitVector->SetBitsAsDecimalString($DecimalString, [$BitOrder]);
|
|
1383
|
|
1384 Set bit values in I<BitVector> using specified I<DecimalString> and return I<BitVector>. The
|
|
1385 size of I<BitVector> is not changed.
|
|
1386
|
|
1387 =item B<SetBitsAsHexadecimalString>
|
|
1388
|
|
1389 $BitVector->SetBitsAsHexadecimalString($HexadecimalString, [$BitOrder]);
|
|
1390
|
|
1391 Set bit values in I<BitVector> using specified I<HexadecimalString> and return I<BitVector>. The
|
|
1392 size of I<BitVector> is not changed.
|
|
1393
|
|
1394 =item B<SetBitsAsOctalString>
|
|
1395
|
|
1396 $BitVector->SetBitsAsOctalString($OctalString, [$BitOrder]);
|
|
1397
|
|
1398 Set bit values in I<BitVector> using specified I<OctalString> and return I<BitVector>. The
|
|
1399 size of I<BitVector> is not changed.
|
|
1400
|
|
1401 =item B<SetBitsAsRawBinaryString>
|
|
1402
|
|
1403 $BitVector->SetBitsAsRawBinaryString($RawBinaryString);
|
|
1404
|
|
1405 Set bit values in I<BitVector> using specified I<RawBinaryString> and return I<BitVector>. The
|
|
1406 size of I<BitVector> is not changed.
|
|
1407
|
|
1408 =item B<SetBitsRange>
|
|
1409
|
|
1410 $BitVector->SetBitsRange($MinBitNum, $MaxBitNum);
|
|
1411
|
|
1412 Set specified bit numbers between I<MinBitNum> and I<MaxBitNum> to 1 in I<BitVector>
|
|
1413 object and return I<BitVector>.
|
|
1414
|
|
1415 =item B<StringifyBitVector>
|
|
1416
|
|
1417 $String = $BitVector->StringifyBitVector();
|
|
1418
|
|
1419 Returns a string containing information about I<BitVector> object.
|
|
1420
|
|
1421 =back
|
|
1422
|
|
1423 =head1 AUTHOR
|
|
1424
|
|
1425 Manish Sud <msud@san.rr.com>
|
|
1426
|
|
1427 =head1 SEE ALSO
|
|
1428
|
|
1429 Vector.pm
|
|
1430
|
|
1431 =head1 COPYRIGHT
|
|
1432
|
|
1433 Copyright (C) 2015 Manish Sud. All rights reserved.
|
|
1434
|
|
1435 This file is part of MayaChemTools.
|
|
1436
|
|
1437 MayaChemTools is free software; you can redistribute it and/or modify it under
|
|
1438 the terms of the GNU Lesser General Public License as published by the Free
|
|
1439 Software Foundation; either version 3 of the License, or (at your option)
|
|
1440 any later version.
|
|
1441
|
|
1442 =cut
|