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