Add bitbuf getters

This commit is contained in:
Kawe Mazidjatari 2023-08-21 11:28:55 +02:00
parent 650f961fb0
commit c344dde672
2 changed files with 124 additions and 14 deletions

View File

@ -108,10 +108,10 @@ class CBitBuffer
{
public:
CBitBuffer(void);
inline void SetDebugName(const char* pName) { m_pDebugName = pName; }
inline const char* GetDebugName() const { return m_pDebugName; }
inline bool IsOverflowed() const { return m_bOverflow; }
inline void SetOverflowFlag() { m_bOverflow = true; }
FORCEINLINE void SetDebugName(const char* pName) { m_pDebugName = pName; }
FORCEINLINE const char* GetDebugName() const { return m_pDebugName; }
FORCEINLINE bool IsOverflowed() const { return m_bOverflow; }
FORCEINLINE void SetOverflowFlag() { m_bOverflow = true; }
////////////////////////////////////
const char* m_pDebugName;
@ -135,12 +135,23 @@ public:
void GrabNextDWord(bool bOverFlowImmediately = false);
void FetchNext();
int64 GetNumBitsRead(void) const;
FORCEINLINE int64 GetNumBytesRead(void) const { return ((GetNumBitsRead() + 7) >> 3); }
int ReadSBitLong(int numbits);
uint32 ReadUBitLong(int numbits);
inline int ReadByte() { return ReadSBitLong(sizeof(unsigned char) << 3); }
inline int ReadChar() { return ReadSBitLong(sizeof(char) << 3); }
bool ReadString(char* pStr, int bufLen, bool bLine = false, int* pOutNumChars = nullptr);
FORCEINLINE int ReadChar() { return ReadSBitLong(sizeof(char) << 3); }
FORCEINLINE int ReadByte() { return ReadSBitLong(sizeof(unsigned char) << 3); }
FORCEINLINE int ReadShort() { return ReadUBitLong(sizeof(short) << 3); }
FORCEINLINE int ReadWord() { return ReadUBitLong(sizeof(unsigned short) << 3); }
FORCEINLINE int ReadLong() { return ReadUBitLong(sizeof(int32) << 3); }
int64 ReadLongLong();
float ReadFloat();
void ReadBits(void* pOutData, int nBits);
bool ReadBytes(void* pOut, int nBytes);
bool ReadString(char* pStr, int bufLen, bool bLine = false, int* pOutNumChars = nullptr);
////////////////////////////////////
uint32 m_nInBufWord;
@ -190,12 +201,12 @@ public:
inline bool WriteBytes(const void* pIn, int nBytes) { return WriteBits(pIn, nBytes << 3); }
// How many bytes are filled in?
inline int GetNumBytesWritten() const { return BitByte(this->m_iCurBit); }
inline int GetNumBitsWritten() const { return this->m_iCurBit; }
inline int GetMaxNumBits() const { return this->m_nDataBits; }
inline int GetNumBitsLeft() const { return this->m_nDataBits - m_iCurBit; }
inline int GetNumBytesLeft() const { return this->GetNumBitsLeft() >> 3; }
inline unsigned char* GetData() const { return this->m_pData; }
FORCEINLINE int GetNumBytesWritten() const { return BitByte(this->m_iCurBit); }
FORCEINLINE int GetNumBitsWritten() const { return this->m_iCurBit; }
FORCEINLINE int GetMaxNumBits() const { return this->m_nDataBits; }
FORCEINLINE int GetNumBitsLeft() const { return this->m_nDataBits - m_iCurBit; }
FORCEINLINE int GetNumBytesLeft() const { return this->GetNumBitsLeft() >> 3; }
FORCEINLINE unsigned char* GetData() const { return this->m_pData; }
inline const char* GetDebugName() const { return this->m_pDebugName; }
inline void SetDebugName(const char* pDebugName) { m_pDebugName = pDebugName; }
@ -204,7 +215,7 @@ public:
bool CheckForOverflow(int nBits);
void SetOverflowFlag();
inline bool IsOverflowed() const { return this->m_bOverflow; }
FORCEINLINE bool IsOverflowed() const { return this->m_bOverflow; }
private:
// The current buffer.
unsigned char* m_pData;

View File

@ -205,6 +205,21 @@ void CBitRead::FetchNext()
GrabNextDWord(false);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int64 CBitRead::GetNumBitsRead(void) const
{
if (!m_pData) // pesky null ptr bitbufs. these happen.
return 0;
int64 nCurOfs = int64(((intp(m_pDataIn) - intp(m_pData)) / 4) - 1);
nCurOfs *= 32;
nCurOfs += (32 - m_nBitsAvail);
int64 nAdjust = 8 * (m_nDataBytes & 3);
return MIN(nCurOfs + nAdjust, m_nDataBits);
}
//-----------------------------------------------------------------------------
// Purpose: reads an unsigned integer from the buffer
//-----------------------------------------------------------------------------
@ -250,6 +265,90 @@ int CBitRead::ReadSBitLong(int numbits)
return (nRet << (32 - numbits)) >> (32 - numbits);
}
//-----------------------------------------------------------------------------
// Purpose: reads a signed 64-bit integer from the buffer
//-----------------------------------------------------------------------------
int64 CBitRead::ReadLongLong()
{
int64 retval;
uint* pLongs = (uint*)&retval;
// Read the two DWORDs according to network endian
const short endianIndex = 0x0100;
byte* idx = (byte*)&endianIndex;
pLongs[*idx++] = ReadUBitLong(sizeof(long) << 3);
pLongs[*idx] = ReadUBitLong(sizeof(long) << 3);
return retval;
}
//-----------------------------------------------------------------------------
// Purpose: reads a float from the buffer
//-----------------------------------------------------------------------------
float CBitRead::ReadFloat()
{
float ret;
Assert(sizeof(ret) == 4);
ReadBits(&ret, 32);
// Swap the float, since ReadBits reads raw data
LittleFloat(&ret, &ret);
return ret;
}
//-----------------------------------------------------------------------------
// Purpose: reads bits from the buffer
//-----------------------------------------------------------------------------
void CBitRead::ReadBits(void* pOutData, int nBits)
{
unsigned char* pOut = (unsigned char*)pOutData;
int nBitsLeft = nBits;
// align output to dword boundary
while (((uintp)pOut & 3) != 0 && nBitsLeft >= 8)
{
*pOut = (unsigned char)ReadUBitLong(8);
++pOut;
nBitsLeft -= 8;
}
// X360TBD: Can't read dwords in ReadBits because they'll get swapped
if (IsPC())
{
// read dwords
while (nBitsLeft >= 32)
{
*((uint32*)pOut) = ReadUBitLong(32);
pOut += sizeof(uint32);
nBitsLeft -= 32;
}
}
// read remaining bytes
while (nBitsLeft >= 8)
{
*pOut = (unsigned char)ReadUBitLong(8);
++pOut;
nBitsLeft -= 8;
}
// read remaining bits
if (nBitsLeft)
{
*pOut = (unsigned char)ReadUBitLong(nBitsLeft);
}
}
//-----------------------------------------------------------------------------
// Purpose: reads bytes from the buffer
//-----------------------------------------------------------------------------
bool CBitRead::ReadBytes(void* pOut, int nBytes)
{
ReadBits(pOut, nBytes << 3);
return !IsOverflowed();
}
//-----------------------------------------------------------------------------
// Purpose: reads a string from the buffer
//-----------------------------------------------------------------------------