////////////////////////////////////////////////////////////////////////////
//
// Bit input and output classes
// (c)2003 Jeremy Collake and Bitsum Technologies
// jeremy@bitsum.com
//
// This code may not be used without the permission of Bitsum Technologies.
// To use this code in your application, please email us at support@bitsum.com
// and we will be happy to grant you a free license.
//
//////////////////////////////////////////////////////////////////////////////
#include "bitio.h"
#include <excpt.h>
bitout::bitout(PSTREAM plStream)
{
pStream=plStream;
cByte=0;
nBitCount=1; // must be initialized to 1
}
bitout::~bitout()
{
// in case stream is deallocated before
// destructor is called, we must catch exception.
__try
{
Flush();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
void bitout::EmitBit(BIT bBit)
{
cByte<<=1;
cByte|=(unsigned int)bBit;
nBitCount<<=1;
if(!nBitCount)
{
*pStream=cByte;
pStream++;
nBitCount=1;
}
}
void bitout::EmitByte(BYTE ctByte)
{
for(unsigned int nI=0;nI<8;nI++)
{
EmitBit((bool)(ctByte>>7));
ctByte<<=1;
}
}
void bitout::EmitBits(DWORD ctByte, DWORD nBits)
{
ctByte<<=(31-nBits+1);
for(unsigned int nI=0;nI<nBits;nI++)
{
EmitBit((bool)(ctByte>>31));
ctByte<<=1;
}
}
void bitout::Flush()
{
while(nBitCount!=1)
{
EmitBit(false);
}
}
PSTREAM bitout::ptr()
{
return pStream;
}
// the following save and restore the current
// stream position. Please note that this
// mechanism only allows for one push, obviously.
// Since more are not needed, a more complex
// structure will hinder performance. Implement
// typical stack if more are needed at any
// point.
void bitout::push()
{
pushed_nBitCount=nBitCount;
pushed_cByte=cByte;
pushed_pStream=pStream;
}
void bitout::pop()
{
nBitCount=pushed_nBitCount;
cByte=pushed_cByte;
pStream=pushed_pStream;
}
// emit word w to the stream
void bitout::EmitWord(WORD w)
{
for(unsigned int nI=0;nI<16;nI++)
{
EmitBit((bool)(w>>15));
w<<=1;
}
}
void bitout::EmitDword(DWORD dw)
{
for(unsigned int nI=0;nI<32;nI++)
{
EmitBit((bool)(dw>>31));
dw<<=1;
}
}
bitin::bitin(PSTREAM plStream)
{
pStream=plStream;
cByte=0;
nBitCount=0;
}
BIT bitin::GetBit()
{
nBitCount>>=1;
if(!nBitCount)
{
cByte=*pStream;
pStream++;
nBitCount=0x80;
}
return cByte&nBitCount?true:false;
}
BYTE bitin::GetByte()
{
BYTE cR=0;
for(unsigned int nI=0;nI<8;nI++)
{
cR|=GetBit()<<(7-nI);
}
return cR;
}
WORD bitin::GetWord()
{
WORD w=0;
for(unsigned int nI=0;nI<16;nI++)
{
w|=GetBit()<<(15-nI);
}
return w;
}
DWORD bitin::GetDword()
{
DWORD dw=0;
for(unsigned int nI=0;nI<32;nI++)
{
dw|=GetBit()<<(31-nI);
}
return dw;
}
DWORD bitin::GetBits(DWORD dwBits)
{
DWORD dwR=0;
for(unsigned int nI=0;nI<dwBits;nI++)
{
dwR|=GetBit()<<((dwBits-1)-nI);
}
return dwR;
}