/**********************************************************************/ /** 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_