sl@25: /*************************************************************************** sl@25: * Arrays of Arbitrary Bit Length sl@25: * sl@25: * File : bitarray.cpp sl@25: * Purpose : Provides object with methods for creation and manipulation of sl@25: * arbitrary length arrays of bits. sl@25: * sl@25: * Bit arrays are implemented as vectors of unsigned chars. Bit sl@25: * 0 is the MSB of char 0, and the last bit is the least sl@25: * significant (non-spare) bit of the last unsigned char. sl@25: * sl@25: * Example: array of 20 bits (0 through 19) with 8 bit unsigned sl@25: * chars requires 3 unsigned chars (0 through 2) to sl@25: * store all the bits. sl@25: * sl@25: * char 0 1 2 sl@25: * +--------+--------+--------+ sl@25: * | | | | sl@25: * +--------+--------+--------+ sl@25: * bit 01234567 8911111111111XXXX sl@25: * 012345 6789 sl@25: * sl@25: * Author : Michael Dipperstein sl@25: * Date : July 23, 2004 sl@25: * sl@25: **************************************************************************** sl@25: * HISTORY sl@25: * sl@25: * $Id: bitarray.cpp,v 1.7 2010/02/04 03:31:43 michael Exp $ sl@25: * $Log: bitarray.cpp,v $ sl@25: * Revision 1.7 2010/02/04 03:31:43 michael sl@25: * Replaced vector with an array of unsigned char. sl@25: * sl@25: * Made updates for GCC 4.4. sl@25: * sl@25: * Revision 1.5 2007/08/06 05:23:29 michael sl@25: * Updated for LGPL Version 3. sl@25: * sl@25: * All methods that don't modify object have been made sl@25: * const to increase functionality of const bit_array_c. sl@25: * sl@25: * All assignment operators return a reference to the object being assigned a value so that operator chaining will work. sl@25: * sl@25: * Added >> and << operators. sl@25: * sl@25: * Revision 1.3 2006/04/30 23:34:07 michael sl@25: * Improved performance by incorporating Benjamin Schindler's sl@25: * changes to pass arguments as a reference. sl@25: * sl@25: * Revision 1.2 2004/08/05 22:16:49 michael sl@25: * Add overloads for bitwise operators returning values. sl@25: * Add a more natural looking way to set bit values. sl@25: * sl@25: * Revision 1.1.1.1 2004/08/04 13:28:20 michael sl@25: * bit_array_c sl@25: * sl@25: **************************************************************************** sl@25: * sl@25: * Bitarray: An ANSI C++ class for manipulating arbitrary length bit arrays sl@25: * Copyright (C) 2004, 2006-2007, 2010 by sl@25: * Michael Dipperstein (mdipper@alumni.engr.ucsb.edu) sl@25: * sl@25: * This file is part of the bit array library. sl@25: * sl@25: * The bit array library is free software; you can redistribute it and/or sl@25: * modify it under the terms of the GNU Lesser General Public License as sl@25: * published by the Free Software Foundation; either version 3 of the sl@25: * License, or (at your option) any later version. sl@25: * sl@25: * The bit array library is distributed in the hope that it will be useful, sl@25: * but WITHOUT ANY WARRANTY; without even the implied warranty of sl@25: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser sl@25: * General Public License for more details. sl@25: * sl@25: * You should have received a copy of the GNU Lesser General Public License sl@25: * along with this program. If not, see . sl@25: * sl@25: ***************************************************************************/ sl@25: sl@25: /*************************************************************************** sl@25: * INCLUDED FILES sl@25: ***************************************************************************/ sl@25: #include sl@25: #include sl@25: #include "bitarray.h" sl@25: sl@25: using namespace std; sl@25: sl@25: /*************************************************************************** sl@25: * MACROS sl@25: ***************************************************************************/ sl@25: sl@25: /* make CHAR_BIT 8 if it's not defined in limits.h */ sl@25: #ifndef CHAR_BIT sl@25: #warning CHAR_BIT not defined. Assuming 8 bits. sl@25: #define CHAR_BIT 8 sl@25: #endif sl@25: sl@25: /* position of bit within character */ sl@25: #define BIT_CHAR(bit) ((bit) / CHAR_BIT) sl@25: sl@25: /* array index for character containing bit */ sl@25: //SL: that for big endian? sl@25: //#define BIT_IN_CHAR(bit) (1 << (CHAR_BIT - 1 - ((bit) % CHAR_BIT))) sl@25: //SL: I guess we want little endian for our Futaba GP1212A01A sl@25: #define BIT_IN_CHAR(bit) (1 << (((bit) % CHAR_BIT))) sl@25: sl@25: /* number of characters required to contain number of bits */ sl@25: #define BITS_TO_CHARS(bits) ((((bits) - 1) / CHAR_BIT) + 1) sl@25: sl@25: /* most significant bit in a character */ sl@25: #define MS_BIT (1 << (CHAR_BIT - 1)) sl@25: sl@25: /*************************************************************************** sl@25: * METHODS sl@25: ***************************************************************************/ sl@25: sl@25: /*************************************************************************** sl@25: * Method : bit_array_c - constructor sl@25: * Description: This is the bit_array_c constructor. It reserves memory sl@25: * for the vector storing the array. sl@25: * Parameters : numBits - number of bits in the array sl@25: * Effects : Allocates vectory for array bits sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: BitArray::BitArray(const int numBits): sl@25: m_NumBits(numBits) sl@25: { sl@25: m_SizeInBytes = BITS_TO_CHARS(numBits); sl@25: sl@25: sl@25: /* allocate space for bit array */ sl@25: m_Array = new unsigned char[m_SizeInBytes]; sl@25: sl@25: /* set all bits to 0 */ sl@25: fill_n(m_Array, m_SizeInBytes, 0); sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : bit_array_c - constructor sl@25: * Description: This is the bit_array_c constructor. It copies the sl@25: * for contents of a vector of unsigned char into the sl@25: * bitarray. sl@25: * Parameters : vect - vector to be copied sl@25: * numBits - number of bits in the array sl@25: * Effects : Allocates vectory for array bits sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: BitArray::BitArray(unsigned char *array, const int numBits): sl@25: m_NumBits(numBits), sl@25: m_Array(array) sl@25: { sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : ~bit_array_c - destructor sl@25: * Description: This is the bit_array_c destructor. At this point it's sl@25: * just a place holder. sl@25: * Parameters : None sl@25: * Effects : None sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: BitArray::~BitArray(void) sl@25: { sl@25: delete[] m_Array; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : Dump sl@25: * Description: This method dumps the conents of a bit array to stdout. sl@25: * The format of the dump is a series of bytes represented in sl@25: * hexadecimal. sl@25: * Parameters : outStream - stream to write to sl@25: * Effects : Array contents are dumped to stdout sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: void BitArray::Dump(std::ostream &outStream) sl@25: { sl@25: int size; sl@25: sl@25: size = BITS_TO_CHARS(m_NumBits); sl@25: sl@25: outStream.width(2); sl@25: outStream.fill('0'); sl@25: outStream << uppercase << hex << (int)(m_Array[0]); /* first byte */ sl@25: sl@25: for (int i = 1; i < size; i++) sl@25: { sl@25: /* remaining bytes with a leading space */ sl@25: outStream << " "; sl@25: outStream.width(2); sl@25: outStream.fill('0'); sl@25: outStream << (int)(m_Array[i]); sl@25: } sl@25: sl@25: outStream << dec; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : SetAll sl@25: * Description: This method sets every bit in the bit array to 1. This sl@25: * method uses UCHAR_MAX to determine what it means to set sl@25: * all bits in an unsigned char, so it is crucial that the sl@25: * machine implementation of unsigned char utilizes all of sl@25: * the bits in the memory allocated for an unsigned char. sl@25: * Parameters : None sl@25: * Effects : Each of the bits used in the bit array are set to 1. sl@25: * Unused (spare) bits are set to 0. sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: void BitArray::SetAll(void) sl@25: { sl@25: int bits, size; sl@25: unsigned char mask; sl@25: sl@25: size = BITS_TO_CHARS(m_NumBits); sl@25: sl@25: /* set bits in all bytes to 1 */ sl@25: fill_n(m_Array, size, UCHAR_MAX); sl@25: sl@25: /* zero any spare bits so increment and decrement are consistent */ sl@25: bits = m_NumBits % CHAR_BIT; sl@25: if (bits != 0) sl@25: { sl@25: mask = UCHAR_MAX << (CHAR_BIT - bits); sl@25: m_Array[BIT_CHAR(m_NumBits - 1)] = mask; sl@25: } sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : ClearAll sl@25: * Description: This method sets every bit in the bit array to 0. sl@25: * Parameters : None sl@25: * Effects : Each of the bits in the bit array are set to 0. sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: void BitArray::ClearAll(void) sl@25: { sl@25: int size; sl@25: sl@25: size = BITS_TO_CHARS(m_NumBits); sl@25: sl@25: /* set bits in all bytes to 0 */ sl@25: fill_n(m_Array, size, 0); sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : SetBit sl@25: * Description: This method sets a bit in the bit array to 1. sl@25: * Parameters : bit - the number of the bit to set sl@25: * Effects : The specified bit will be set to 1. sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: void BitArray::SetBit(const unsigned int bit) sl@25: { sl@25: if (m_NumBits <= bit) sl@25: { sl@25: return; /* bit out of range */ sl@25: } sl@25: sl@25: m_Array[BIT_CHAR(bit)] |= BIT_IN_CHAR(bit); sl@25: } sl@25: sl@25: /** sl@25: */ sl@25: void BitArray::SetBitValue(const unsigned int bit, bool aValue) sl@25: { sl@25: if (aValue) sl@25: { sl@25: SetBit(bit); sl@25: } sl@25: else sl@25: { sl@25: ClearBit(bit); sl@25: } sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : ClearBit sl@25: * Description: This method sets a bit in the bit array to 0. sl@25: * Parameters : bit - the number of the bit to clear sl@25: * Effects : The specified bit will be set to 0. sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: void BitArray::ClearBit(const unsigned int bit) sl@25: { sl@25: unsigned char mask; sl@25: sl@25: if (m_NumBits <= bit) sl@25: { sl@25: return; /* bit out of range */ sl@25: } sl@25: sl@25: /* create a mask to zero out desired bit */ sl@25: mask = BIT_IN_CHAR(bit); sl@25: mask = ~mask; sl@25: sl@25: m_Array[BIT_CHAR(bit)] &= mask; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator() sl@25: * Description: Overload of the () operator. This method approximates sl@25: * array indices used for assignment. It returns a sl@25: * bit_array_index_c which includes an = method used to sl@25: * set bit values. sl@25: * Parameters : bit - index of array bit sl@25: * Effects : None sl@25: * Returned : bit_array_index_c (pointer to bit) sl@25: ***************************************************************************/ sl@25: BitArrayIndex BitArray::operator()(const unsigned int bit) sl@25: { sl@25: BitArrayIndex result(this, bit); sl@25: sl@25: return result; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator[] sl@25: * Description: Overload of the [] operator. This method returns the sl@25: * value of a bit in the bit array. sl@25: * Parameters : bit - index of array bit sl@25: * Effects : None sl@25: * Returned : The value of the specified bit. sl@25: ***************************************************************************/ sl@25: bool BitArray::operator[](const unsigned int bit) const sl@25: { sl@25: return((m_Array[BIT_CHAR(bit)] & BIT_IN_CHAR(bit)) != 0); sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator== sl@25: * Description: overload of the == operator sl@25: * Parameters : other - bit array to compare sl@25: * Effects : None sl@25: * Returned : True if this == other. Otherwise false. sl@25: ***************************************************************************/ sl@25: bool BitArray::operator==(const BitArray &other) const sl@25: { sl@25: if (m_NumBits != other.m_NumBits) sl@25: { sl@25: /* unequal sizes */ sl@25: return false; sl@25: } sl@25: sl@25: return (this->m_Array == other.m_Array); sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator!= sl@25: * Description: overload of the != operator sl@25: * Parameters : other - bit array to compare sl@25: * Effects : None sl@25: * Returned : True if this != other. Otherwise false. sl@25: ***************************************************************************/ sl@25: bool BitArray::operator!=(const BitArray &other) const sl@25: { sl@25: if (m_NumBits != other.m_NumBits) sl@25: { sl@25: /* unequal sizes */ sl@25: return true; sl@25: } sl@25: sl@25: return (this->m_Array != other.m_Array); sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator< sl@25: * Description: overload of the < operator sl@25: * Parameters : other - bit array to compare sl@25: * Effects : None sl@25: * Returned : True if this < other. Otherwise false. sl@25: ***************************************************************************/ sl@25: bool BitArray::operator<(const BitArray &other) const sl@25: { sl@25: if (m_NumBits != other.m_NumBits) sl@25: { sl@25: /* unequal sizes */ sl@25: return false; sl@25: } sl@25: sl@25: return (this->m_Array < other.m_Array); sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator<= sl@25: * Description: overload of the <= operator sl@25: * Parameters : other - bit array to compare sl@25: * Effects : None sl@25: * Returned : True if this <= other. Otherwise false. sl@25: ***************************************************************************/ sl@25: bool BitArray::operator<=(const BitArray &other) const sl@25: { sl@25: if (m_NumBits != other.m_NumBits) sl@25: { sl@25: /* unequal sizes */ sl@25: return false; sl@25: } sl@25: sl@25: return (this->m_Array <= other.m_Array); sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator> sl@25: * Description: overload of the > operator sl@25: * Parameters : other - bit array to compare sl@25: * Effects : None sl@25: * Returned : True if this > other. Otherwise false. sl@25: ***************************************************************************/ sl@25: bool BitArray::operator>(const BitArray &other) const sl@25: { sl@25: if (m_NumBits != other.m_NumBits) sl@25: { sl@25: /* unequal sizes */ sl@25: return false; sl@25: } sl@25: sl@25: return (this->m_Array > other.m_Array); sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator>= sl@25: * Description: overload of the >= operator sl@25: * Parameters : other - bit array to compare sl@25: * Effects : None sl@25: * Returned : True if this >= other. Otherwise false. sl@25: ***************************************************************************/ sl@25: bool BitArray::operator>=(const BitArray &other) const sl@25: { sl@25: if (m_NumBits != other.m_NumBits) sl@25: { sl@25: /* unequal sizes */ sl@25: return false; sl@25: } sl@25: sl@25: return (this->m_Array >= other.m_Array); sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator~ sl@25: * Description: overload of the ~ operator. Negates all non-spare bits in sl@25: * bit array sl@25: * Parameters : None sl@25: * Effects : None sl@25: * Returned : value of this after bitwise not sl@25: ***************************************************************************/ sl@25: BitArray BitArray::operator~(void) const sl@25: { sl@25: BitArray result(this->m_NumBits); sl@25: result = *this; sl@25: result.Not(); sl@25: sl@25: return result; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator& sl@25: * Description: overload of the & operator. Performs a bitwise and sl@25: * between the source array and this bit array. sl@25: * Parameters : other - bit array on righthand side of & sl@25: * Effects : None sl@25: * Returned : value of bitwise and of this and other. sl@25: ***************************************************************************/ sl@25: BitArray BitArray::operator&(const BitArray &other) const sl@25: { sl@25: BitArray result(this->m_NumBits); sl@25: result = *this; sl@25: result &= other; sl@25: sl@25: return result; sl@25: } sl@25: sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator^ sl@25: * Description: overload of the ^ operator. Performs a bitwise xor sl@25: * between the source array and this bit array. sl@25: * Parameters : other - bit array on righthand side of ^ sl@25: * Effects : None sl@25: * Returned : value of bitwise xor of this and other. sl@25: ***************************************************************************/ sl@25: BitArray BitArray::operator^(const BitArray &other) const sl@25: { sl@25: BitArray result(this->m_NumBits); sl@25: result = *this; sl@25: result ^= other; sl@25: sl@25: return result; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator| sl@25: * Description: overload of the | operator. Performs a bitwise or sl@25: * between the source array and this bit array. sl@25: * Parameters : other - bit array on righthand side of | sl@25: * Effects : None sl@25: * Returned : value of bitwise or of this and other. sl@25: ***************************************************************************/ sl@25: BitArray BitArray::operator|(const BitArray &other) const sl@25: { sl@25: BitArray result(this->m_NumBits); sl@25: result = *this; sl@25: result |= other; sl@25: sl@25: return result; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator<< sl@25: * Description: overload of the << operator. Performs a bitwise left sl@25: * shift of this bit array. sl@25: * Parameters : count - the number of bits to shift left sl@25: * Effects : None sl@25: * Returned : result of bitwise left shift sl@25: ***************************************************************************/ sl@25: BitArray BitArray::operator<<(const unsigned int count) const sl@25: { sl@25: BitArray result(this->m_NumBits); sl@25: result = *this; sl@25: result <<= count; sl@25: sl@25: return result; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator>> sl@25: * Description: overload of the >> operator. Performs a bitwise right sl@25: * shift of this bit array. sl@25: * Parameters : count - the number of bits to shift right sl@25: * Effects : None sl@25: * Returned : result of bitwise right shift sl@25: ***************************************************************************/ sl@25: BitArray BitArray::operator>>(const unsigned int count) const sl@25: { sl@25: BitArray result(this->m_NumBits); sl@25: result = *this; sl@25: result >>= count; sl@25: sl@25: return result; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator++ (prefix) sl@25: * Description: overload of the ++ operator. Increments the contents of sl@25: * a bit array. Overflows cause rollover. sl@25: * Parameters : None sl@25: * Effects : Bit array contents are incremented sl@25: * Returned : Reference to this array after increment sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator++(void) sl@25: { sl@25: int i; sl@25: unsigned char maxValue; /* maximum value for current char */ sl@25: unsigned char one; /* least significant bit in current char */ sl@25: sl@25: if (m_NumBits == 0) sl@25: { sl@25: return *this; /* nothing to increment */ sl@25: } sl@25: sl@25: /* handle arrays that don't use every bit in the last character */ sl@25: i = (m_NumBits % CHAR_BIT); sl@25: if (i != 0) sl@25: { sl@25: maxValue = UCHAR_MAX << (CHAR_BIT - i); sl@25: one = 1 << (CHAR_BIT - i); sl@25: } sl@25: else sl@25: { sl@25: maxValue = UCHAR_MAX; sl@25: one = 1; sl@25: } sl@25: sl@25: for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--) sl@25: { sl@25: if (m_Array[i] != maxValue) sl@25: { sl@25: m_Array[i] = m_Array[i] + one; sl@25: return *this; sl@25: } sl@25: else sl@25: { sl@25: /* need to carry to next byte */ sl@25: m_Array[i] = 0; sl@25: sl@25: /* remaining characters must use all bits */ sl@25: maxValue = UCHAR_MAX; sl@25: one = 1; sl@25: } sl@25: } sl@25: sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator++ (postfix) sl@25: * Description: overload of the ++ operator. Increments the contents of sl@25: * a bit array. Overflows cause rollover. sl@25: * Parameters : dumy - needed for postfix increment sl@25: * Effects : Bit array contents are incremented sl@25: * Returned : Reference to this array after increment sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator++(int dummy) sl@25: { sl@25: ++(*this); sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator-- (prefix) sl@25: * Description: overload of the -- operator. Decrements the contents of sl@25: * a bit array. Underflows cause rollover. sl@25: * Parameters : None sl@25: * Effects : Bit array contents are decremented sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator--(void) sl@25: { sl@25: int i; sl@25: unsigned char maxValue; /* maximum value for current char */ sl@25: unsigned char one; /* least significant bit in current char */ sl@25: sl@25: if (m_NumBits == 0) sl@25: { sl@25: return *this; /* nothing to decrement */ sl@25: } sl@25: sl@25: /* handle arrays that don't use every bit in the last character */ sl@25: i = (m_NumBits % CHAR_BIT); sl@25: if (i != 0) sl@25: { sl@25: maxValue = UCHAR_MAX << (CHAR_BIT - i); sl@25: one = 1 << (CHAR_BIT - i); sl@25: } sl@25: else sl@25: { sl@25: maxValue = UCHAR_MAX; sl@25: one = 1; sl@25: } sl@25: sl@25: for (i = BIT_CHAR(m_NumBits - 1); i >= 0; i--) sl@25: { sl@25: if (m_Array[i] >= one) sl@25: { sl@25: m_Array[i] = m_Array[i] - one; sl@25: return *this; sl@25: } sl@25: else sl@25: { sl@25: /* need to borrow from the next byte */ sl@25: m_Array[i] = maxValue; sl@25: sl@25: /* remaining characters must use all bits */ sl@25: maxValue = UCHAR_MAX; sl@25: one = 1; sl@25: } sl@25: } sl@25: sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator-- (postfix) sl@25: * Description: overload of the -- operator. Decrements the contents of sl@25: * a bit array. Underflows cause rollover. sl@25: * Parameters : dumy - needed for postfix decrement sl@25: * Effects : Bit array contents are decremented sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator--(int dummy) sl@25: { sl@25: --(*this); sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator= sl@25: * Description: overload of the = operator. Copies source contents into sl@25: * this bit array. sl@25: * Parameters : src - Source bit array sl@25: * Effects : Source bit array contents are copied into this array sl@25: * Returned : Reference to this array after copy sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator=(const BitArray &src) sl@25: { sl@25: if (*this == src) sl@25: { sl@25: /* don't do anything for a self assignment */ sl@25: return *this; sl@25: } sl@25: sl@25: if (m_NumBits != src.m_NumBits) sl@25: { sl@25: /* don't do assignment with different array sizes */ sl@25: return *this; sl@25: } sl@25: sl@25: if ((m_NumBits == 0) || (src.m_NumBits == 0)) sl@25: { sl@25: /* don't do assignment with unallocated array */ sl@25: return *this; sl@25: } sl@25: sl@25: /* copy bits from source */ sl@25: int size; sl@25: size = BITS_TO_CHARS(m_NumBits); sl@25: sl@25: copy(src.m_Array, &src.m_Array[size], this->m_Array); sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator&= sl@25: * Description: overload of the &= operator. Performs a bitwise and sl@25: * between the source array and this bit array. This bit sl@25: * array will contain the result. sl@25: * Parameters : src - Source bit array sl@25: * Effects : Results of bitwise and are stored in this array sl@25: * Returned : Reference to this array after and sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator&=(const BitArray &src) sl@25: { sl@25: int size; sl@25: sl@25: size = BITS_TO_CHARS(m_NumBits); sl@25: sl@25: if (m_NumBits != src.m_NumBits) sl@25: { sl@25: /* don't do assignment with different array sizes */ sl@25: return *this; sl@25: } sl@25: sl@25: /* AND array one unsigned char at a time */ sl@25: for(int i = 0; i < size; i++) sl@25: { sl@25: m_Array[i] = m_Array[i] & src.m_Array[i]; sl@25: } sl@25: sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator^= sl@25: * Description: overload of the ^= operator. Performs a bitwise xor sl@25: * between the source array and this bit array. This bit sl@25: * array will contain the result. sl@25: * Parameters : src - Source bit array sl@25: * Effects : Results of bitwise xor are stored in this array sl@25: * Returned : Reference to this array after xor sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator^=(const BitArray &src) sl@25: { sl@25: int size; sl@25: sl@25: size = BITS_TO_CHARS(m_NumBits); sl@25: sl@25: if (m_NumBits != src.m_NumBits) sl@25: { sl@25: /* don't do assignment with different array sizes */ sl@25: return *this; sl@25: } sl@25: sl@25: /* XOR array one unsigned char at a time */ sl@25: for(int i = 0; i < size; i++) sl@25: { sl@25: m_Array[i] = m_Array[i] ^ src.m_Array[i]; sl@25: } sl@25: sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator|= sl@25: * Description: overload of the |= operator. Performs a bitwise or sl@25: * between the source array and this bit array. This bit sl@25: * array will contain the result. sl@25: * Parameters : src - Source bit array sl@25: * Effects : Results of bitwise or are stored in this array sl@25: * Returned : Reference to this array after or sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator|=(const BitArray &src) sl@25: { sl@25: int size; sl@25: sl@25: size = BITS_TO_CHARS(m_NumBits); sl@25: sl@25: if (m_NumBits != src.m_NumBits) sl@25: { sl@25: /* don't do assignment with different array sizes */ sl@25: return *this; sl@25: } sl@25: sl@25: /* OR array one unsigned char at a time */ sl@25: for(int i = 0; i < size; i++) sl@25: { sl@25: m_Array[i] = m_Array[i] | src.m_Array[i]; sl@25: } sl@25: sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : Not sl@25: * Description: Negates all non-spare bits in bit array. sl@25: * Parameters : None sl@25: * Effects : Contents of bit array are negated. Any spare bits are sl@25: * left at 0. sl@25: * Returned : Reference to this array after not sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::Not(void) sl@25: { sl@25: int bits; sl@25: unsigned char mask; sl@25: int size; sl@25: sl@25: size = BITS_TO_CHARS(m_NumBits); sl@25: sl@25: if (m_NumBits == 0) sl@25: { sl@25: /* don't do not with unallocated array */ sl@25: return *this; sl@25: } sl@25: sl@25: /* NOT array one unsigned char at a time */ sl@25: for(int i = 0; i < size; i++) sl@25: { sl@25: m_Array[i] = ~m_Array[i]; sl@25: } sl@25: sl@25: /* zero any spare bits so increment and decrement are consistent */ sl@25: bits = m_NumBits % CHAR_BIT; sl@25: if (bits != 0) sl@25: { sl@25: mask = UCHAR_MAX << (CHAR_BIT - bits); sl@25: m_Array[BIT_CHAR(m_NumBits - 1)] &= mask; sl@25: } sl@25: sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator<<= sl@25: * Description: overload of the <<= operator. Performs a left shift on sl@25: * this bit array. This bit array will contain the result. sl@25: * Parameters : shifts - number of bit positions to shift sl@25: * Effects : Results of the shifts are stored in this array sl@25: * Returned : Reference to this array after shift sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator<<=(const unsigned int shifts) sl@25: { sl@25: int i; sl@25: int chars = shifts / CHAR_BIT; /* number of whole byte shifts */ sl@25: sl@25: if (shifts >= m_NumBits) sl@25: { sl@25: /* all bits have been shifted off */ sl@25: this->ClearAll(); sl@25: return *this; sl@25: } sl@25: sl@25: /* first handle big jumps of bytes */ sl@25: if (chars > 0) sl@25: { sl@25: int size; sl@25: sl@25: size = BITS_TO_CHARS(m_NumBits); sl@25: sl@25: for (i = 0; (i + chars) < size; i++) sl@25: { sl@25: m_Array[i] = m_Array[i + chars]; sl@25: } sl@25: sl@25: /* now zero out new bytes on the right */ sl@25: for (i = size; chars > 0; chars--) sl@25: { sl@25: m_Array[i - chars] = 0; sl@25: } sl@25: } sl@25: sl@25: /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */ sl@25: for (i = 0; i < (int)(shifts % CHAR_BIT); i++) sl@25: { sl@25: for (unsigned int j = 0; j < BIT_CHAR(m_NumBits - 1); j++) sl@25: { sl@25: m_Array[j] <<= 1; sl@25: sl@25: /* handle shifts across byte bounds */ sl@25: if (m_Array[j + 1] & MS_BIT) sl@25: { sl@25: m_Array[j] |= 0x01; sl@25: } sl@25: } sl@25: sl@25: m_Array[BIT_CHAR(m_NumBits - 1)] <<= 1; sl@25: } sl@25: sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator>>= sl@25: * Description: overload of the >>= operator. Performs a right shift on sl@25: * this bit array. This bit array will contain the result. sl@25: * Parameters : shifts - number of bit positions to shift sl@25: * Effects : Results of the shifts are stored in this array sl@25: * Returned : Reference to this array after shift sl@25: ***************************************************************************/ sl@25: BitArray& BitArray::operator>>=(const unsigned int shifts) sl@25: { sl@25: int i; sl@25: char mask; sl@25: int chars = shifts / CHAR_BIT; /* number of whole byte shifts */ sl@25: sl@25: if (shifts >= m_NumBits) sl@25: { sl@25: /* all bits have been shifted off */ sl@25: this->ClearAll(); sl@25: return *this; sl@25: } sl@25: sl@25: /* first handle big jumps of bytes */ sl@25: if (chars > 0) sl@25: { sl@25: for (i = BIT_CHAR(m_NumBits - 1); (i - chars) >= 0; i--) sl@25: { sl@25: m_Array[i] = m_Array[i - chars]; sl@25: } sl@25: sl@25: /* now zero out new bytes on the right */ sl@25: for (; chars > 0; chars--) sl@25: { sl@25: m_Array[chars - 1] = 0; sl@25: } sl@25: } sl@25: sl@25: /* now we have at most CHAR_BIT - 1 bit shifts across the whole array */ sl@25: for (i = 0; i < (int)(shifts % CHAR_BIT); i++) sl@25: { sl@25: for (unsigned int j = BIT_CHAR(m_NumBits - 1); j > 0; j--) sl@25: { sl@25: m_Array[j] >>= 1; sl@25: sl@25: /* handle shifts across byte bounds */ sl@25: if (m_Array[j - 1] & 0x01) sl@25: { sl@25: m_Array[j] |= MS_BIT; sl@25: } sl@25: } sl@25: sl@25: m_Array[0] >>= 1; sl@25: } sl@25: sl@25: /*********************************************************************** sl@25: * zero any spare bits that are shifted beyond the end of the bit array sl@25: * so that increment and decrement are consistent. sl@25: ***********************************************************************/ sl@25: i = m_NumBits % CHAR_BIT; sl@25: if (i != 0) sl@25: { sl@25: mask = UCHAR_MAX << (CHAR_BIT - i); sl@25: m_Array[BIT_CHAR(m_NumBits - 1)] &= mask; sl@25: } sl@25: sl@25: return *this; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : bit_array_index_c - constructor sl@25: * Description: This is the bit_array_index_c constructor. It stores a sl@25: * pointer to the bit array and the bit index. sl@25: * Parameters : array - pointer to bit array sl@25: * index - index of bit in array sl@25: * Effects : Pointer to bit array and bit index are stored. sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: BitArrayIndex::BitArrayIndex(BitArray *array, sl@25: const unsigned int index) sl@25: { sl@25: m_BitArray = array; sl@25: m_Index = index; sl@25: } sl@25: sl@25: /*************************************************************************** sl@25: * Method : operator= sl@25: * Description: overload of the = operator. Sets the bit array bit to sl@25: * the value of src. sl@25: * Parameters : src - bit value sl@25: * Effects : Bit pointed to by this object is set to the value of sl@25: * source. sl@25: * Returned : None sl@25: ***************************************************************************/ sl@25: void BitArrayIndex::operator=(const bool src) sl@25: { sl@25: if (m_BitArray == NULL) sl@25: { sl@25: return; /* no array */ sl@25: } sl@25: sl@25: if (m_BitArray->SizeInBits() <= m_Index) sl@25: { sl@25: return; /* index is out of bounds */ sl@25: } sl@25: sl@25: if (src) sl@25: { sl@25: m_BitArray->SetBit(m_Index); sl@25: } sl@25: else sl@25: { sl@25: m_BitArray->ClearBit(m_Index); sl@25: } sl@25: }