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