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