基于位操作的类CBitBuffer

http://tech.ddvip.com   2007年03月16日    社区交流

本文详细介绍基于位操作的类CBitBuffer

  二、类实现

#include "BitBuffer.h"
#include "math.h"
#define BYTEBITS 8
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBitBuffer::CBitBuffer()
{
m_llLength= 0; // The count in bits of buffer
m_pBegin= NULL; // The beginning pointer of buffer, the last byte.
m_pEnd = NULL; // The ending pointer of buffer
m_pCurByte= NULL; // The current pointer in byte of buffer
m_nCurOffset= 0; // The offset in bits from current pointer
m_bLocked= FALSE;// Whether the buffer is locked
}
CBitBuffer::CBitBuffer(BYTE *pBegin, LONGLONG llLen)
{
m_llLength= llLen; // The count in bits of buffer
m_pBegin= pBegin; // The beginning pointer of buffer, the last byte.
m_pCurByte= pBegin; // The current pointer in byte of buffer
m_nCurOffset= 0; // The offset in bits from current pointer
m_pEnd = pBegin + llLen / BYTEBITS; // The ending pointer of buffer
m_bLocked= FALSE; // Whether the buffer is locked
}
CBitBuffer::~CBitBuffer()
{
}
// Seek to the ending of buffer
// Return the length of the buffer in bits
LONGLONG CBitBuffer::SeekToEnd()
{
m_pCurByte = m_pEnd;
m_nCurOffset = 0;
return m_llLength;
}
// Seek to the beginning of buffer
void CBitBuffer::SeekToBegin()
{
m_pCurByte = m_pBegin;
m_nCurOffset = 0;
}
// Seek from current pointer in bits
// Return the new bit offset from the beginning of the buffer
// (in) llOff: The offset in bits from current pointer in bits
LONGLONG CBitBuffer::Seek(LONGLONG llOff)
{
LONGLONG pos = (m_pCurByte - m_pBegin) * BYTEBITS + m_nCurOffset;
pos += llOff;
if(pos < 0 || pos > m_llLength)
 return -1;
m_pCurByte = m_pBegin + pos / BYTEBITS;
m_nCurOffset = pos % BYTEBITS;
return pos;
}
LONGLONG CBitBuffer::GetLength()
{
return m_llLength;
}
LONGLONG CBitBuffer::SetLength(LONGLONG llLen)
{
if(m_bLocked)
 return -1;
LONGLONG temp = m_llLength;
m_pEnd = m_pBegin + llLen / BYTEBITS;
if(m_pCurByte > m_pEnd)
{
 m_pCurByte = NULL;
 m_nCurOffset = 0;
}
m_llLength = llLen;
return temp;
}
BOOL CBitBuffer::ShareBuffer(BYTE *pBegin, LONGLONG llLen)
{
if(m_bLocked || pBegin == NULL)
 return FALSE;
m_llLength= llLen; // The count in bits of buffer
m_pBegin= pBegin; // The beginning pointer of buffer, the last byte.
m_pCurByte= pBegin; // The current pointer in byte of buffer
m_nCurOffset= 0; // The offset in bits from current pointer
m_pEnd = pBegin + llLen / BYTEBITS; // The ending pointer of buffer
m_bLocked= FALSE; // Whether the buffer is locked
return TRUE;
}
BOOL CBitBuffer::Create(LONGLONG llLen)
{
if(m_bLocked)
 return FALSE;
m_pBegin = (BYTE*)malloc(llLen / BYTEBITS);
if(m_pBegin == NULL)
 return FALSE;
m_llLength = llLen;
m_pCurByte = m_pBegin;
m_nCurOffset = 0;
m_pEnd = m_pBegin + llLen / BYTEBITS;
m_bLocked = TRUE;
return TRUE;
}
void CBitBuffer::Release()
{
if(m_bLocked && m_pBegin)
{
 free(m_pBegin);
 m_pBegin = NULL;
 m_pCurByte = NULL;
 m_nCurOffset = 0;
 m_pEnd = NULL;
 m_bLocked = FALSE;
 
}
else if(m_bLocked == FALSE)
{
 m_pBegin= NULL;
 m_pCurByte= NULL;
 m_nCurOffset= 0;
 m_pEnd = NULL;
}
}
int CBitBuffer::Read(BYTE nCount)
{
DWORD64 D64 = *((DWORD64*)m_pCurByte);
D64 = (D64 >> 8*0 << (64-8)) |
  (D64 >> 8*1 << (64-8) >> (8*1)) |
  (D64 >> 8*2 << (64-8) >> (8*2)) |
  (D64 >> 8*3 << (64-8) >> (8*3)) |
  (D64 >> 8*4 << (64-8) >> (8*4)) |
  (D64 >> 8*5 << (64-8) >> (8*5)) |
  (D64 >> 8*6 << (64-8) >> (8*6)) |
  (D64 >> 8*7 << (64-8) >> (8*7)) ;
  
int re = (int)(D64 << m_nCurOffset >> (64-nCount));
m_pCurByte += (m_nCurOffset + nCount)/8;
m_nCurOffset = (m_nCurOffset + nCount)%8;
return re;
}
void CBitBuffer::WriteBinary(char * pBinStr)
{
int len = strlen(pBinStr);
for(int i=0;i<len;i++)
{
 if(pBinStr[i] == '1')
 {
 WriteBit1();
 }
 else if(pBinStr[i] == '0')
 {
 WriteBit0();
 }
 else if(pBinStr[i] == '*')
 {
 Seek(1);
 }
}
}
void CBitBuffer::WriteHex(char * pHexStr)
{
// Before use this function you should make sure BYTE ALIGNED and CAPITAL LETTER .
// Here do not verify anything, you should verify before call this function.
int len = strlen(pHexStr);
int iActualLen=0;
int h;
for(int i=0;i<len;i++)
{
 if(pHexStr[i] >= '0' && pHexStr[i] <= '9')
 {
 if((iActualLen++)%2==0)
  h = pHexStr[i]-'0';
 else
 {
  *m_pCurByte = h*16 + pHexStr[i] - '0';
  m_pCurByte++;
 }
 }
 else if(pHexStr[i] >= 'A' && pHexStr[i] <= 'F')
 {
 if((iActualLen++)%2==0)
  h = pHexStr[i]-'A'+10;
 else
 {
  *m_pCurByte = h*16 + pHexStr[i]-'A'+10;
  m_pCurByte++;
 }
 }
 else if(pHexStr[i] >= 'a' && pHexStr[i] <= 'f')
 {
 if((iActualLen++)%2==0)
  h = pHexStr[i]-'a'+10;
 else
 {
  *m_pCurByte = h*16 + pHexStr[i]-'a'+10;
  m_pCurByte++;
 }
 }
}
if(iActualLen%2 == 1)
{
 *m_pCurByte = *m_pCurByte & 0x0F | (((BYTE)h)<<4);
 m_nCurOffset = 4;
}
}
BOOL CBitBuffer::IsByteAligned()
{
if(m_nCurOffset == 0)
 return TRUE;
else
 return FALSE;
}
void CBitBuffer::WriteDecimal(UINT nData, int nCount)
{
//!!nCount<=32
int nByteCountNeed = (m_nCurOffset + nCount - 1)/BYTEBITS + 1;
//Head:
DWORD64 head = (*m_pCurByte) >> (BYTEBITS-m_nCurOffset)<< (BYTEBITS-m_nCurOffset) + 7*BYTEBITS;
//Bottom:
int b = BYTEBITS-(nByteCountNeed*8-m_nCurOffset-nCount);
DWORD64 bottom = (DWORD64)((BYTE)(*(m_pCurByte+nByteCountNeed-1) << (BYTEBITS-b)) >> b) << (64-nByteCountNeed*8);
BYTE test = *(m_pCurByte+nByteCountNeed-1) << (BYTEBITS-b);
test = test >> b;
//Center:
DWORD64 center = (DWORD64)nData << (64-m_nCurOffset-nCount);
//Result;
DWORD64 resu = head | center | bottom;
 BYTE * pResu = (BYTE *)(&resu);
int n = 0;
for(int i=7;i>=8-nByteCountNeed;i--)
{
 if(n==0 && m_nCurOffset!=0)
 {
 *(m_pCurByte+n) = *(m_pCurByte+n) >> (BYTEBITS-m_nCurOffset) << (BYTEBITS-m_nCurOffset) | pResu[i];
 }
 else
 *(m_pCurByte+n) = pResu[i];
 n++;
}
m_pCurByte += (m_nCurOffset+nCount)/8;
m_nCurOffset = (m_nCurOffset+nCount)%8;
}
void CBitBuffer::WriteBuffer(BYTE *pSubBuff, int nCount)
{
memcpy(m_pCurByte,pSubBuff,nCount);
m_nCurOffset = 0;
}
BYTE * CBitBuffer::GetBegin()
{
return m_pBegin;
}
BYTE * CBitBuffer::GetEnd()
{
return m_pEnd;
}
BYTE * CBitBuffer::GetCurByte()
{
return m_pCurByte;
}
BYTE CBitBuffer::GetCurOffset()
{
return m_nCurOffset;
}
BOOL CBitBuffer::IsLocked()
{
return m_bLocked;
}
void CBitBuffer::WriteBit1()
{
*m_pCurByte = *m_pCurByte | (0x80>>m_nCurOffset);
m_nCurOffset++;
if(m_nCurOffset >= 8)
{
 m_pCurByte ++;
 m_nCurOffset = 0;
}
}
void CBitBuffer::WriteBit0()
{
*m_pCurByte = *m_pCurByte & (~(0x80>>m_nCurOffset));
m_nCurOffset++;
if(m_nCurOffset >= 8)
{
 m_pCurByte ++;
 m_nCurOffset = 0;
}
}

作者:阳光    责编:豆豆技术应用

正在加载评论...