You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
5.8 KiB
234 lines
5.8 KiB
|
|
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// The copyright to the contents herein is the property of Valve, L.L.C. |
|
// The contents may be used and/or copied only with the written permission of |
|
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in |
|
// the agreement/contract under which the contents have been supplied. |
|
// |
|
//***************************************************************************** |
|
// |
|
// Contents: |
|
// |
|
// CSimpleBitString |
|
// |
|
// Authors: chrisn |
|
// |
|
// Target restrictions: |
|
// |
|
// Tool restrictions: |
|
// |
|
// Things to do: |
|
// |
|
//***************************************************************************** |
|
|
|
|
|
//***************************************************************************** |
|
// |
|
// Include files required to build and use this module. |
|
// |
|
//***************************************************************************** |
|
|
|
// Precompiled header (must come first - includes project common headers) |
|
//#include "stdafx.h" |
|
#include "tier0/platform.h" |
|
#include "tier1/utlvector.h" |
|
#include "simplebitstring.h" |
|
|
|
|
|
|
|
//***************************************************************************** |
|
// |
|
// Class definitions: |
|
// |
|
//***************************************************************************** |
|
|
|
// |
|
// class CSimpleBitString::iterator |
|
// |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Function: |
|
// |
|
//----------------------------------------------------------------------------- |
|
void CSimpleBitString::AppendBits( uint64 u64Data, uint32 NumSignificantLowBitsOfData ) |
|
{ |
|
Assert |
|
( |
|
NumSignificantLowBitsOfData <= 64 |
|
); |
|
|
|
while ( NumSignificantLowBitsOfData > 0 ) |
|
{ |
|
// Clear top bits of data |
|
if ( NumSignificantLowBitsOfData < 64 ) |
|
u64Data &= ( (1ULL << NumSignificantLowBitsOfData) - 1 ); // will fail for 64 bits |
|
|
|
uint32 Idx = m_uNumBits / 8; |
|
uint32 NumUsedBitsInLastByte = m_uNumBits % 8; |
|
|
|
uint32 NumAvailableBitsInLastByte = 8 - NumUsedBitsInLastByte; |
|
|
|
uint32 NumBitsToPutInThisByte |
|
= min( NumAvailableBitsInLastByte, NumSignificantLowBitsOfData ); |
|
|
|
uint8 BitsForThisByte |
|
= ( u64Data >> (NumSignificantLowBitsOfData - NumBitsToPutInThisByte) ) |
|
& ( (1ULL << NumBitsToPutInThisByte) - 1 ); |
|
|
|
m_vecU8[Idx] |= ( BitsForThisByte |
|
<< ( NumAvailableBitsInLastByte - NumBitsToPutInThisByte ) ); |
|
|
|
m_uNumBits += NumBitsToPutInThisByte; |
|
|
|
NumAvailableBitsInLastByte -= NumBitsToPutInThisByte; |
|
if ( NumAvailableBitsInLastByte == 0 ) |
|
{ |
|
m_vecU8[ m_vecU8.AddToTail() ] = 0x00; |
|
} |
|
|
|
// We've used the top N bits of data |
|
NumSignificantLowBitsOfData -= NumBitsToPutInThisByte; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Function: |
|
// |
|
//----------------------------------------------------------------------------- |
|
void CSimpleBitString::AppendBits( const uint8 * pData, uint32 NumBitsOfData ) |
|
{ |
|
Assert( pData ); |
|
|
|
uint32 NumBytes = NumBitsOfData / 8; |
|
for ( uint32 i = 0; i < NumBytes; ++i ) |
|
{ |
|
AppendBits( *(pData++), 8 ); |
|
} |
|
uint32 NumTailBits = NumBitsOfData % 8; |
|
AppendBits( (*pData) >> (8U - NumTailBits), NumTailBits ); |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Function: |
|
// |
|
//----------------------------------------------------------------------------- |
|
void CSimpleBitString::ReversiblyObfusticateBitsFromStart( uint NumBits, const uint8 * pObfusticationData, size_t uSizeOfObfusticationData ) |
|
{ |
|
Assert( pObfusticationData ); |
|
|
|
if ( NumBits > m_uNumBits |
|
|| NumBits > uSizeOfObfusticationData * 8 |
|
) |
|
{ |
|
AssertMsg( false, "ReversiblyObfusticateBitsFromStart(): Bad NumBits" ); |
|
return; // bugbug taylor bool return |
|
} |
|
|
|
uint8 * pBits = & m_vecU8[0]; |
|
|
|
uint NumBytes = NumBits / 8; |
|
for ( uint i = 0; i < NumBytes; ++i ) |
|
{ |
|
*(pBits++) ^= *(pObfusticationData++); |
|
} |
|
uint NumTailBits = NumBits % 8; |
|
if ( NumTailBits > 0 ) |
|
{ |
|
*pBits ^= ( *(pObfusticationData++) & (((1U << NumTailBits) - 1) << (8U - NumTailBits) ) ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Function: |
|
// |
|
//----------------------------------------------------------------------------- |
|
uint8 CSimpleBitString::GetByteChecksumFromStart( uint NumBits ) const |
|
{ |
|
if ( NumBits > m_uNumBits ) |
|
{ |
|
AssertMsg( false, "GenerateByteChecksumFromStart(): Bad NumBits" ); |
|
return 0; |
|
} |
|
|
|
uint8 u8Checksum = 0; |
|
const uint8 * pBits = & m_vecU8[0]; |
|
|
|
uint NumBytes = NumBits / 8; |
|
for ( uint i = 0; i < NumBytes; ++i ) |
|
{ |
|
u8Checksum += *(pBits++); |
|
} |
|
uint NumTailBits = NumBits % 8; |
|
if ( NumTailBits > 0 ) |
|
{ |
|
u8Checksum += ( *(pBits) & (((1U << NumTailBits) - 1) << (8U - NumTailBits) ) ); |
|
} |
|
|
|
return u8Checksum; |
|
} |
|
|
|
|
|
|
|
// |
|
// class CSimpleBitString::iterator |
|
// |
|
uint32 CSimpleBitString::iterator::GetNextBits( uint32 NumBitsToGet ) |
|
{ |
|
Assert |
|
( |
|
NumBitsToGet <= 32 |
|
); |
|
|
|
return static_cast<uint32>( GetNextBits64( NumBitsToGet ) ); |
|
} |
|
|
|
uint64 CSimpleBitString::iterator::GetNextBits64( uint32 NumBitsToGet ) |
|
{ |
|
Assert |
|
( |
|
NumBitsToGet <= 64 |
|
); |
|
|
|
if ( m_uNextBitIdx + NumBitsToGet > m_rSimpleBitString.m_uNumBits ) |
|
{ |
|
AssertMsg( false, "Not enough bits in CSimpleBitString" ); |
|
return 0; |
|
} |
|
|
|
uint64 u64Data = 0; |
|
|
|
while ( NumBitsToGet > 0 ) |
|
{ |
|
uint32 Idx = m_uNextBitIdx / 8; |
|
Assert( Idx < (uint32)m_rSimpleBitString.m_vecU8.Count() ); |
|
|
|
uint32 NumConsumedBitsInThisByte = m_uNextBitIdx % 8; |
|
uint32 NumAvailableBitsInThisByte = 8 - NumConsumedBitsInThisByte; |
|
|
|
uint32 NumBitsToGetFromThisByte |
|
= min( NumAvailableBitsInThisByte, NumBitsToGet ); |
|
|
|
uint8 BitsFromThisByte |
|
= ( m_rSimpleBitString.m_vecU8[Idx] >> (NumAvailableBitsInThisByte - NumBitsToGetFromThisByte) ) |
|
& ( (1UL << NumBitsToGetFromThisByte) - 1 ); |
|
|
|
u64Data <<= NumBitsToGetFromThisByte; |
|
u64Data |= BitsFromThisByte; |
|
|
|
m_uNextBitIdx += NumBitsToGetFromThisByte; |
|
NumBitsToGet -= NumBitsToGetFromThisByte; |
|
} |
|
|
|
return u64Data; |
|
} |
|
|
|
|