src/BitArray.cpp
author sl
Tue, 27 May 2014 17:49:33 +0200
changeset 27 ee1305f3a6bf
parent 25 233a997193b8
permissions -rw-r--r--
Experimenting with our bitmap to bitarray convertion.
     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 {
   129     m_SizeInBytes = BITS_TO_CHARS(numBits);
   130 
   131 
   132     /* allocate space for bit array */
   133     m_Array = new unsigned char[m_SizeInBytes];
   134 
   135     /* set all bits to 0 */
   136     fill_n(m_Array, m_SizeInBytes, 0);
   137 }
   138 
   139 /***************************************************************************
   140 *   Method     : bit_array_c - constructor
   141 *   Description: This is the bit_array_c constructor.  It copies the
   142 *                for contents of a vector of unsigned char into the
   143 *                bitarray.
   144 *   Parameters : vect - vector to be copied
   145 *                numBits - number of bits in the array
   146 *   Effects    : Allocates vectory for array bits
   147 *   Returned   : None
   148 ***************************************************************************/
   149 BitArray::BitArray(unsigned char *array, const int numBits):
   150     m_NumBits(numBits),
   151     m_Array(array)
   152 {
   153 }
   154 
   155 /***************************************************************************
   156 *   Method     : ~bit_array_c - destructor
   157 *   Description: This is the bit_array_c destructor.  At this point it's
   158 *                just a place holder.
   159 *   Parameters : None
   160 *   Effects    : None
   161 *   Returned   : None
   162 ***************************************************************************/
   163 BitArray::~BitArray(void)
   164 {
   165     delete[] m_Array;
   166 }
   167 
   168 /***************************************************************************
   169 *   Method     : Dump
   170 *   Description: This method dumps the conents of a bit array to stdout.
   171 *                The format of the dump is a series of bytes represented in
   172 *                hexadecimal.
   173 *   Parameters : outStream - stream to write to
   174 *   Effects    : Array contents are dumped to stdout
   175 *   Returned   : None
   176 ***************************************************************************/
   177 void BitArray::Dump(std::ostream &outStream)
   178 {
   179     int size;
   180 
   181     size = BITS_TO_CHARS(m_NumBits);
   182 
   183     outStream.width(2);
   184     outStream.fill('0');
   185     outStream << uppercase << hex << (int)(m_Array[0]);  /* first byte */
   186 
   187     for (int i = 1; i < size; i++)
   188     {
   189         /* remaining bytes with a leading space */
   190         outStream << " ";
   191         outStream.width(2);
   192         outStream.fill('0');
   193         outStream << (int)(m_Array[i]);
   194     }
   195 
   196     outStream << dec;
   197 }
   198 
   199 /***************************************************************************
   200 *   Method     : SetAll
   201 *   Description: This method sets every bit in the bit array to 1.  This
   202 *                method uses UCHAR_MAX to determine what it means to set
   203 *                all bits in an unsigned char, so it is crucial that the
   204 *                machine implementation of unsigned char utilizes all of
   205 *                the bits in the memory allocated for an unsigned char.
   206 *   Parameters : None
   207 *   Effects    : Each of the bits used in the bit array are set to 1.
   208 *                Unused (spare) bits are set to 0.
   209 *   Returned   : None
   210 ***************************************************************************/
   211 void BitArray::SetAll(void)
   212 {
   213     int bits, size;
   214     unsigned char mask;
   215 
   216     size = BITS_TO_CHARS(m_NumBits);
   217 
   218     /* set bits in all bytes to 1 */
   219     fill_n(m_Array, size, UCHAR_MAX);
   220 
   221     /* zero any spare bits so increment and decrement are consistent */
   222     bits = m_NumBits % CHAR_BIT;
   223     if (bits != 0)
   224     {
   225         mask = UCHAR_MAX << (CHAR_BIT - bits);
   226         m_Array[BIT_CHAR(m_NumBits - 1)] = mask;
   227     }
   228 }
   229 
   230 /***************************************************************************
   231 *   Method     : ClearAll
   232 *   Description: This method sets every bit in the bit array to 0.
   233 *   Parameters : None
   234 *   Effects    : Each of the bits in the bit array are set to 0.
   235 *   Returned   : None
   236 ***************************************************************************/
   237 void BitArray::ClearAll(void)
   238 {
   239     int size;
   240 
   241     size = BITS_TO_CHARS(m_NumBits);
   242 
   243     /* set bits in all bytes to 0 */
   244     fill_n(m_Array, size, 0);
   245 }
   246 
   247 /***************************************************************************
   248 *   Method     : SetBit
   249 *   Description: This method sets a bit in the bit array to 1.
   250 *   Parameters : bit - the number of the bit to set
   251 *   Effects    : The specified bit will be set to 1.
   252 *   Returned   : None
   253 ***************************************************************************/
   254 void BitArray::SetBit(const unsigned int bit)
   255 {
   256     if (m_NumBits <= bit)
   257     {
   258         return;         /* bit out of range */
   259     }
   260 
   261     m_Array[BIT_CHAR(bit)] |= BIT_IN_CHAR(bit);
   262 }
   263 
   264 /**
   265 */
   266 void BitArray::SetBitValue(const unsigned int bit, bool aValue)
   267 	{
   268 	if (aValue)
   269 		{
   270 		SetBit(bit);
   271 		}
   272 	else
   273 		{
   274 		ClearBit(bit);
   275 		}
   276 	}
   277 
   278 /***************************************************************************
   279 *   Method     : ClearBit
   280 *   Description: This method sets a bit in the bit array to 0.
   281 *   Parameters : bit - the number of the bit to clear
   282 *   Effects    : The specified bit will be set to 0.
   283 *   Returned   : None
   284 ***************************************************************************/
   285 void BitArray::ClearBit(const unsigned int bit)
   286 {
   287     unsigned char mask;
   288 
   289     if (m_NumBits <= bit)
   290     {
   291         return;         /* bit out of range */
   292     }
   293 
   294     /* create a mask to zero out desired bit */
   295     mask =  BIT_IN_CHAR(bit);
   296     mask = ~mask;
   297 
   298     m_Array[BIT_CHAR(bit)] &= mask;
   299 }
   300 
   301 /***************************************************************************
   302 *   Method     : operator()
   303 *   Description: Overload of the () operator.  This method approximates
   304 *                array indices used for assignment.  It returns a
   305 *                bit_array_index_c which includes an = method used to
   306 *                set bit values.
   307 *   Parameters : bit - index of array bit
   308 *   Effects    : None
   309 *   Returned   : bit_array_index_c (pointer to bit)
   310 ***************************************************************************/
   311 BitArrayIndex BitArray::operator()(const unsigned int bit)
   312 {
   313     BitArrayIndex result(this, bit);
   314 
   315     return result;
   316 }
   317 
   318 /***************************************************************************
   319 *   Method     : operator[]
   320 *   Description: Overload of the [] operator.  This method returns the
   321 *                value of a bit in the bit array.
   322 *   Parameters : bit - index of array bit
   323 *   Effects    : None
   324 *   Returned   : The value of the specified bit.
   325 ***************************************************************************/
   326 bool BitArray::operator[](const unsigned int bit) const
   327 {
   328     return((m_Array[BIT_CHAR(bit)] & BIT_IN_CHAR(bit)) != 0);
   329 }
   330 
   331 /***************************************************************************
   332 *   Method     : operator==
   333 *   Description: overload of the == operator
   334 *   Parameters : other - bit array to compare
   335 *   Effects    : None
   336 *   Returned   : True if this == other.  Otherwise false.
   337 ***************************************************************************/
   338 bool BitArray::operator==(const BitArray &other) const
   339 {
   340     if (m_NumBits != other.m_NumBits)
   341     {
   342         /* unequal sizes */
   343         return false;
   344     }
   345 
   346     return (this->m_Array == other.m_Array);
   347 }
   348 
   349 /***************************************************************************
   350 *   Method     : operator!=
   351 *   Description: overload of the != operator
   352 *   Parameters : other - bit array to compare
   353 *   Effects    : None
   354 *   Returned   : True if this != other.  Otherwise false.
   355 ***************************************************************************/
   356 bool BitArray::operator!=(const BitArray &other) const
   357 {
   358     if (m_NumBits != other.m_NumBits)
   359     {
   360         /* unequal sizes */
   361         return true;
   362     }
   363 
   364     return (this->m_Array != other.m_Array);
   365 }
   366 
   367 /***************************************************************************
   368 *   Method     : operator<
   369 *   Description: overload of the < operator
   370 *   Parameters : other - bit array to compare
   371 *   Effects    : None
   372 *   Returned   : True if this < other.  Otherwise false.
   373 ***************************************************************************/
   374 bool BitArray::operator<(const BitArray &other) const
   375 {
   376     if (m_NumBits != other.m_NumBits)
   377     {
   378         /* unequal sizes */
   379         return false;
   380     }
   381 
   382     return (this->m_Array < other.m_Array);
   383 }
   384 
   385 /***************************************************************************
   386 *   Method     : operator<=
   387 *   Description: overload of the <= operator
   388 *   Parameters : other - bit array to compare
   389 *   Effects    : None
   390 *   Returned   : True if this <= other.  Otherwise false.
   391 ***************************************************************************/
   392 bool BitArray::operator<=(const BitArray &other) const
   393 {
   394     if (m_NumBits != other.m_NumBits)
   395     {
   396         /* unequal sizes */
   397         return false;
   398     }
   399 
   400     return (this->m_Array <= other.m_Array);
   401 }
   402 
   403 /***************************************************************************
   404 *   Method     : operator>
   405 *   Description: overload of the > operator
   406 *   Parameters : other - bit array to compare
   407 *   Effects    : None
   408 *   Returned   : True if this > other.  Otherwise false.
   409 ***************************************************************************/
   410 bool BitArray::operator>(const BitArray &other) const
   411 {
   412     if (m_NumBits != other.m_NumBits)
   413     {
   414         /* unequal sizes */
   415         return false;
   416     }
   417 
   418     return (this->m_Array > other.m_Array);
   419 }
   420 
   421 /***************************************************************************
   422 *   Method     : operator>=
   423 *   Description: overload of the >= operator
   424 *   Parameters : other - bit array to compare
   425 *   Effects    : None
   426 *   Returned   : True if this >= other.  Otherwise false.
   427 ***************************************************************************/
   428 bool BitArray::operator>=(const BitArray &other) const
   429 {
   430     if (m_NumBits != other.m_NumBits)
   431     {
   432         /* unequal sizes */
   433         return false;
   434     }
   435 
   436     return (this->m_Array >= other.m_Array);
   437 }
   438 
   439 /***************************************************************************
   440 *   Method     : operator~
   441 *   Description: overload of the ~ operator.  Negates all non-spare bits in
   442 *                bit array
   443 *   Parameters : None
   444 *   Effects    : None
   445 *   Returned   : value of this after bitwise not
   446 ***************************************************************************/
   447 BitArray BitArray::operator~(void) const
   448 {
   449     BitArray result(this->m_NumBits);
   450     result = *this;
   451     result.Not();
   452 
   453     return result;
   454 }
   455 
   456 /***************************************************************************
   457 *   Method     : operator&
   458 *   Description: overload of the & operator.  Performs a bitwise and
   459 *                between the source array and this bit array.
   460 *   Parameters : other - bit array on righthand side of &
   461 *   Effects    : None
   462 *   Returned   : value of bitwise and of this and other.
   463 ***************************************************************************/
   464 BitArray BitArray::operator&(const BitArray &other) const
   465 {
   466     BitArray result(this->m_NumBits);
   467     result = *this;
   468     result &= other;
   469 
   470     return result;
   471 }
   472 
   473 
   474 /***************************************************************************
   475 *   Method     : operator^
   476 *   Description: overload of the ^ operator.  Performs a bitwise xor
   477 *                between the source array and this bit array.
   478 *   Parameters : other - bit array on righthand side of ^
   479 *   Effects    : None
   480 *   Returned   : value of bitwise xor of this and other.
   481 ***************************************************************************/
   482 BitArray BitArray::operator^(const BitArray &other) const
   483 {
   484     BitArray result(this->m_NumBits);
   485     result = *this;
   486     result ^= other;
   487 
   488     return result;
   489 }
   490 
   491 /***************************************************************************
   492 *   Method     : operator|
   493 *   Description: overload of the | operator.  Performs a bitwise or
   494 *                between the source array and this bit array.
   495 *   Parameters : other - bit array on righthand side of |
   496 *   Effects    : None
   497 *   Returned   : value of bitwise or of this and other.
   498 ***************************************************************************/
   499 BitArray BitArray::operator|(const BitArray &other) const
   500 {
   501     BitArray result(this->m_NumBits);
   502     result = *this;
   503     result |= other;
   504 
   505     return result;
   506 }
   507 
   508 /***************************************************************************
   509 *   Method     : operator<<
   510 *   Description: overload of the << operator.  Performs a bitwise left
   511 *                shift of this bit array.
   512 *   Parameters : count - the number of bits to shift left
   513 *   Effects    : None
   514 *   Returned   : result of bitwise left shift
   515 ***************************************************************************/
   516 BitArray BitArray::operator<<(const unsigned int count) const
   517 {
   518     BitArray result(this->m_NumBits);
   519     result = *this;
   520     result <<= count;
   521 
   522     return result;
   523 }
   524 
   525 /***************************************************************************
   526 *   Method     : operator>>
   527 *   Description: overload of the >> operator.  Performs a bitwise right
   528 *                shift of this bit array.
   529 *   Parameters : count - the number of bits to shift right
   530 *   Effects    : None
   531 *   Returned   : result of bitwise right shift
   532 ***************************************************************************/
   533 BitArray BitArray::operator>>(const unsigned int count) const
   534 {
   535     BitArray result(this->m_NumBits);
   536     result = *this;
   537     result >>= count;
   538 
   539     return result;
   540 }
   541 
   542 /***************************************************************************
   543 *   Method     : operator++ (prefix)
   544 *   Description: overload of the ++ operator.  Increments the contents of
   545 *                a bit array.  Overflows cause rollover.
   546 *   Parameters : None
   547 *   Effects    : Bit array contents are incremented
   548 *   Returned   : Reference to this array after increment
   549 ***************************************************************************/
   550 BitArray& BitArray::operator++(void)
   551 {
   552     int i;
   553     unsigned char maxValue;     /* maximum value for current char */
   554     unsigned char one;          /* least significant bit in current char */
   555 
   556     if (m_NumBits == 0)
   557     {
   558         return *this;           /* nothing to increment */
   559     }
   560 
   561     /* handle arrays that don't use every bit in the last character */
   562     i = (m_NumBits % CHAR_BIT);
   563     if (i != 0)
   564     {
   565         maxValue = UCHAR_MAX << (CHAR_BIT - i);
   566         one = 1 << (CHAR_BIT - i);
   567     }
   568     else
   569     {
   570         maxValue = UCHAR_MAX;
   571         one = 1;
   572     }
   573 
   574     for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
   575     {
   576         if (m_Array[i] != maxValue)
   577         {
   578             m_Array[i] = m_Array[i] + one;
   579             return *this;
   580         }
   581         else
   582         {
   583             /* need to carry to next byte */
   584             m_Array[i] = 0;
   585 
   586             /* remaining characters must use all bits */
   587             maxValue = UCHAR_MAX;
   588             one = 1;
   589         }
   590     }
   591 
   592     return *this;
   593 }
   594 
   595 /***************************************************************************
   596 *   Method     : operator++ (postfix)
   597 *   Description: overload of the ++ operator.  Increments the contents of
   598 *                a bit array.  Overflows cause rollover.
   599 *   Parameters : dumy - needed for postfix increment
   600 *   Effects    : Bit array contents are incremented
   601 *   Returned   : Reference to this array after increment
   602 ***************************************************************************/
   603 BitArray& BitArray::operator++(int dummy)
   604 {
   605     ++(*this);
   606     return *this;
   607 }
   608 
   609 /***************************************************************************
   610 *   Method     : operator-- (prefix)
   611 *   Description: overload of the -- operator.  Decrements the contents of
   612 *                a bit array.  Underflows cause rollover.
   613 *   Parameters : None
   614 *   Effects    : Bit array contents are decremented
   615 *   Returned   : None
   616 ***************************************************************************/
   617 BitArray& BitArray::operator--(void)
   618 {
   619     int i;
   620     unsigned char maxValue;     /* maximum value for current char */
   621     unsigned char one;          /* least significant bit in current char */
   622 
   623     if (m_NumBits == 0)
   624     {
   625         return *this;           /* nothing to decrement */
   626     }
   627 
   628     /* handle arrays that don't use every bit in the last character */
   629     i = (m_NumBits % CHAR_BIT);
   630     if (i != 0)
   631     {
   632         maxValue = UCHAR_MAX << (CHAR_BIT - i);
   633         one = 1 << (CHAR_BIT - i);
   634     }
   635     else
   636     {
   637         maxValue = UCHAR_MAX;
   638         one = 1;
   639     }
   640 
   641     for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--)
   642     {
   643         if (m_Array[i] >= one)
   644         {
   645             m_Array[i] = m_Array[i] - one;
   646             return *this;
   647         }
   648         else
   649         {
   650             /* need to borrow from the next byte */
   651             m_Array[i] = maxValue;
   652 
   653             /* remaining characters must use all bits */
   654             maxValue = UCHAR_MAX;
   655             one = 1;
   656         }
   657     }
   658 
   659     return *this;
   660 }
   661 
   662 /***************************************************************************
   663 *   Method     : operator-- (postfix)
   664 *   Description: overload of the -- operator.  Decrements the contents of
   665 *                a bit array.  Underflows cause rollover.
   666 *   Parameters : dumy - needed for postfix decrement
   667 *   Effects    : Bit array contents are decremented
   668 *   Returned   : None
   669 ***************************************************************************/
   670 BitArray& BitArray::operator--(int dummy)
   671 {
   672     --(*this);
   673     return *this;
   674 }
   675 
   676 /***************************************************************************
   677 *   Method     : operator=
   678 *   Description: overload of the = operator.  Copies source contents into
   679 *                this bit array.
   680 *   Parameters : src - Source bit array
   681 *   Effects    : Source bit array contents are copied into this array
   682 *   Returned   : Reference to this array after copy
   683 ***************************************************************************/
   684 BitArray& BitArray::operator=(const BitArray &src)
   685 {
   686     if (*this == src)
   687     {
   688         /* don't do anything for a self assignment */
   689         return *this;
   690     }
   691 
   692     if (m_NumBits != src.m_NumBits)
   693     {
   694         /* don't do assignment with different array sizes */
   695         return *this;
   696     }
   697 
   698     if ((m_NumBits == 0) || (src.m_NumBits == 0))
   699     {
   700         /* don't do assignment with unallocated array */
   701         return *this;
   702     }
   703 
   704     /* copy bits from source */
   705     int size;
   706     size = BITS_TO_CHARS(m_NumBits);
   707 
   708     copy(src.m_Array, &src.m_Array[size], this->m_Array);
   709     return *this;
   710 }
   711 
   712 /***************************************************************************
   713 *   Method     : operator&=
   714 *   Description: overload of the &= operator.  Performs a bitwise and
   715 *                between the source array and this bit array.  This bit
   716 *                array will contain the result.
   717 *   Parameters : src - Source bit array
   718 *   Effects    : Results of bitwise and are stored in this array
   719 *   Returned   : Reference to this array after and
   720 ***************************************************************************/
   721 BitArray& BitArray::operator&=(const BitArray &src)
   722 {
   723     int size;
   724 
   725     size = BITS_TO_CHARS(m_NumBits);
   726 
   727     if (m_NumBits != src.m_NumBits)
   728     {
   729         /* don't do assignment with different array sizes */
   730         return *this;
   731     }
   732 
   733     /* AND array one unsigned char at a time */
   734     for(int i = 0; i < size; i++)
   735     {
   736         m_Array[i] = m_Array[i] & src.m_Array[i];
   737     }
   738 
   739     return *this;
   740 }
   741 
   742 /***************************************************************************
   743 *   Method     : operator^=
   744 *   Description: overload of the ^= operator.  Performs a bitwise xor
   745 *                between the source array and this bit array.  This bit
   746 *                array will contain the result.
   747 *   Parameters : src - Source bit array
   748 *   Effects    : Results of bitwise xor are stored in this array
   749 *   Returned   : Reference to this array after xor
   750 ***************************************************************************/
   751 BitArray& BitArray::operator^=(const BitArray &src)
   752 {
   753     int size;
   754 
   755     size = BITS_TO_CHARS(m_NumBits);
   756 
   757     if (m_NumBits != src.m_NumBits)
   758     {
   759         /* don't do assignment with different array sizes */
   760         return *this;
   761     }
   762 
   763     /* XOR array one unsigned char at a time */
   764     for(int i = 0; i < size; i++)
   765     {
   766         m_Array[i] = m_Array[i] ^ src.m_Array[i];
   767     }
   768 
   769     return *this;
   770 }
   771 
   772 /***************************************************************************
   773 *   Method     : operator|=
   774 *   Description: overload of the |= operator.  Performs a bitwise or
   775 *                between the source array and this bit array.  This bit
   776 *                array will contain the result.
   777 *   Parameters : src - Source bit array
   778 *   Effects    : Results of bitwise or are stored in this array
   779 *   Returned   : Reference to this array after or
   780 ***************************************************************************/
   781 BitArray& BitArray::operator|=(const BitArray &src)
   782 {
   783     int size;
   784 
   785     size = BITS_TO_CHARS(m_NumBits);
   786 
   787     if (m_NumBits != src.m_NumBits)
   788     {
   789         /* don't do assignment with different array sizes */
   790         return *this;
   791     }
   792 
   793     /* OR array one unsigned char at a time */
   794     for(int i = 0; i < size; i++)
   795     {
   796         m_Array[i] = m_Array[i] | src.m_Array[i];
   797     }
   798 
   799     return *this;
   800 }
   801 
   802 /***************************************************************************
   803 *   Method     : Not
   804 *   Description: Negates all non-spare bits in bit array.
   805 *   Parameters : None
   806 *   Effects    : Contents of bit array are negated.  Any spare bits are
   807 *                left at 0.
   808 *   Returned   : Reference to this array after not
   809 ***************************************************************************/
   810 BitArray& BitArray::Not(void)
   811 {
   812     int bits;
   813     unsigned char mask;
   814     int size;
   815 
   816     size = BITS_TO_CHARS(m_NumBits);
   817 
   818     if (m_NumBits == 0)
   819     {
   820         /* don't do not with unallocated array */
   821         return *this;
   822     }
   823 
   824     /* NOT array one unsigned char at a time */
   825     for(int i = 0; i < size; i++)
   826     {
   827         m_Array[i] = ~m_Array[i];
   828     }
   829 
   830     /* zero any spare bits so increment and decrement are consistent */
   831     bits = m_NumBits % CHAR_BIT;
   832     if (bits != 0)
   833     {
   834         mask = UCHAR_MAX << (CHAR_BIT - bits);
   835         m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
   836     }
   837 
   838     return *this;
   839 }
   840 
   841 /***************************************************************************
   842 *   Method     : operator<<=
   843 *   Description: overload of the <<= operator.  Performs a left shift on
   844 *                this bit array.  This bit array will contain the result.
   845 *   Parameters : shifts - number of bit positions to shift
   846 *   Effects    : Results of the shifts are stored in this array
   847 *   Returned   : Reference to this array after shift
   848 ***************************************************************************/
   849 BitArray& BitArray::operator<<=(const unsigned int shifts)
   850 {
   851     int i;
   852     int chars = shifts / CHAR_BIT; /* number of whole byte shifts */
   853 
   854     if (shifts >= m_NumBits)
   855     {
   856         /* all bits have been shifted off */
   857         this->ClearAll();
   858         return *this;
   859     }
   860 
   861     /* first handle big jumps of bytes */
   862     if (chars > 0)
   863     {
   864         int size;
   865 
   866         size = BITS_TO_CHARS(m_NumBits);
   867 
   868         for (i = 0; (i + chars) < size; i++)
   869         {
   870             m_Array[i] = m_Array[i + chars];
   871         }
   872 
   873         /* now zero out new bytes on the right */
   874         for (i = size; chars > 0; chars--)
   875         {
   876             m_Array[i - chars] = 0;
   877         }
   878     }
   879 
   880     /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
   881     for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
   882     {
   883         for (unsigned int j = 0; j < BIT_CHAR(m_NumBits - 1); j++)
   884         {
   885             m_Array[j] <<= 1;
   886 
   887             /* handle shifts across byte bounds */
   888             if (m_Array[j + 1] & MS_BIT)
   889             {
   890                 m_Array[j] |= 0x01;
   891             }
   892         }
   893 
   894         m_Array[BIT_CHAR(m_NumBits - 1)] <<= 1;
   895     }
   896 
   897     return *this;
   898 }
   899 
   900 /***************************************************************************
   901 *   Method     : operator>>=
   902 *   Description: overload of the >>= operator.  Performs a right shift on
   903 *                this bit array.  This bit array will contain the result.
   904 *   Parameters : shifts - number of bit positions to shift
   905 *   Effects    : Results of the shifts are stored in this array
   906 *   Returned   : Reference to this array after shift
   907 ***************************************************************************/
   908 BitArray& BitArray::operator>>=(const unsigned int shifts)
   909 {
   910     int i;
   911     char mask;
   912     int chars = shifts / CHAR_BIT;  /* number of whole byte shifts */
   913 
   914     if (shifts >= m_NumBits)
   915     {
   916         /* all bits have been shifted off */
   917         this->ClearAll();
   918         return *this;
   919     }
   920 
   921     /* first handle big jumps of bytes */
   922     if (chars > 0)
   923     {
   924         for (i = BIT_CHAR(m_NumBits - 1); (i - chars) >= 0; i--)
   925         {
   926             m_Array[i] = m_Array[i - chars];
   927         }
   928 
   929         /* now zero out new bytes on the right */
   930         for (; chars > 0; chars--)
   931         {
   932             m_Array[chars - 1] = 0;
   933         }
   934     }
   935 
   936     /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */
   937     for (i = 0; i < (int)(shifts % CHAR_BIT); i++)
   938     {
   939         for (unsigned int j = BIT_CHAR(m_NumBits - 1); j > 0; j--)
   940         {
   941             m_Array[j] >>= 1;
   942 
   943             /* handle shifts across byte bounds */
   944             if (m_Array[j - 1] & 0x01)
   945             {
   946                 m_Array[j] |= MS_BIT;
   947             }
   948         }
   949 
   950         m_Array[0] >>= 1;
   951     }
   952 
   953     /***********************************************************************
   954     * zero any spare bits that are shifted beyond the end of the bit array
   955     * so that increment and decrement are consistent.
   956     ***********************************************************************/
   957     i = m_NumBits % CHAR_BIT;
   958     if (i != 0)
   959     {
   960         mask = UCHAR_MAX << (CHAR_BIT - i);
   961         m_Array[BIT_CHAR(m_NumBits - 1)] &= mask;
   962     }
   963 
   964     return *this;
   965 }
   966 
   967 /***************************************************************************
   968 *   Method     : bit_array_index_c - constructor
   969 *   Description: This is the bit_array_index_c constructor.  It stores a
   970 *                pointer to the bit array and the bit index.
   971 *   Parameters : array - pointer to bit array
   972 *                index - index of bit in array
   973 *   Effects    : Pointer to bit array and bit index are stored.
   974 *   Returned   : None
   975 ***************************************************************************/
   976 BitArrayIndex::BitArrayIndex(BitArray *array,
   977     const unsigned int index)
   978 {
   979     m_BitArray = array;
   980     m_Index = index;
   981 }
   982 
   983 /***************************************************************************
   984 *   Method     : operator=
   985 *   Description: overload of the = operator.  Sets the bit array bit to
   986 *                the value of src.
   987 *   Parameters : src - bit value
   988 *   Effects    : Bit pointed to by this object is set to the value of
   989 *                source.
   990 *   Returned   : None
   991 ***************************************************************************/
   992 void BitArrayIndex::operator=(const bool src)
   993 {
   994     if (m_BitArray == NULL)
   995     {
   996         return;     /* no array */
   997     }
   998 
   999     if (m_BitArray->SizeInBits() <= m_Index)
  1000     {
  1001         return;     /* index is out of bounds */
  1002     }
  1003 
  1004     if (src)
  1005     {
  1006         m_BitArray->SetBit(m_Index);
  1007     }
  1008     else
  1009     {
  1010         m_BitArray->ClearBit(m_Index);
  1011     }
  1012 }