Files
Sun1602/Utility/BitStream.hpp
T
2022-10-26 12:25:11 +08:00

234 lines
5.1 KiB
C++

#pragma once
#ifndef UTILITY_BITSTREAM_V1_H
#define UTILITY_BITSTREAM_V1_H
#define USING_BITSTREAM_VERSION (2)
#if (USING_BITSTREAM_VERSION == 2)
#include "./BitStream_v2.hpp"
#elif (USING_BITSTREAM_VERSION == 1)
#include "assert.h"
#include <fstream>
#define BITS_TO_BYTES(x) (((x)+7)>>3)
#define BYTES_TO_BITS(x) ((x)<<3)
#define DEBUG_BIT_STREAM
//#define DEBUG_BIT_STREAM_TEST
class BitStream
{
public:
BitStream( BYTE * p, WORD wNumberOfByte, BOOL TF)
:m_pBuffer(p), m_BufferMaxSizeByte(wNumberOfByte), m_Offset(0)
{
if(TF)
{
memset(m_pBuffer,0, wNumberOfByte);
#ifdef DEBUG_BIT_STREAM_TEST
FileStream.open( "Temp\\WriteBit.txt", ios::out );
#endif
}
else
{
#ifdef DEBUG_BIT_STREAM_TEST
FileStream.open( "Temp\\ReadBit.txt", ios::out );
#endif
}
}
~BitStream()
{
#ifdef DEBUG_BIT_STREAM_TEST
FileStream.close();
#endif
}
public:
void SetBuf( BYTE * p, WORD wNumberOfByte, BOOL TF)
{
m_Offset=0;
m_pBuffer=p;
m_BufferMaxSizeByte=wNumberOfByte;
if(TF)
memset(m_pBuffer,0, wNumberOfByte);
}
template<class TYPE>
__inline void Write( TYPE type, int NumberOfBits )
{
if( NumberOfBits <= 0)
return;
Write(&type, NumberOfBits);
}
template<class TYPE>
__inline void Read( TYPE & type, int NumberOfBits )
{
if( NumberOfBits <= 0)
return;
memset(&type, 0, sizeof(TYPE));
Read(&type, NumberOfBits);
}
template<class TYPE>
__inline void Write( TYPE * pvBuf, int NumberOfBits)
{
if( NumberOfBits <= 0 )
return;
assert( m_Offset + NumberOfBits <= BYTES_TO_BITS(m_BufferMaxSizeByte) );
if(m_Offset + NumberOfBits > BYTES_TO_BITS(m_BufferMaxSizeByte) )
return;
#ifdef DEBUG_BIT_STREAM_TEST
FileStream << endl;
FileStream << NumberOfBits << endl;
#endif
const BYTE* pBuffer = reinterpret_cast<const BYTE*>(pvBuf);
//unit byte
int i = 0;
for(; i < (NumberOfBits >> 3); ++i)
{
WriteByte(*(pBuffer+i), 8);
#ifdef DEBUG_BIT_STREAM_TEST
FileStream << (DWORD)(*(pBuffer+i)) << ' ';
#endif
}
//unit bit
DWORD WriteBit = NumberOfBits % 8;
if( WriteBit > 0)
{
#ifdef DEBUG_BIT_STREAM
unsigned __int64 i64_Test = 1;
ASSERT(*(pBuffer+i) < (i64_Test << WriteBit));
#endif
WriteByte( (*(pBuffer+i)) << (8-WriteBit), WriteBit);
#ifdef DEBUG_BIT_STREAM_TEST
FileStream << (DWORD)(*(pBuffer+i)) << ' ';
#endif
}
}
template<class TYPE>
__inline void Read( TYPE * pvBuf, int NumberOfBits )
{
if( NumberOfBits <= 0)
return;
// assert( m_Offset + NumberOfBits <= BYTES_TO_BITS(m_BufferMaxSizeByte) );
if(m_Offset + NumberOfBits > BYTES_TO_BITS(m_BufferMaxSizeByte) )
return;
#ifdef DEBUG_BIT_STREAM_TEST
FileStream << endl;
FileStream << NumberOfBits << endl;
#endif
BYTE* pBuffer = reinterpret_cast<BYTE*>(pvBuf);
//unit byte
int i = 0;
for(; i < (NumberOfBits >> 3); ++i)
{
memset(pBuffer+i, 0, 1);
ReadByte( pBuffer+i, 8, 0);
#ifdef DEBUG_BIT_STREAM_TEST
FileStream << (DWORD)(*(pBuffer+i)) << ' ';
#endif
}
//unit bit
DWORD ReadBit = NumberOfBits % 8;
if( 0 != ReadBit )
{
memset(pBuffer+i, 0, 1);
ReadByte( pBuffer+i, ReadBit, 0);
*(pBuffer+i) = (*(pBuffer+i)) >> (8 - ReadBit);
#ifdef DEBUG_BIT_STREAM_TEST
FileStream << (DWORD)(*(pBuffer+i)) << ' ';
#endif
}
}
__inline int GetMaxBufferBytes() const { return m_BufferMaxSizeByte; }
__inline int GetReadOffset() const { return m_Offset; }
__inline int GetNumberOfBitsUsed() const { return m_Offset; }
__inline int GetNumberOfBytesUsed() const { return BITS_TO_BYTES(m_Offset); }
__inline void SetReadOffSet( const int offset ) { m_Offset = offset; }
__inline void SetWriteOffSet( const int offset ) { m_Offset = offset; }
private:
//WriteByte는 왼쪽비트부터 복사하므로 오른쪽 기준으로 복사시에는 왼쪽으로 쉬프트 해서 호출.
void WriteByte( BYTE Buffer, int NumberOfBits)
{
if(NumberOfBits <= 0)
return;
DWORD dwPortion = m_Offset >> 3;
DWORD dwRemain = m_Offset % 8;
m_pBuffer[dwPortion] |= (Buffer) >> dwRemain;
int EmptySpace = (8-dwRemain);
if(NumberOfBits > EmptySpace)
{
m_Offset += EmptySpace;
WriteByte((Buffer) << EmptySpace, NumberOfBits - EmptySpace);
}
else
{
m_Offset += NumberOfBits;
}
}
//ReadByte는 왼쪽비트부터 읽으므로 오른쪽 기준으로 복사를 원할시 호출후 오른쪽으로 쉬프트
void ReadByte( BYTE* pBuffer, int NumberOfBits, DWORD ReadPos )
{
if( NumberOfBits <= 0 )
return;
DWORD dwPortion = m_Offset >> 3;
DWORD dwRemain = m_Offset % 8;
//memset(pBuffer, 0 , 1);
int ReadSpace = (8-dwRemain);
if( NumberOfBits > ReadSpace )
{
*pBuffer |= m_pBuffer[dwPortion] << dwRemain;
m_Offset += ReadSpace;
ReadByte(pBuffer, NumberOfBits - ReadSpace, ReadPos+ReadSpace);
}
else
{
//쓰레기값 삭제
BYTE Temp = m_pBuffer[dwPortion] >> (ReadSpace - NumberOfBits);
Temp = Temp << (ReadSpace - NumberOfBits);
Temp = Temp << dwRemain;
*pBuffer |= Temp >> ReadPos;
m_Offset += NumberOfBits;
}
}
private:
#ifdef DEBUG_BIT_STREAM_TEST
std::ofstream FileStream;
#endif
BYTE * m_pBuffer;
int m_BufferMaxSizeByte;
int m_Offset;
};
#endif //(USING_BITSTREAM_VERSION == 1)
#endif //UTILITY_BITSTREAM_V1_H