MiniDisplay/BitArray.cpp
author sl
Thu, 29 May 2014 19:46:57 +0200
changeset 18 79801cc3bc94
parent 4 7d34342ac6e9
permissions -rw-r--r--
Restoring some of our on-screen functionality for debug purposes.
We could prove that updating a single pixel is much faster than updating our
whole screen. Single pixel updates runs at full 24 FPS.
     1 /***************************************************************************
     2 *                         Arrays of Arbitrary Bit Length
     3 *
     4 *   File    : bitarray.cpp
     5 *   Purpose : Provides object with methods for creation and manipulation of
     6 *             arbitrary length arrays of bits.
     7 *
     8 *             Bit arrays are implemented as vectors of unsigned chars.  Bit
     9 *             0 is the MSB of char 0, and the last bit is the least
    10 *             significant (non-spare) bit of the last unsigned char.
    11 *
    12 *             Example: array of 20 bits (0 through 19) with 8 bit unsigned
    13 *                      chars requires 3 unsigned chars (0 through 2) to
    14 *                      store all the bits.
    15 *
    16 *                        char       0       1         2
    17 *                               +--------+--------+--------+
    18 *                               |        |        |        |
    19 *                               +--------+--------+--------+
    20 *                        bit     01234567 8911111111111XXXX
    21 *                                           012345 6789
    22 *
    23 *   Author  : Michael Dipperstein
    24 *   Date    : July 23, 2004
    25 *
    26 ****************************************************************************
    27 *   HISTORY
    28 *
    29 *   $Id: bitarray.cpp,v 1.7 2010/02/04 03:31:43 michael Exp $
    30 *   $Log: bitarray.cpp,v $
    31 *   Revision 1.7  2010/02/04 03:31:43  michael
    32 *   Replaced vector<unsigned char> with an array of unsigned char.
    33 *
    34 *   Made updates for GCC 4.4.
    35 *
    36 *   Revision 1.5  2007/08/06 05:23:29  michael
    37 *   Updated for LGPL Version 3.
    38 *
    39 *   All methods that don't modify object have been made
    40 *   const to increase functionality of const bit_array_c.
    41 *
    42 *   All assignment operators return a reference to the object being assigned a value so that operator chaining will work.
    43 *
    44 *   Added >> and << operators.
    45 *
    46 *   Revision 1.3  2006/04/30 23:34:07  michael
    47 *   Improved performance by incorporating Benjamin Schindler's
    48 *   <bschindler@student.ethz.ch> changes to pass arguments as a reference.
    49 *
    50 *   Revision 1.2  2004/08/05 22:16:49  michael
    51 *   Add overloads for bitwise operators returning values.
    52 *   Add a more natural looking way to set bit values.
    53 *
    54 *   Revision 1.1.1.1  2004/08/04 13:28:20  michael
    55 *   bit_array_c
    56 *
    57 ****************************************************************************
    58 *
    59 * Bitarray: An ANSI C++ class for manipulating arbitrary length bit arrays
    60 * Copyright (C) 2004, 2006-2007, 2010 by
    61 *       Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
    62 *
    63 * This file is part of the bit array library.
    64 *
    65 * The bit array library is free software; you can redistribute it and/or
    66 * modify it under the terms of the GNU Lesser General Public License as
    67 * published by the Free Software Foundation; either version 3 of the
    68 * License, or (at your option) any later version.
    69 *
    70 * The bit array library is distributed in the hope that it will be useful,
    71 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    72 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
    73 * General Public License for more details.
    74 *
    75 * You should have received a copy of the GNU Lesser General Public License
    76 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    77 *
    78 ***************************************************************************/
    79 
    80 /***************************************************************************
    81 *                             INCLUDED FILES
    82 ***************************************************************************/
    83 #include <iostream>
    84 #include <climits>
    85 #include "bitarray.h"
    86 
    87 using namespace std;
    88 
    89 /***************************************************************************
    90 *                                 MACROS
    91 ***************************************************************************/
    92 
    93 /* make CHAR_BIT 8 if it's not defined in limits.h */
    94 #ifndef CHAR_BIT
    95 #warning CHAR_BIT not defined.  Assuming 8 bits.
    96 #define CHAR_BIT 8
    97 #endif
    98 
    99 /* position of bit within character */
   100 #define BIT_CHAR(bit)         ((bit) / CHAR_BIT)
   101 
   102 /* array index for character containing bit */
   103 //SL: We had to change that macro since bits in our frame buffer are the other way around
   104 //TODO: Find a solution to tackle that problem
   105 //#define BIT_IN_CHAR(bit)      (1 << (CHAR_BIT - 1 - ((bit)  % CHAR_BIT)))
   106 #define BIT_IN_CHAR(bit)      (1 << (((bit)  % CHAR_BIT)))
   107 
   108 /* number of characters required to contain number of bits */
   109 #define BITS_TO_CHARS(bits)   ((((bits) - 1) / CHAR_BIT) + 1)
   110 
   111 /* most significant bit in a character */
   112 #define MS_BIT                (1 << (CHAR_BIT - 1))
   113 
   114 /***************************************************************************
   115 *                                 METHODS
   116 ***************************************************************************/
   117 
   118 /***************************************************************************
   119 *   Method     : bit_array_c - constructor
   120 *   Description: This is the bit_array_c constructor.  It reserves memory
   121 *                for the vector storing the array.
   122 *   Parameters : numBits - number of bits in the array
   123 *   Effects    : Allocates vectory for array bits
   124 *   Returned   : None
   125 ***************************************************************************/
   126 BitArray::BitArray(const int numBits):
   127     m_NumBits(numBits),
   128     m_Array(NULL),
   129     m_OwnsBuffer(true)
   130 {
   131     m_SizeInBytes = BITS_TO_CHARS(numBits);
   132 
   133 
   134     /* allocate space for bit array */
   135     m_Array = new unsigned char[m_SizeInBytes];
   136 
   137     /* set all bits to 0 */
   138     fill_n(m_Array, m_SizeInBytes, 0);
   139 }
   140 
   141 /***************************************************************************
   142 *   Method     : bit_array_c - constructor
   143 *   Description: This is the bit_array_c constructor.  It copies the
   144 *                for contents of a vector of unsigned char into the
   145 *                bitarray.
   146 *   Parameters : vect - vector to be copied
   147 *                numBits - number of bits in the array
   148 *   Effects    : Allocates vectory for array bits
   149 *   Returned   : None
   150 ***************************************************************************/
   151 BitArray::BitArray(unsigned char *array, const int numBits,bool aOwnsBuffer):
   152     m_NumBits(numBits),
   153     m_Array(array),
   154     m_OwnsBuffer(aOwnsBuffer)
   155 {
   156 
   157 }
   158 
   159 /***************************************************************************
   160 *   Method     : ~bit_array_c - destructor
   161 *   Description: This is the bit_array_c destructor.  At this point it's
   162 *                just a place holder.
   163 *   Parameters : None
   164 *   Effects    : None
   165 *   Returned   : None
   166 ***************************************************************************/
   167 BitArray::~BitArray(void)
   168 {
   169     if (m_OwnsBuffer)
   170     {
   171         delete[] m_Array;
   172         m_Array = NULL;
   173     }
   174 }
   175 
   176 /***************************************************************************
   177 *   Method     : Dump
   178 *   Description: This method dumps the conents of a bit array to stdout.
   179 *                The format of the dump is a series of bytes represented in
   180 *                hexadecimal.
   181 *   Parameters : outStream - stream to write to
   182 *   Effects    : Array contents are dumped to stdout
   183 *   Returned   : None
   184 ***************************************************************************/
   185 void BitArray::Dump(std::ostream &outStream)
   186 {
   187     int size;
   188 
   189     size = BITS_TO_CHARS(m_NumBits);
   190 
   191     outStream.width(2);
   192     outStream.fill('0');
   193     outStream << uppercase << hex << (int)(m_Array[0]);  /* first byte */
   194 
   195     for (int i = 1; i < size; i++)
   196     {
   197         /* remaining bytes with a leading space */
   198         outStream << " ";
   199         outStream.width(2);
   200         outStream.fill('0');
   201         outStream << (int)(m_Array[i]);
   202     }
   203 
   204     outStream << dec;
   205 }
   206 
   207 /***************************************************************************
   208 *   Method     : SetAll
   209 *   Description: This method sets every bit in the bit array to 1.  This
   210 *                method uses UCHAR_MAX to determine what it means to set
   211 *                all bits in an unsigned char, so it is crucial that the
   212 *                machine implementation of unsigned char utilizes all of
   213 *                the bits in the memory allocated for an unsigned char.
   214 *   Parameters : None
   215 *   Effects    : Each of the bits used in the bit array are set to 1.
   216 *                Unused (spare) bits are set to 0.
   217 *   Returned   : None
   218 ***************************************************************************/
   219 void BitArray::SetAll(void)
   220 {
   221     int bits, size;
   222     unsigned char mask;
   223 
   224     size = BITS_TO_CHARS(m_NumBits);
   225 
   226     /* set bits in all bytes to 1 */
   227     fill_n(m_Array, size, UCHAR_MAX);
   228 
   229     /* zero any spare bits so increment and decrement are consistent */
   230     bits = m_NumBits % CHAR_BIT;
   231     if (bits != 0)
   232     {
   233         mask = UCHAR_MAX << (CHAR_BIT - bits);
   234         m_Array[BIT_CHAR(m_NumBits - 1)] = mask;
   235     }
   236 }
   237 
   238 /***************************************************************************
   239 *   Method     : ClearAll
   240 *   Description: This method sets every bit in the bit array to 0.
   241 *   Parameters : None
   242 *   Effects    : Each of the bits in the bit array are set to 0.
   243 *   Returned   : None
   244 ***************************************************************************/
   245 void BitArray::ClearAll(void)
   246 {
   247     int size;
   248 
   249     size = BITS_TO_CHARS(m_NumBits);
   250 
   251     /* set bits in all bytes to 0 */
   252     fill_n(m_Array, size, 0);
   253 }
   254 
   255 /***************************************************************************
   256 *   Method     : SetBit
   257 *   Description: This method sets a bit in the bit array to 1.
   258 *   Parameters : bit - the number of the bit to set
   259 *   Effects    : The specified bit will be set to 1.
   260 *   Returned   : None
   261 ***************************************************************************/
   262 void BitArray::SetBit(const unsigned int bit)
   263 {
   264     if (m_NumBits <= bit)
   265     {
   266         return;         /* bit out of range */
   267     }
   268 
   269     m_Array[BIT_CHAR(bit)] |= BIT_IN_CHAR(bit);
   270 }
   271 
   272 /**
   273 */
   274 void BitArray::SetBitValue(const unsigned int bit, bool aValue)
   275 	{
   276 	if (aValue)
   277 		{
   278 		SetBit(bit);
   279 		}
   280 	else
   281 		{
   282 		ClearBit(bit);
   283 		}
   284 	}
   285 
   286 /***************************************************************************
   287 *   Method     : ClearBit
   288 *   Description: This method sets a bit in the bit array to 0.
   289 *   Parameters : bit - the number of the bit to clear
   290 *   Effects    : The specified bit will be set to 0.
   291 *   Returned   : None
   292 ***************************************************************************/
   293 void BitArray::ClearBit(const unsigned int bit)
   294 {
   295     unsigned char mask;
   296 
   297     if (m_NumBits <= bit)
   298     {
   299         return;         /* bit out of range */
   300     }
   301 
   302     /* create a mask to zero out desired bit */
   303     mask =  BIT_IN_CHAR(bit);
   304     mask = ~mask;
   305 
   306     m_Array[BIT_CHAR(bit)] &= mask;
   307 }
   308 
   309 /***************************************************************************
   310 *   Method     : operator()
   311 *   Description: Overload of the () operator.  This method approximates
   312 *                array indices used for assignment.  It returns a
   313 *                bit_array_index_c which includes an = method used to
   314 *                set bit values.
   315 *   Parameters : bit - index of array bit
   316 *   Effects    : None
   317 *   Returned   : bit_array_index_c (pointer to bit)
   318 ***************************************************************************/
   319 BitArrayIndex BitArray::operator()(const unsigned int bit)
   320 {
   321     BitArrayIndex result(this, bit);
   322 
   323     return result;
   324 }
   325 
   326 /***************************************************************************
   327 *   Method     : operator[]
   328 *   Description: Overload of the [] operator.  This method returns the
   329 *                value of a bit in the bit array.
   330 *   Parameters : bit - index of array bit
   331 *   Effects    : None
   332 *   Returned   : The value of the specified bit.
   333 ***************************************************************************/
   334 bool BitArray::operator[](const unsigned int bit) const
   335 {
   336     return((m_Array[BIT_CHAR(bit)] & BIT_IN_CHAR(bit)) != 0);
   337 }
   338 
   339 /***************************************************************************
   340 *   Method     : operator==
   341 *   Description: overload of the == operator
   342 *   Parameters : other - bit array to compare
   343 *   Effects    : None
   344 *   Returned   : True if this == other.  Otherwise false.
   345 ***************************************************************************/
   346 bool BitArray::operator==(const BitArray &other) const
   347 {
   348     if (m_NumBits != other.m_NumBits)
   349     {
   350         /* unequal sizes */
   351         return false;
   352     }
   353 
   354     return (this->m_Array == other.m_Array);
   355 }
   356 
   357 /***************************************************************************
   358 *   Method     : operator!=
   359 *   Description: overload of the != operator
   360 *   Parameters : other - bit array to compare
   361 *   Effects    : None
   362 *   Returned   : True if this != other.  Otherwise false.
   363 ***************************************************************************/
   364 bool BitArray::operator!=(const BitArray &other) const
   365 {
   366     if (m_NumBits != other.m_NumBits)
   367     {
   368         /* unequal sizes */
   369         return true;
   370     }
   371 
   372     return (this->m_Array != other.m_Array);
   373 }
   374 
   375 /***************************************************************************
   376 *   Method     : operator<
   377 *   Description: overload of the < operator
   378 *   Parameters : other - bit array to compare
   379 *   Effects    : None
   380 *   Returned   : True if this < other.  Otherwise false.
   381 ***************************************************************************/
   382 bool BitArray::operator<(const BitArray &other) const
   383 {
   384     if (m_NumBits != other.m_NumBits)
   385     {
   386         /* unequal sizes */
   387         return false;
   388     }
   389 
   390     return (this->m_Array < other.m_Array);
   391 }
   392 
   393 /***************************************************************************
   394 *   Method     : operator<=
   395 *   Description: overload of the <= operator
   396 *   Parameters : other - bit array to compare
   397 *   Effects    : None
   398 *   Returned   : True if this <= other.  Otherwise false.
   399 ***************************************************************************/
   400 bool BitArray::operator<=(const BitArray &other) const
   401 {
   402     if (m_NumBits != other.m_NumBits)
   403     {
   404         /* unequal sizes */
   405         return false;
   406     }
   407 
   408     return (this->m_Array <= other.m_Array);
   409 }
   410 
   411 /***************************************************************************
   412 *   Method     : operator>
   413 *   Description: overload of the > operator
   414 *   Parameters : other - bit array to compare
   415 *   Effects    : None
   416 *   Returned   : True if this > other.  Otherwise false.
   417 ***************************************************************************/
   418 bool BitArray::operator>(const BitArray &other) const
   419 {
   420     if (m_NumBits != other.m_NumBits)
   421     {
   422         /* unequal sizes */
   423         return false;
   424     }
   425 
   426     return (this->m_Array > other.m_Array);
   427 }
   428 
   429 /***************************************************************************
   430 *   Method     : operator>=
   431 *   Description: overload of the >= operator
   432 *   Parameters : other - bit array to compare
   433 *   Effects    : None
   434 *   Returned   : True if this >= other.  Otherwise false.
   435 ***************************************************************************/
   436 bool BitArray::operator>=(const BitArray &other) const
   437 {
   438     if (m_NumBits != other.m_NumBits)
   439     {
   440         /* unequal sizes */
   441         return false;
   442     }
   443 
   444     return (this->m_Array >= other.m_Array);
   445 }
   446 
   447 /***************************************************************************
   448 *   Method     : operator~
   449 *   Description: overload of the ~ operator.  Negates all non-spare bits in
   450 *                bit array
   451 *   Parameters : None
   452 *   Effects    : None
   453 *   Returned   : value of this after bitwise not
   454 ***************************************************************************/
   455 BitArray BitArray::operator~(void) const
   456 {
   457     BitArray result(this->m_NumBits);
   458     result = *this;
   459     result.Not();
   460 
   461     return result;
   462 }
   463 
   464 /***************************************************************************
   465 *   Method     : operator&
   466 *   Description: overload of the & operator.  Performs a bitwise and
   467 *                between the source array and this bit array.
   468 *   Parameters : other - bit array on righthand side of &
   469 *   Effects    : None
   470 *   Returned   : value of bitwise and of this and other.
   471 ***************************************************************************/
   472 BitArray BitArray::operator&(const BitArray &other) const
   473 {
   474     BitArray result(this->m_NumBits);
   475     result = *this;
   476     result &= other;
   477 
   478     return result;
   479 }
   480 
   481 
   482 /***************************************************************************
   483 *   Method     : operator^
   484 *   Description: overload of the ^ operator.  Performs a bitwise xor
   485 *                between the source array and this bit array.
   486 *   Parameters : other - bit array on righthand side of ^
   487 *   Effects    : None
   488 *   Returned   : value of bitwise xor of this and other.
   489 ***************************************************************************/
   490 BitArray BitArray::operator^(const BitArray &other) const
   491 {
   492     BitArray result(this->m_NumBits);
   493     result = *this;
   494     result ^= other;
   495 
   496     return result;
   497 }
   498 
   499 /***************************************************************************
   500 *   Method     : operator|
   501 *   Description: overload of the | operator.  Performs a bitwise or
   502 *                between the source array and this bit array.
   503 *   Parameters : other - bit array on righthand side of |
   504 *   Effects    : None
   505 *   Returned   : value of bitwise or of this and other.
   506 ***************************************************************************/
   507 BitArray BitArray::operator|(const BitArray &other) const
   508 {
   509     BitArray result(this->m_NumBits);
   510     result = *this;
   511     result |= other;
   512 
   513     return result;
   514 }
   515 
   516 /***************************************************************************
   517 *   Method     : operator<<
   518 *   Description: overload of the << operator.  Performs a bitwise left
   519 *                shift of this bit array.
   520 *   Parameters : count - the number of bits to shift left
   521 *   Effects    : None
   522 *   Returned   : result of bitwise left shift
   523 ***************************************************************************/
   524 BitArray BitArray::operator<<(const unsigned int count) const
   525 {
   526     BitArray result(this->m_NumBits);
   527     result = *this;
   528     result <<= count;
   529 
   530     return result;
   531 }
   532 
   533 /***************************************************************************
   534 *   Method     : operator>>
   535 *   Description: overload of the >> operator.  Performs a bitwise right
   536 *                shift of this bit array.
   537 *   Parameters : count - the number of bits to shift right
   538 *   Effects    : None
   539 *   Returned   : result of bitwise right shift
   540 ***************************************************************************/
   541 BitArray BitArray::operator>>(const unsigned int count) const
   542 {
   543     BitArray result(this->m_NumBits);
   544     result = *this;
   545     result >>= count;
   546 
   547     return result;
   548 }
   549 
   550 /***************************************************************************
   551 *   Method     : operator++ (prefix)
   552 *   Description: overload of the ++ operator.  Increments the contents of
   553 *                a bit array.  Overflows cause rollover.
   554 *   Parameters : None
   555 *   Effects    : Bit array contents are incremented
   556 *   Returned   : Reference to this array after increment
   557 ***************************************************************************/
   558 BitArray& BitArray::operator++(void)
   559 {
   560     int i;
   561     unsigned char maxValue;     /* maximum value for current char */
   562     unsigned char one;          /* least significant bit in current char */
   563 
   564     if (m_NumBits == 0)
   565     {
   566         return *this;           /* nothing to increment */
   567     }
   568 
   569     /* handle arrays that don't use every bit in the last character */
   570     i = (m_NumBits % CHAR_BIT);
   571     if (i != 0)
   572     {
   573         maxValue = UCHAR_MAX << (CHAR_BIT - i);
   574         one = 1 << (CHAR_BIT - i);
   575     }
   576     else
   577     {
   578         maxValue = UCHAR_MAX;
   579         one = 1;
   580     }
   581 
   582     for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
   583     {
   584         if (m_Array[i] != maxValue)
   585         {
   586             m_Array[i] = m_Array[i] + one;
   587             return *this;
   588         }
   589         else
   590         {
   591             /* need to carry to next byte */
   592             m_Array[i] = 0;
   593 
   594             /* remaining characters must use all bits */
   595             maxValue = UCHAR_MAX;
   596             one = 1;
   597         }
   598     }
   599 
   600     return *this;
   601 }
   602 
   603 /***************************************************************************
   604 *   Method     : operator++ (postfix)
   605 *   Description: overload of the ++ operator.  Increments the contents of
   606 *                a bit array.  Overflows cause rollover.
   607 *   Parameters : dumy - needed for postfix increment
   608 *   Effects    : Bit array contents are incremented
   609 *   Returned   : Reference to this array after increment
   610 ***************************************************************************/
   611 BitArray& BitArray::operator++(int dummy)
   612 {
   613     ++(*this);
   614     return *this;
   615 }
   616 
   617 /***************************************************************************
   618 *   Method     : operator-- (prefix)
   619 *   Description: overload of the -- operator.  Decrements the contents of
   620 *                a bit array.  Underflows cause rollover.
   621 *   Parameters : None
   622 *   Effects    : Bit array contents are decremented
   623 *   Returned   : None
   624 ***************************************************************************/
   625 BitArray& BitArray::operator--(void)
   626 {
   627     int i;
   628     unsigned char maxValue;     /* maximum value for current char */
   629     unsigned char one;          /* least significant bit in current char */
   630 
   631     if (m_NumBits == 0)
   632     {
   633         return *this;           /* nothing to decrement */
   634     }
   635 
   636     /* handle arrays that don't use every bit in the last character */
   637     i = (m_NumBits % CHAR_BIT);
   638     if (i != 0)
   639     {
   640         maxValue = UCHAR_MAX << (CHAR_BIT - i);
   641         one = 1 << (CHAR_BIT - i);
   642     }
   643     else
   644     {
   645         maxValue = UCHAR_MAX;
   646         one = 1;
   647     }
   648 
   649     for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
   650     {
   651         if (m_Array[i] >= one)
   652         {
   653             m_Array[i] = m_Array[i] - one;
   654             return *this;
   655         }
   656         else
   657         {
   658             /* need to borrow from the next byte */
   659             m_Array[i] = maxValue;
   660 
   661             /* remaining characters must use all bits */
   662             maxValue = UCHAR_MAX;
   663             one = 1;
   664         }
   665     }
   666 
   667     return *this;
   668 }
   669 
   670 /***************************************************************************
   671 *   Method     : operator-- (postfix)
   672 *   Description: overload of the -- operator.  Decrements the contents of
   673 *                a bit array.  Underflows cause rollover.
   674 *   Parameters : dumy - needed for postfix decrement
   675 *   Effects    : Bit array contents are decremented
   676 *   Returned   : None
   677 ***************************************************************************/
   678 BitArray& BitArray::operator--(int dummy)
   679 {
   680     --(*this);
   681     return *this;
   682 }
   683 
   684 /***************************************************************************
   685 *   Method     : operator=
   686 *   Description: overload of the = operator.  Copies source contents into
   687 *                this bit array.
   688 *   Parameters : src - Source bit array
   689 *   Effects    : Source bit array contents are copied into this array
   690 *   Returned   : Reference to this array after copy
   691 ***************************************************************************/
   692 BitArray& BitArray::operator=(const BitArray &src)
   693 {
   694     if (*this == src)
   695     {
   696         /* don't do anything for a self assignment */
   697         return *this;
   698     }
   699 
   700     if (m_NumBits != src.m_NumBits)
   701     {
   702         /* don't do assignment with different array sizes */
   703         return *this;
   704     }
   705 
   706     if ((m_NumBits == 0) || (src.m_NumBits == 0))
   707     {
   708         /* don't do assignment with unallocated array */
   709         return *this;
   710     }
   711 
   712     /* copy bits from source */
   713     int size;
   714     size = BITS_TO_CHARS(m_NumBits);
   715 
   716     copy(src.m_Array, &src.m_Array[size], this->m_Array);
   717     return *this;
   718 }
   719 
   720 /***************************************************************************
   721 *   Method     : operator&=
   722 *   Description: overload of the &= operator.  Performs a bitwise and
   723 *                between the source array and this bit array.  This bit
   724 *                array will contain the result.
   725 *   Parameters : src - Source bit array
   726 *   Effects    : Results of bitwise and are stored in this array
   727 *   Returned   : Reference to this array after and
   728 ***************************************************************************/
   729 BitArray& BitArray::operator&=(const BitArray &src)
   730 {
   731     int size;
   732 
   733     size = BITS_TO_CHARS(m_NumBits);
   734 
   735     if (m_NumBits != src.m_NumBits)
   736     {
   737         /* don't do assignment with different array sizes */
   738         return *this;
   739     }
   740 
   741     /* AND array one unsigned char at a time */
   742     for(int i = 0; i < size; i++)
   743     {
   744         m_Array[i] = m_Array[i] & src.m_Array[i];
   745     }
   746 
   747     return *this;
   748 }
   749 
   750 /***************************************************************************
   751 *   Method     : operator^=
   752 *   Description: overload of the ^= operator.  Performs a bitwise xor
   753 *                between the source array and this bit array.  This bit
   754 *                array will contain the result.
   755 *   Parameters : src - Source bit array
   756 *   Effects    : Results of bitwise xor are stored in this array
   757 *   Returned   : Reference to this array after xor
   758 ***************************************************************************/
   759 BitArray& BitArray::operator^=(const BitArray &src)
   760 {
   761     int size;
   762 
   763     size = BITS_TO_CHARS(m_NumBits);
   764 
   765     if (m_NumBits != src.m_NumBits)
   766     {
   767         /* don't do assignment with different array sizes */
   768         return *this;
   769     }
   770 
   771     /* XOR array one unsigned char at a time */
   772     for(int i = 0; i < size; i++)
   773     {
   774         m_Array[i] = m_Array[i] ^ src.m_Array[i];
   775     }
   776 
   777     return *this;
   778 }
   779 
   780 /***************************************************************************
   781 *   Method     : operator|=
   782 *   Description: overload of the |= operator.  Performs a bitwise or
   783 *                between the source array and this bit array.  This bit
   784 *                array will contain the result.
   785 *   Parameters : src - Source bit array
   786 *   Effects    : Results of bitwise or are stored in this array
   787 *   Returned   : Reference to this array after or
   788 ***************************************************************************/
   789 BitArray& BitArray::operator|=(const BitArray &src)
   790 {
   791     int size;
   792 
   793     size = BITS_TO_CHARS(m_NumBits);
   794 
   795     if (m_NumBits != src.m_NumBits)
   796     {
   797         /* don't do assignment with different array sizes */
   798         return *this;
   799     }
   800 
   801     /* OR array one unsigned char at a time */
   802     for(int i = 0; i < size; i++)
   803     {
   804         m_Array[i] = m_Array[i] | src.m_Array[i];
   805     }
   806 
   807     return *this;
   808 }
   809 
   810 /***************************************************************************
   811 *   Method     : Not
   812 *   Description: Negates all non-spare bits in bit array.
   813 *   Parameters : None
   814 *   Effects    : Contents of bit array are negated.  Any spare bits are
   815 *                left at 0.
   816 *   Returned   : Reference to this array after not
   817 ***************************************************************************/
   818 BitArray& BitArray::Not(void)
   819 {
   820     int bits;
   821     unsigned char mask;
   822     int size;
   823 
   824     size = BITS_TO_CHARS(m_NumBits);
   825 
   826     if (m_NumBits == 0)
   827     {
   828         /* don't do not with unallocated array */
   829         return *this;
   830     }
   831 
   832     /* NOT array one unsigned char at a time */
   833     for(int i = 0; i < size; i++)
   834     {
   835         m_Array[i] = ~m_Array[i];
   836     }
   837 
   838     /* zero any spare bits so increment and decrement are consistent */
   839     bits = m_NumBits % CHAR_BIT;
   840     if (bits != 0)
   841     {
   842         mask = UCHAR_MAX << (CHAR_BIT - bits);
   843         m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
   844     }
   845 
   846     return *this;
   847 }
   848 
   849 /***************************************************************************
   850 *   Method     : operator<<=
   851 *   Description: overload of the <<= operator.  Performs a left shift on
   852 *                this bit array.  This bit array will contain the result.
   853 *   Parameters : shifts - number of bit positions to shift
   854 *   Effects    : Results of the shifts are stored in this array
   855 *   Returned   : Reference to this array after shift
   856 ***************************************************************************/
   857 BitArray& BitArray::operator<<=(const unsigned int shifts)
   858 {
   859     int i;
   860     int chars = shifts / CHAR_BIT; /* number of whole byte shifts */
   861 
   862     if (shifts >= m_NumBits)
   863     {
   864         /* all bits have been shifted off */
   865         this->ClearAll();
   866         return *this;
   867     }
   868 
   869     /* first handle big jumps of bytes */
   870     if (chars > 0)
   871     {
   872         int size;
   873 
   874         size = BITS_TO_CHARS(m_NumBits);
   875 
   876         for (i = 0; (i + chars) < size; i++)
   877         {
   878             m_Array[i] = m_Array[i + chars];
   879         }
   880 
   881         /* now zero out new bytes on the right */
   882         for (i = size; chars > 0; chars--)
   883         {
   884             m_Array[i - chars] = 0;
   885         }
   886     }
   887 
   888     /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
   889     for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
   890     {
   891         for (unsigned int j = 0; j < BIT_CHAR(m_NumBits - 1); j++)
   892         {
   893             m_Array[j] <<= 1;
   894 
   895             /* handle shifts across byte bounds */
   896             if (m_Array[j + 1] & MS_BIT)
   897             {
   898                 m_Array[j] |= 0x01;
   899             }
   900         }
   901 
   902         m_Array[BIT_CHAR(m_NumBits - 1)] <<= 1;
   903     }
   904 
   905     return *this;
   906 }
   907 
   908 /***************************************************************************
   909 *   Method     : operator>>=
   910 *   Description: overload of the >>= operator.  Performs a right shift on
   911 *                this bit array.  This bit array will contain the result.
   912 *   Parameters : shifts - number of bit positions to shift
   913 *   Effects    : Results of the shifts are stored in this array
   914 *   Returned   : Reference to this array after shift
   915 ***************************************************************************/
   916 BitArray& BitArray::operator>>=(const unsigned int shifts)
   917 {
   918     int i;
   919     char mask;
   920     int chars = shifts / CHAR_BIT;  /* number of whole byte shifts */
   921 
   922     if (shifts >= m_NumBits)
   923     {
   924         /* all bits have been shifted off */
   925         this->ClearAll();
   926         return *this;
   927     }
   928 
   929     /* first handle big jumps of bytes */
   930     if (chars > 0)
   931     {
   932         for (i = BIT_CHAR(m_NumBits - 1); (i - chars) >= 0; i--)
   933         {
   934             m_Array[i] = m_Array[i - chars];
   935         }
   936 
   937         /* now zero out new bytes on the right */
   938         for (; chars > 0; chars--)
   939         {
   940             m_Array[chars - 1] = 0;
   941         }
   942     }
   943 
   944     /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
   945     for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
   946     {
   947         for (unsigned int j = BIT_CHAR(m_NumBits - 1); j > 0; j--)
   948         {
   949             m_Array[j] >>= 1;
   950 
   951             /* handle shifts across byte bounds */
   952             if (m_Array[j - 1] & 0x01)
   953             {
   954                 m_Array[j] |= MS_BIT;
   955             }
   956         }
   957 
   958         m_Array[0] >>= 1;
   959     }
   960 
   961     /***********************************************************************
   962     * zero any spare bits that are shifted beyond the end of the bit array
   963     * so that increment and decrement are consistent.
   964     ***********************************************************************/
   965     i = m_NumBits % CHAR_BIT;
   966     if (i != 0)
   967     {
   968         mask = UCHAR_MAX << (CHAR_BIT - i);
   969         m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
   970     }
   971 
   972     return *this;
   973 }
   974 
   975 /***************************************************************************
   976 *   Method     : bit_array_index_c - constructor
   977 *   Description: This is the bit_array_index_c constructor.  It stores a
   978 *                pointer to the bit array and the bit index.
   979 *   Parameters : array - pointer to bit array
   980 *                index - index of bit in array
   981 *   Effects    : Pointer to bit array and bit index are stored.
   982 *   Returned   : None
   983 ***************************************************************************/
   984 BitArrayIndex::BitArrayIndex(BitArray *array,
   985     const unsigned int index)
   986 {
   987     m_BitArray = array;
   988     m_Index = index;
   989 }
   990 
   991 /***************************************************************************
   992 *   Method     : operator=
   993 *   Description: overload of the = operator.  Sets the bit array bit to
   994 *                the value of src.
   995 *   Parameters : src - bit value
   996 *   Effects    : Bit pointed to by this object is set to the value of
   997 *                source.
   998 *   Returned   : None
   999 ***************************************************************************/
  1000 void BitArrayIndex::operator=(const bool src)
  1001 {
  1002     if (m_BitArray == NULL)
  1003     {
  1004         return;     /* no array */
  1005     }
  1006 
  1007     if (m_BitArray->SizeInBits() <= m_Index)
  1008     {
  1009         return;     /* index is out of bounds */
  1010     }
  1011 
  1012     if (src)
  1013     {
  1014         m_BitArray->SetBit(m_Index);
  1015     }
  1016     else
  1017     {
  1018         m_BitArray->ClearBit(m_Index);
  1019     }
  1020 }