smatskevich

InputBitStream for Huffman coding

May 13th, 2017
123
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <assert.h>
  2. #include <vector>
  3. #include "Huffman.h"
  4.  
  5. using std::vector;
  6.  
  7. class CInputBitStream {
  8. public:
  9.     CInputBitStream( IInputStream& _stream );
  10.  
  11.     // Считывание одного бита.
  12.     bool ReadBit( bool& value );
  13.     // Считывание одного байта.
  14.     bool ReadByte( byte& value );
  15.  
  16. private:
  17.     IInputStream& stream;
  18.     unsigned char lastByte; // Последний байт, считанный из stream.
  19.     char readBitsCount; // Количество считанных бит из lastByte.
  20. };
  21.  
  22. CInputBitStream::CInputBitStream( IInputStream& _stream ) :
  23.     stream( _stream ),
  24.     lastByte( 0 ),
  25.     readBitsCount( 8 )
  26. {
  27. }
  28.  
  29. bool CInputBitStream::ReadBit( bool& value )
  30. {
  31.     assert( readBitsCount <= 8 );
  32.     if( readBitsCount == 8 ) {
  33.         // Биты закончились. Берем следующий.
  34.         if( !stream.Read( lastByte ) ) {
  35.             // Нету.
  36.             return false;
  37.         }
  38.         readBitsCount = 0;
  39.     }
  40.     // Считаем очередной бит.
  41.     ++readBitsCount;
  42.     value = ( ( lastByte >> ( 8 - readBitsCount ) ) & 1 ) != 0;
  43.     return true;
  44. }
  45.  
  46. bool CInputBitStream::ReadByte( byte& value )
  47. {
  48.     // Можно 8 раз сделать ReadBit, но все равно их надо приготовить в байт.
  49.     // Поэтому сразу делаем нужный байт.
  50.     assert( readBitsCount <= 8 );
  51.     assert( readBitsCount != 0 );
  52.     if( readBitsCount == 8 ) {
  53.         return stream.Read( value );
  54.     }
  55.     const byte upper = lastByte << readBitsCount;
  56.     if( !stream.Read( lastByte ) ) {
  57.         return false;
  58.     }
  59.     const byte lower = lastByte >> ( 8 - readBitsCount );
  60.     value = upper | lower;
  61.     return true;
  62. }
  63.  
  64. class CInputStream : public IInputStream {
  65. public:
  66.     explicit CInputStream( vector<byte>&& source );
  67.  
  68.     // Возвращает false, если поток закончился
  69.     virtual bool Read( byte& value ) override;
  70.  
  71. private:
  72.     vector<byte> data;
  73.     int readBytesCount;
  74. };
  75.  
  76. CInputStream::CInputStream( vector<byte>&& source ) :
  77.     data( std::move( source ) ),
  78.     readBytesCount( 0 )
  79. {
  80. }
  81.  
  82. bool CInputStream::Read( byte& value )
  83. {
  84.     if( readBytesCount >= static_cast<int>( data.size() ) ) {
  85.         return false;
  86.     }
  87.     value = data[readBytesCount++];
  88.     return true;
  89. }
  90.  
  91. int main()
  92. {
  93.     vector<byte> source = { 3, 8, 255, 0, 1 };
  94.     CInputStream inputStream( std::move( source ) );
  95.     CInputBitStream inputBitStream( inputStream );
  96.  
  97.     bool boolValue = false;
  98.     inputBitStream.ReadBit( boolValue ); // 0
  99.     inputBitStream.ReadBit( boolValue ); // 0
  100.     inputBitStream.ReadBit( boolValue ); // 0
  101.     inputBitStream.ReadBit( boolValue ); // 0
  102.     inputBitStream.ReadBit( boolValue ); // 0
  103.     inputBitStream.ReadBit( boolValue ); // 0
  104.     inputBitStream.ReadBit( boolValue ); // 1
  105.     inputBitStream.ReadBit( boolValue ); // 1
  106.     inputBitStream.ReadBit( boolValue ); // 0
  107.     byte value = 0;
  108.     inputBitStream.ReadByte( value ); // 17
  109.     return 0;
  110. }
RAW Paste Data