windows-nt/Source/XPSP1/NT/admin/netui/common/h/bitfield.hxx
2020-09-26 16:20:57 +08:00

209 lines
5.9 KiB
C++

/**********************************************************************/
/** Microsoft LAN Manager **/
/** Copyright(c) Microsoft Corp., 1990, 1991 **/
/**********************************************************************/
/*
Bitfield.hxx
This file contains the class definition for the bitfield class.
FILE HISTORY:
Johnl 13-Jul-1991 Created
*/
#ifndef _BITFIELD_HXX_
#define _BITFIELD_HXX_
#include "base.hxx"
#include "uibuffer.hxx"
enum BITVALUES { OFF = 0 , ON = 1 } ;
/*************************************************************************
NAME: BITFIELD
SYNOPSIS: This class provides a variable size bitfield class
INTERFACE:
Fill in after comments
PARENT: BASE
CAVEATS:
It is assumed that the last byte of the bitvector extends to a byte
boundary. This allows multi-byte settings without having to worry
about the half byte case at the end. Any unused bits should always
be set to 0.
NOTES:
HISTORY:
Johnl 13-Jul-1991 Created
**************************************************************************/
DLL_CLASS BITFIELD : public BASE
{
public:
/* All bits are initialized to 0 during construction
*/
BITFIELD( unsigned cBitsInBitfield, enum BITVALUES bitInit ) ;
/* Initializes the bitfield to the chunk of memory pointed at by
* pbInitValue of size cInitBytes. If cTotalBytes is 0, then the
* size of the bitfield is assumed to be 8*cInitBytes bits long, otherwise
* the bitfield is cTotalBits long.
*/
BITFIELD( const BYTE * pbInitValue,
unsigned cInitBytes,
unsigned cTotalBits = 0 ) ;
BITFIELD( const BITFIELD & bitfieldSrc ) ;
/* Provide easy ways to initialize the bitfield with standard types
* which will generally be manifests.
* The size is assumed to be the size of the data type.
*/
BITFIELD( USHORT usInit ) ;
BITFIELD( ULONG ulInit ) ;
~BITFIELD() ;
/* Resizes the bitfield to the specified count of bits.
*/
APIERR Resize( unsigned cBitsInBitfield ) ;
/* Clear or set all of the bits in the bitfield
*/
void SetAllBits( enum BITVALUES bit = ON ) ;
/* Set the bit at bit offset iBitPos to the value of bBit (defaults to 1).
*/
void SetBit( unsigned iBitPos, enum BITVALUES bitVal = ON ) ;
BOOL IsBitSet( unsigned iBitPos ) const ;
//
// Does a bitwise complement of the bitfield
//
void Not( void ) ;
/* Given two bitfields, ANDs the contents and returns TRUE if any of the
* same positioned bits are set.
* Example: if ( bitOldBits & bitMaskBits ) ... ;
*
* For an equivalent OR operation, simply check if any bits are set
*/
BOOL operator&( const BITFIELD & bitfieldSrc ) ;
/* ORs or ANDs or Assigns the bitfield on the right with the target bitfield on the
* left.
* Example: bitMyBits |= bitMaskBits ;
*
* The bitfields must be of the same size.
*/
BITFIELD & operator=( const BITFIELD & bitfieldSrc ) ;
BITFIELD & operator=( ULONG ulMask ) ;
BITFIELD & operator=( USHORT usMask ) ;
void operator&=( const BITFIELD & bitfieldSrc ) ;
void operator|=( const BITFIELD & bitfieldSrc ) ;
BOOL operator==( BITFIELD & bitfieldSrc ) ;
BOOL operator==( ULONG ulMask ) const ;
BOOL operator==( USHORT usMask ) const ;
BOOL operator!=( BITFIELD & bitfieldSrc )
{ return !operator==( bitfieldSrc ) ; }
/* Provide easy way to do masks with common types, the bitfield does not
* have to be the same size as the operand type, must be at least as big
* however.
*/
//void operator&=( BYTE bSrc ) ;
void operator&=( USHORT usSrc ) ;
void operator&=( ULONG ulSrc ) ;
//void operator|=( BYTE bSrc ) ;
void operator|=( USHORT usSrc ) ;
void operator|=( ULONG ulSrc ) ;
/* Conversion operators:
*
* The size must match the size of the bitfield.
*/
operator ULONG() ;
operator USHORT() ;
//operator BYTE() ;
/* Returns the number of bits in this bitfield
*/
unsigned QueryCount( void ) const
{ return _cBitsInBitfield ; }
/* Returns the number of BYTEs it takes to represent this bitfield.
*
* Need to add one if a bit overhangs a BYTE boundary.
*
* BUGBUG - Misleading name, is really Byte count of bitfield
*/
unsigned QueryAllocSize( void ) const
{ return ( QueryCount()/8 + ( QueryCount() % 8 ? 1 : 0 ) ) ; }
/* Return the number of bits into the byte the requested bit is at
*/
unsigned QueryOffset( unsigned iBitPos ) const
{ return iBitPos % 8 ; }
protected:
/* Get a pointer to the BYTE which contains the requested bit (for
* multi-byte setting, should occur on a BYTE boundary).
* iBitOffset - index of the requested bit (0 = 1st bit, 1 = 2nd bit etc.)
* cbitsTargetOpSize - number of bits that will be used in the
* operation, used for bounds checking
*/
BYTE * QueryBitPos( unsigned iBitOffset, unsigned cbitsTargetOpSize ) const ;
/* Returns TRUE if the bitfield had to be allocated in _pbBitVector,
* returns FALSE if the bitfield is wholly contained in _ulBitfield.
*/
BOOL IsAllocated( void ) const
{ return ( _cBitsInBitfield > QueryMaxNonAllocBitCount() ) ; }
/* Returns the number of bits that a BITFIELD object can hold without
* allocating any memory.
*/
unsigned QueryMaxNonAllocBitCount( void ) const
{ return (8 * sizeof(ULONG)) ; }
/* Allocates the memory required by the bitfield class if the size
* is greater then what can fit inline.
*/
APIERR AllocBitfield( unsigned cBitsInBitfield ) ;
private:
/* The actual bitfield.
*/
union
{
BYTE * _pbBitVector ; // Pointer to allocated bitfield
ULONG _ulBitfield ; // ULONG bitfield if bitfield < 32 bits
} ;
/* Count of bits that are in this bitfield.
*/
unsigned _cBitsInBitfield ;
} ;
#endif // _BITFIELD_HXX_