Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // The copyright to the contents herein is the property of Valve, L.L.C.
  4. // The contents may be used and/or copied only with the written permission of
  5. // Valve, L.L.C., or in accordance with the terms and conditions stipulated in
  6. // the agreement/contract under which the contents have been supplied.
  7. //
  8. //*****************************************************************************
  9. //
  10. // Contents:
  11. //
  12. // CSimpleBitString
  13. //
  14. // Authors: chrisn
  15. //
  16. // Target restrictions:
  17. //
  18. // Tool restrictions:
  19. //
  20. // Things to do:
  21. //
  22. //*****************************************************************************
  23. //*****************************************************************************
  24. //
  25. // Include files required to build and use this module.
  26. //
  27. //*****************************************************************************
  28. // Precompiled header (must come first - includes project common headers)
  29. //#include "stdafx.h"
  30. #include "tier0/platform.h"
  31. #include "tier1/utlvector.h"
  32. #include "simplebitstring.h"
  33. //*****************************************************************************
  34. //
  35. // Class definitions:
  36. //
  37. //*****************************************************************************
  38. //
  39. // class CSimpleBitString::iterator
  40. //
  41. //-----------------------------------------------------------------------------
  42. //
  43. // Function:
  44. //
  45. //-----------------------------------------------------------------------------
  46. void CSimpleBitString::AppendBits( uint64 u64Data, uint32 NumSignificantLowBitsOfData )
  47. {
  48. Assert
  49. (
  50. NumSignificantLowBitsOfData <= 64
  51. );
  52. while ( NumSignificantLowBitsOfData > 0 )
  53. {
  54. // Clear top bits of data
  55. if ( NumSignificantLowBitsOfData < 64 )
  56. u64Data &= ( (1ULL << NumSignificantLowBitsOfData) - 1 ); // will fail for 64 bits
  57. uint32 Idx = m_uNumBits / 8;
  58. uint32 NumUsedBitsInLastByte = m_uNumBits % 8;
  59. uint32 NumAvailableBitsInLastByte = 8 - NumUsedBitsInLastByte;
  60. uint32 NumBitsToPutInThisByte
  61. = min( NumAvailableBitsInLastByte, NumSignificantLowBitsOfData );
  62. uint8 BitsForThisByte
  63. = ( u64Data >> (NumSignificantLowBitsOfData - NumBitsToPutInThisByte) )
  64. & ( (1ULL << NumBitsToPutInThisByte) - 1 );
  65. m_vecU8[Idx] |= ( BitsForThisByte
  66. << ( NumAvailableBitsInLastByte - NumBitsToPutInThisByte ) );
  67. m_uNumBits += NumBitsToPutInThisByte;
  68. NumAvailableBitsInLastByte -= NumBitsToPutInThisByte;
  69. if ( NumAvailableBitsInLastByte == 0 )
  70. {
  71. m_vecU8[ m_vecU8.AddToTail() ] = 0x00;
  72. }
  73. // We've used the top N bits of data
  74. NumSignificantLowBitsOfData -= NumBitsToPutInThisByte;
  75. }
  76. }
  77. //-----------------------------------------------------------------------------
  78. //
  79. // Function:
  80. //
  81. //-----------------------------------------------------------------------------
  82. void CSimpleBitString::AppendBits( const uint8 * pData, uint32 NumBitsOfData )
  83. {
  84. Assert( pData );
  85. uint32 NumBytes = NumBitsOfData / 8;
  86. for ( uint32 i = 0; i < NumBytes; ++i )
  87. {
  88. AppendBits( *(pData++), 8 );
  89. }
  90. uint32 NumTailBits = NumBitsOfData % 8;
  91. AppendBits( (*pData) >> (8U - NumTailBits), NumTailBits );
  92. }
  93. //-----------------------------------------------------------------------------
  94. //
  95. // Function:
  96. //
  97. //-----------------------------------------------------------------------------
  98. void CSimpleBitString::ReversiblyObfusticateBitsFromStart( uint NumBits, const uint8 * pObfusticationData, size_t uSizeOfObfusticationData )
  99. {
  100. Assert( pObfusticationData );
  101. if ( NumBits > m_uNumBits
  102. || NumBits > uSizeOfObfusticationData * 8
  103. )
  104. {
  105. AssertMsg( false, "ReversiblyObfusticateBitsFromStart(): Bad NumBits" );
  106. return; // bugbug taylor bool return
  107. }
  108. uint8 * pBits = & m_vecU8[0];
  109. uint NumBytes = NumBits / 8;
  110. for ( uint i = 0; i < NumBytes; ++i )
  111. {
  112. *(pBits++) ^= *(pObfusticationData++);
  113. }
  114. uint NumTailBits = NumBits % 8;
  115. if ( NumTailBits > 0 )
  116. {
  117. *pBits ^= ( *(pObfusticationData++) & (((1U << NumTailBits) - 1) << (8U - NumTailBits) ) );
  118. }
  119. }
  120. //-----------------------------------------------------------------------------
  121. //
  122. // Function:
  123. //
  124. //-----------------------------------------------------------------------------
  125. uint8 CSimpleBitString::GetByteChecksumFromStart( uint NumBits ) const
  126. {
  127. if ( NumBits > m_uNumBits )
  128. {
  129. AssertMsg( false, "GenerateByteChecksumFromStart(): Bad NumBits" );
  130. return 0;
  131. }
  132. uint8 u8Checksum = 0;
  133. const uint8 * pBits = & m_vecU8[0];
  134. uint NumBytes = NumBits / 8;
  135. for ( uint i = 0; i < NumBytes; ++i )
  136. {
  137. u8Checksum += *(pBits++);
  138. }
  139. uint NumTailBits = NumBits % 8;
  140. if ( NumTailBits > 0 )
  141. {
  142. u8Checksum += ( *(pBits) & (((1U << NumTailBits) - 1) << (8U - NumTailBits) ) );
  143. }
  144. return u8Checksum;
  145. }
  146. //
  147. // class CSimpleBitString::iterator
  148. //
  149. uint32 CSimpleBitString::iterator::GetNextBits( uint32 NumBitsToGet )
  150. {
  151. Assert
  152. (
  153. NumBitsToGet <= 32
  154. );
  155. return static_cast<uint32>( GetNextBits64( NumBitsToGet ) );
  156. }
  157. uint64 CSimpleBitString::iterator::GetNextBits64( uint32 NumBitsToGet )
  158. {
  159. Assert
  160. (
  161. NumBitsToGet <= 64
  162. );
  163. if ( m_uNextBitIdx + NumBitsToGet > m_rSimpleBitString.m_uNumBits )
  164. {
  165. AssertMsg( false, "Not enough bits in CSimpleBitString" );
  166. return 0;
  167. }
  168. uint64 u64Data = 0;
  169. while ( NumBitsToGet > 0 )
  170. {
  171. uint32 Idx = m_uNextBitIdx / 8;
  172. Assert( Idx < (uint32)m_rSimpleBitString.m_vecU8.Count() );
  173. uint32 NumConsumedBitsInThisByte = m_uNextBitIdx % 8;
  174. uint32 NumAvailableBitsInThisByte = 8 - NumConsumedBitsInThisByte;
  175. uint32 NumBitsToGetFromThisByte
  176. = min( NumAvailableBitsInThisByte, NumBitsToGet );
  177. uint8 BitsFromThisByte
  178. = ( m_rSimpleBitString.m_vecU8[Idx] >> (NumAvailableBitsInThisByte - NumBitsToGetFromThisByte) )
  179. & ( (1UL << NumBitsToGetFromThisByte) - 1 );
  180. u64Data <<= NumBitsToGetFromThisByte;
  181. u64Data |= BitsFromThisByte;
  182. m_uNextBitIdx += NumBitsToGetFromThisByte;
  183. NumBitsToGet -= NumBitsToGetFromThisByte;
  184. }
  185. return u64Data;
  186. }