Back to index

CBitStream16.h

 
//----------------------------------------------------------------------------- 
//  $Header: CBitStream16.h,v 2.2 96/10/17 15:36:53 messer Exp $ 
// 
//  COOL Program Library   
//  Copyright (C) CERES collaboration, 1995, 1996 
// 
//  Declaration and implementation of class CBitStream16. 
// 
//  Extract n bits from a 16 bit aligned buffer of any length, 
//  where n must be in the range [1...16]. 
// 
//----------------------------------------------------------------------------- 
#ifndef CBITSTREAM16_H 
#define CBITSTREAM16_H 
 
class CBitStream16 { 
#ifdef ARCH_IS_LITTLE_ENDIAN 
  enum { SHORTHI = 0, SHORTLO = 1 }; 
#else 
  enum { SHORTHI = 1, SHORTLO = 0 }; 
#endif 
public: 
   inline CBitStream16(const unsigned short*, unsigned int);    
    
   inline unsigned long peek(unsigned int=1);   // tells you what to expect for the next 'next()' 
   inline unsigned long next(unsigned int=1);	// extracts the next bits 
   inline int eos() const;			// returns True if end-of-stream is reached 
   inline int bad() const;			// returns True if error bit is set 
   inline int count() const;			// returns number of bits extracted so far 
    
private:    
   int  maxbits; 
   int  bitpos;					// running from 0 to lastbit 
   unsigned short *buffer; 
   int error; 
    
private: 
   CBitStream16(); 
   CBitStream16(const CBitStream16&); 
}; 
 
 
int CBitStream16::eos() const {return bitpos >= maxbits;} 
int CBitStream16::bad() const {return error != 0;} 
int CBitStream16::count() const {return bitpos;} 
 
CBitStream16::CBitStream16() { /* nop */ }                                 
CBitStream16::CBitStream16(const CBitStream16&) { /* nop */ } 
 
CBitStream16::CBitStream16(const unsigned short* chunk, unsigned int chunkbits) 
{ 
   maxbits = int(chunkbits); 
   buffer  = (unsigned short*)chunk; 
   bitpos  = 0; 
   error   = 0; 
} 
 
unsigned long CBitStream16::peek(unsigned int nbits) 
{ 
   const int MaxExtraction = 16; 
   const int BitsInByte    = 8; 
   const int BitsInShort   = 16; 
   const int BitsInLong    = 32; 
   union { 
      unsigned long Long;		// contains later the requested bits right-adjusted  
      unsigned short Short[2]; 
   } result; 
 
   error = (nbits+bitpos > maxbits);	// check if enough bits in buffer to extract nbits 
   error += (nbits > MaxExtraction);	// request exceeds limit 
    
   if (nbits && !error) {  
      int firstShort = bitpos/BitsInShort;	// first short where extraction starts 
       
      // 
      //  Swap order of shorts to give a continuous stream 
      // 
      result.Short[SHORTHI] = buffer[firstShort];        
      result.Short[SHORTLO] = buffer[firstShort+1];  
       
      // 
      //  Right-adjust bits to be extracted and zero the rest  
      // 
      result.Long >>= (firstShort > 0 ? bitpos%(firstShort*BitsInShort) : bitpos); 
      result.Long &= ~(~0L << nbits);  
             
     } 
   return result.Long; 
} 
 
unsigned long CBitStream16::next(unsigned int nbits) 
{	 
   union { 
      unsigned long Long;		// contains later the requested bits right-adjusted  
      unsigned short Short[2]; 
   } result; 
  result.Long = peek(nbits); 
  if (nbits && !error) { 
    bitpos += nbits;				// next bit in buffer 
  } 
   
  return result.Long; 
 
} 
 
 
#endif /* CBITSTREAM16_H */ 

Back to index