smatskevich

Streams for Huffman code

Dec 10th, 2016
141
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <assert.h>
  2. #include <string>
  3. using std::string;
  4.  
  5. class CBitOStream {
  6. public:
  7.     CBitOStream();
  8.     void WriteBit( bool bit );
  9.     void WriteByte( unsigned char byte );
  10.     // Закрывает поток - перебрасывает буфер в результирующую строку, дописывает число бит в последнем байте.
  11.     void Close();
  12.  
  13.     // Получить результат можно только после Close.
  14.     string GetResult() const;
  15.  
  16. private:
  17.     string result;
  18.     unsigned char buffer;
  19.     char bitsInBuffer;
  20.     bool isClosed;
  21. };
  22.  
  23. CBitOStream::CBitOStream() :
  24.     buffer( 0 ),
  25.     bitsInBuffer( 0 ),
  26.     isClosed( false )
  27. {
  28. }
  29.  
  30. void CBitOStream::WriteBit( bool bit )
  31. {
  32.     assert( !isClosed );
  33.  
  34.     // Устанавливаем или сбрасываем нужный бит. Первыми битами считаем старшие.
  35.     if( bit ) {
  36.         buffer |= 1 << ( 7 - bitsInBuffer );
  37.     } else {
  38.         buffer &= ~( 1 << ( 7 - bitsInBuffer ) );
  39.     }
  40.     ++bitsInBuffer;
  41.     if( bitsInBuffer == 8 ) {
  42.         // Буфер закончился. Сбрасываем в результирующую строку.
  43.         result.push_back( buffer );
  44.         buffer = 0;
  45.         bitsInBuffer = 0;
  46.     }
  47. }
  48.  
  49. void CBitOStream::WriteByte( unsigned char byte )
  50. {
  51.     assert( !isClosed );
  52.  
  53.     buffer |= byte >> ( bitsInBuffer ); // Пользуемся тем, что оставшиеся с buffer байты нулевые.
  54.     unsigned char nextBuffer = byte << ( 8 - bitsInBuffer );
  55.  
  56.     // Сбрасываем буфер в результирующую строку.
  57.     result.push_back( buffer );
  58.     buffer = nextBuffer;
  59. }
  60.  
  61. void CBitOStream::Close()
  62. {
  63.     assert( !isClosed );
  64.  
  65.     if( bitsInBuffer == 0 ) {
  66.         // Дописываем, что в последнем байте 8 значащих бит.
  67.         result.push_back( 8 );
  68.     } else {
  69.         // Скидываем недозаполненный буфер и количество значащих бит.
  70.         result.push_back( buffer );
  71.         result.push_back( bitsInBuffer );
  72.     }
  73.     isClosed = true;
  74. }
  75.  
  76. string CBitOStream::GetResult() const
  77. {
  78.     assert( isClosed );
  79.     return result;
  80. }
  81.  
  82. // ----------------------------------------------------------------------------------------------------------
  83.  
  84. class CBitIStream {
  85. public:
  86.     explicit CBitIStream( const string& _source );
  87.  
  88.     // Чтение неоконченного потока.
  89.     bool ReadBit();
  90.     unsigned char ReadByte();
  91.  
  92.     bool IsFinished() const;
  93.  
  94. private:
  95.     const string source;
  96.     int bitsCount; // Общее число бит.
  97.     int pos; // Считанное число бит.
  98. };
  99.  
  100. CBitIStream::CBitIStream( const string& _source ) :
  101.     source( _source ),
  102.     pos( 0 )
  103. {
  104.     assert( !source.empty() );
  105.  
  106.     // Общее число бит.
  107.     bitsCount = 8 * ( source.length() - 2 ) + source[source.length() - 1];
  108. }
RAW Paste Data