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