/* bit_res.cpp

   Implementation of Bit Reservoir for Layer III

   Adapted from the public c code by Jeff Tsay. */


//
//
// optimizing hgetbits() to getonebit() by Timo Jantunen (jeti@iki.fi)
//
//

#include <stdio.h>
#include <stdlib.h>
#include "all.h"
#include "bit_res.h"

Bit_Reserve::Bit_Reserve ()
{
  uint32 shifted_one = 1;

  offset  = 0;
  totbit  = 0;
  buf_byte_idx = 0;
  //buf          = new uint32[BUFSIZE];
  buf          = new uint8[BUFSIZE];
  buf_bit_idx  = 8;
  //putmask      = new uint32[32];
  putmask      = new uint8[32];

  putmask[0] = 0;

  for (int32 i=1; i<32; i++) {
    putmask[i] = putmask[i-1] + shifted_one;
    shifted_one <<= 1;
  }
}

Bit_Reserve::~Bit_Reserve ()
{
  delete [] putmask;
  delete [] buf;
}

uint32 Bit_Reserve::hgetbits(uint32 N)
  // read N bits from the bit stream
{
 totbit += N;

 uint32 val = 0;
 int32 j = N;

 while (j > 0) {
uint32 pp=j;
int32 k;
   if (buf_bit_idx == 0) {
          buf_bit_idx = 8;
             buf_byte_idx++;
	     /*      if (buf_byte_idx > offset)
          { printf("Buffer overflow !!\n");exit(3); } */
   }
//{  pp=j;

//   int32 
k = (pp < buf_bit_idx) ? j : buf_bit_idx;
//}
   // BUFSIZE = 4096 = 2^12, so
   // buf_byte_idx%BUFSIZE == buf_byte_idx & 0xfff
   int32 tmp = buf[buf_byte_idx & 0xfff] & putmask[buf_bit_idx];
   buf_bit_idx -= k;
   tmp = tmp >> buf_bit_idx;
   j -=k;
   val |= tmp << j;
 }
 return(val);
}

void Bit_Reserve::rewindNbits(int32 N)
{
  totbit -= N;
  buf_bit_idx += N;
  while(buf_bit_idx >= 8) {
    buf_bit_idx -= 8;
    buf_byte_idx--;
  }
}

void Bit_Reserve::rewindNbytes(int32 N)
{
  totbit -= (N << 3);
  buf_byte_idx -= N;
//   totbit -= (N << 3);
//   buf_byte_idx -= N>>2;
//   buf_bit_idx -= N&3;
}

