//////////////////////////////////////////////////////////////////////////// // // 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; }