/****************************************************************************
*
* Copyright (C) 2000-2001 RealNetworks, Inc. All rights reserved.
*
* This program is free software. It may be distributed under the terms
* in the file LICENSE, found in the top level of the source distribution.
*
*/
#include "bitset.h"
#include "dbg.h"
#include <string.h>
/*
* n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
* n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
* n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
* n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
* n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
*
* -- C code which reverses the bits in a word.
*
* Everyone should have 'fortune' in their login script. :-)
*/
// A large portion of this is copied from CBuffer
#define WORD_SIZE(bits) ( ((bits+31)/32)*4 )
/*****************************************************************************
*
* CBitSet
*
*****************************************************************************/
CBitSet::CBitSet( void ) :
m_nAlloc(0),
m_nBitLen(0),
m_buf(NULL)
{
// Empty
}
CBitSet::CBitSet( const CBitSet& other ) :
m_nAlloc(0),
m_nBitLen(0),
m_buf(NULL)
{
assert( other.m_buf || (!other.m_nAlloc && !other.m_nBitLen) );
if( other.m_nBitLen )
{
m_nAlloc = WORD_SIZE(other.m_nBitLen);
m_nBitLen = other.m_nBitLen;
m_buf = new BYTE[ m_nAlloc ];
memcpy( m_buf, other.m_buf, m_nAlloc );
}
}
CBitSet::CBitSet( CPBYTE pbuf, size_t bitlen )
{
assert( pbuf );
m_nAlloc = WORD_SIZE(bitlen);
m_nBitLen = bitlen;
m_buf = new BYTE[ m_nAlloc ];
memcpy( m_buf, pbuf, m_nAlloc );
}
CBitSet::~CBitSet( void )
{
delete[] m_buf;
}
CBitSet& CBitSet::operator=( const CBitSet& other )
{
assert( other.m_buf || (!other.m_nAlloc && !other.m_nBitLen) );
m_nAlloc = m_nBitLen = 0;
delete[] m_buf; m_buf = NULL;
if( other.m_nBitLen )
{
m_nAlloc = WORD_SIZE(other.m_nBitLen);
m_nBitLen = other.m_nBitLen;
m_buf = new BYTE[ m_nAlloc ];
memcpy( m_buf, other.m_buf, m_nAlloc );
}
return *this;
}
size_t CBitSet::GetBitSize( void ) const
{
return m_nBitLen;
}
void CBitSet::SetBitSize( size_t bitlen )
{
assert( m_buf || (!m_nAlloc && !m_nBitLen) );
if( bitlen )
{
size_t len = WORD_SIZE(bitlen);
if( len > m_nAlloc )
{
BYTE* pbuf = new BYTE[ len ];
memcpy( pbuf, m_buf, m_nAlloc );
delete[] m_buf;
m_nAlloc = len;
m_buf = pbuf;
}
m_nBitLen = bitlen;
}
else
{
m_nAlloc = m_nBitLen = 0;
delete[] m_buf; m_buf = NULL;
}
}
void CBitSet::Set( CPBYTE pbuf, size_t bitlen )
{
assert( pbuf || !bitlen );
assert( m_buf || (!m_nAlloc && !m_nBitLen) );
if( bitlen )
{
size_t len = WORD_SIZE(bitlen);
if( len > m_nAlloc )
{
delete[] m_buf;
m_buf = new BYTE[ len ];
m_nAlloc = len;
}
memcpy( m_buf, pbuf, len );
m_nBitLen = bitlen;
}
else
{
m_nAlloc = m_nBitLen = 0;
delete[] m_buf; m_buf = NULL;
}
}
size_t CBitSet::GetSize( void ) const
{
return WORD_SIZE(m_nBitLen);
}
PBYTE CBitSet::GetBuffer( void )
{
return m_buf;
}
CPBYTE CBitSet::GetBuffer( void ) const
{
return m_buf;
}
void CBitSet::ZeroBits( void )
{
if( m_nAlloc )
{
assert_or_ret( m_buf );
memset( m_buf, 0, m_nAlloc );
}
}
void CBitSet::SetBit( size_t n )
{
assert( m_buf && n < m_nBitLen );
m_buf[n/8] |= (1 << (n&7));
}
void CBitSet::ClearBit( size_t n )
{
assert( m_buf && n < m_nBitLen );
m_buf[n/8] &= ~(1 << (n&7));
}
bool CBitSet::TestBit( size_t n )
{
assert( m_buf && n < m_nBitLen );
return ( ( m_buf[n/8] & (1 << (n&7)) ) != 0 );
}
/*****************************************************************************
*
* CRevBitSet
*
*****************************************************************************/
void CRevBitSet::SetBit( size_t n )
{
assert( m_buf && n < m_nBitLen );
m_buf[n/8] |= (1 << (7-n&7));
}
void CRevBitSet::ClearBit( size_t n )
{
assert( m_buf && n < m_nBitLen );
m_buf[n/8] &= ~(1 << (7-n&7));
}
bool CRevBitSet::TestBit( size_t n )
{
assert( m_buf && n < m_nBitLen );
return ( ( m_buf[n/8] & (1 << (7-n&7)) ) != 0 );
}
syntax highlighted by Code2HTML, v. 0.9.1