|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 2000.
//
// File: BITSTM.cxx
//
// Contents: 'Bit Stream'
//
// Classes: CBitBuffer
//
// Classes: CBitStream, CWBitStream, CRBitStream
//
// History: 03-Jul-91 KyleP Created
// 24-Aug-92 BartoszM Rewrote it
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#pragma optimize( "t", on )
#include "bitstm.hxx"
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::CSmartBuffer, public
//
// Synopsis: Constructor.
//
// Arguments: [phStorage] -- Physical index -- source of pages
// [mode] -- Access mode for the index
//
// History: 02-Sep-92 BartoszM Created
//
//----------------------------------------------------------------------------
CSmartBuffer::CSmartBuffer ( CPhysStorage& phStorage, EAccessMode mode ) : _phStorage(phStorage), _pBuffer(0), _fWritable( mode == eWriteExisting ) { }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::CSmartBuffer, public
//
// Synopsis: Constructor.
//
// Arguments: [phStorage] -- Physical index -- source of pages
// [fCreate] -- Indicates if new buffer is needed
//
// History: 02-Sep-92 BartoszM Created
//
//----------------------------------------------------------------------------
CSmartBuffer::CSmartBuffer ( CPhysStorage& phStorage, BOOL fCreate ) : _phStorage(phStorage), _numPage(0), _fWritable(fCreate) { if (fCreate) { _pBuffer = _phStorage.BorrowNewBuffer(0);
IncrementSig();
#if CIDBG == 1
CheckCorruption(); #endif
} else { _pBuffer = _phStorage.BorrowBuffer( 0, _fWritable, _fWritable );
CheckCorruption(); } }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::CSmartBuffer, public
//
// Synopsis: Constructor.
//
// Arguments: [phStorage] -- Physical index -- source of pages
// [numPage] -- Page to encapsulate
// [mode] -- Access mode for the index
// [fIncrSig] -- Indicates if page should be signed
//
// History: 02-Sep-92 BartoszM Created
//
//----------------------------------------------------------------------------
CSmartBuffer::CSmartBuffer ( CPhysStorage& phStorage, ULONG numPage, EAccessMode mode, BOOL fIncrSig ) : _phStorage(phStorage), _numPage(numPage), _fWritable(mode == eWriteExisting) { _pBuffer = _phStorage.BorrowBuffer( _numPage, _fWritable, _fWritable );
if ( _fWritable && fIncrSig ) IncrementSig();
if (fIncrSig) CheckCorruption(); }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::CSmartBuffer, public
//
// Synopsis: Constructor.
//
// Arguments: [buf] -- Source CSmartBuffer
// [numPage] -- Page to acquire
//
// History: 02-Sep-92 BartoszM Created
//
//----------------------------------------------------------------------------
CSmartBuffer::CSmartBuffer ( CSmartBuffer& buf, ULONG numPage ) : _phStorage(buf._phStorage), _numPage(numPage), _fWritable(buf._fWritable) { _pBuffer = _phStorage.BorrowBuffer( _numPage, _fWritable, _fWritable );
if ( _fWritable ) IncrementSig();
CheckCorruption(); }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::~CSmartBuffer, public
//
// Synopsis: Destructor.
//
// History: 02-Sep-92 BartoszM Created
//
//----------------------------------------------------------------------------
CSmartBuffer::~CSmartBuffer () { if ( 0 != _pBuffer ) { // If a writable buffer still exists in this destructor we're in a
// failure path that must not THROW. Anything that really needs to
// be on disk should already be there by now, so this code path
// won't throw if it can't flush.
//
// If you see this debugout and you're not unwinding an exception,
// your code is broken.
// If a merge fails and you get this debugout, it's not a problem
//
if ( _fWritable && _phStorage.RequiresFlush( _numPage ) ) { IncrementSig(); ciDebugOut(( DEB_WARN, "deleting writable buffer in potential " "unwind path -- it may not get flushed\n" )); }
_phStorage.ReturnBuffer( _numPage, _fWritable, FALSE ); } }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::CheckCorruption, private
//
// Synopsis: Attempts to determine if the entire page wasn't written
// to disk.
//
// History: ? KyleP Created
//
//----------------------------------------------------------------------------
void CSmartBuffer::CheckCorruption() { if ( 0 == _pBuffer[0] || _pBuffer[0] != _pBuffer[SMARTBUF_PAGE_SIZE_IN_DWORDS + 1] ) { ciDebugOut(( DEB_ERROR, "Buffer at 0x%x corrupt (StartDword = 0x%x, EndDword = 0x%x)\n", _pBuffer, _pBuffer[0], _pBuffer[SMARTBUF_PAGE_SIZE_IN_DWORDS + 1] ));
Win4Assert( !"Index corruption." );
_phStorage.GetStorage().ReportCorruptComponent( ( 0 == _pBuffer[0] ) ? L"SmartBuffer1" : L"SmartBuffer2"); THROW( CException( CI_CORRUPT_DATABASE ) ); } }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::IncrementSig, private
//
// Synopsis: Increments the signature at the start and end of the page.
//
// History: ? KyleP Created
//
//----------------------------------------------------------------------------
void CSmartBuffer::IncrementSig() { Win4Assert( _pBuffer[0] == _pBuffer[SMARTBUF_PAGE_SIZE_IN_DWORDS + 1] );
_pBuffer[0]++; _pBuffer[SMARTBUF_PAGE_SIZE_IN_DWORDS + 1]++; }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::InitSignature, public
//
// Synopsis: Initializes the signature at the start and end of the page.
//
// History: ? KyleP Created
//
//----------------------------------------------------------------------------
void CSmartBuffer::InitSignature() { _pBuffer[0] = _pBuffer[SMARTBUF_PAGE_SIZE_IN_DWORDS + 1] = 1; }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::Refill, public
//
// Synopsis: Makes sure the given page is borrowed and ready to go
//
// Arguments: [numPage] -- The page requested
//
// History: 11/6/98 dlee Added Header
//
//----------------------------------------------------------------------------
void CSmartBuffer::Refill( ULONG numPage ) { if ( 0 != _pBuffer && _fWritable && _phStorage.RequiresFlush( _numPage ) ) { IncrementSig(); }
// first borrow next, then return previous to avoid reloading
ULONG * pOld = _pBuffer; unsigned numOldPage = _numPage; _pBuffer = _phStorage.BorrowBuffer( numPage, _fWritable, _fWritable ); _numPage = numPage;
if ( 0 != pOld ) _phStorage.ReturnBuffer( numOldPage, _fWritable );
Win4Assert( 0 != _pBuffer );
// increment signature
if ( _fWritable ) IncrementSig();
CheckCorruption(); }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::Next, public
//
// Synopsis: Makes sure the next page is borrowed and ready to go
//
// History: 11/6/98 dlee Added Header
//
//----------------------------------------------------------------------------
ULONG* CSmartBuffer::Next() { Win4Assert( 0 != _pBuffer );
if ( 0 != _pBuffer && _fWritable && _phStorage.RequiresFlush( _numPage ) ) IncrementSig();
ULONG * pOld = _pBuffer;
// first borrow next, then return previous to avoid reloading
_pBuffer = _phStorage.BorrowBuffer( _numPage+1, _fWritable, _fWritable ); _numPage++;
if ( 0 != pOld ) _phStorage.ReturnBuffer( _numPage-1, _fWritable );
Win4Assert( 0 != _pBuffer );
if ( _fWritable ) IncrementSig();
CheckCorruption();
return _pBuffer + 1; }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::NextNew, public
//
// Synopsis: Makes sure the next page is borrowed and ready to go
//
// History: 11/6/98 dlee Added Header
//
//----------------------------------------------------------------------------
ULONG* CSmartBuffer::NextNew() { Win4Assert( 0 != _pBuffer );
if ( _fWritable && _phStorage.RequiresFlush( _numPage ) ) IncrementSig();
// first borrow next, then return previous to avoid reloading
_pBuffer = _phStorage.BorrowNewBuffer(_numPage+1); _numPage++; Win4Assert ( _pBuffer != 0 ); _phStorage.ReturnBuffer( _numPage-1, _fWritable );
if ( _fWritable ) IncrementSig();
#if CIDBG == 1
CheckCorruption(); #endif
return _pBuffer + 1; }
//+---------------------------------------------------------------------------
//
// Member: CSmartBuffer::Free, public
//
// Synopsis: Frees the current page if and only if the underlying storage
// is writable. Useful for master merges where we want to
// unmap the old master index so it can be made sparse.
//
// History: 11/6/98 dlee Added Header
//
//----------------------------------------------------------------------------
void CSmartBuffer::Free() { //
// Only free the buffer if the stream (not necessarily the buffer)
// is writable, so the stream can be shrunk from the front during a
// master merge.
//
Win4Assert( _phStorage.IsWritable() );
if ( 0 != _pBuffer ) { if ( _fWritable && _phStorage.RequiresFlush( _numPage ) ) IncrementSig();
_phStorage.ReturnBuffer( _numPage, _fWritable ); _pBuffer = 0; } }
//+---------------------------------------------------------------------------
//
// Member: CBitStream::CBitStream, public
//
// Synopsis: Constructor. Does not load pages.
//
// Arguments: [physIndex] -- Physical index -- source of pages
//
// History: 02-Sep-92 BartoszM Created
//
//----------------------------------------------------------------------------
CBitStream::CBitStream(CPhysStorage& phStorage, CSmartBuffer::EAccessMode mode ) : _buffer(phStorage, mode), _oBuffer( 0 ) { }
//+---------------------------------------------------------------------------
//
// Member: CPBitStream::CPBitStream, public
//
// Synopsis: Constructor. Does not load any pages.
//
// Arguments: [physIndex] -- Physical index -- source of pages
//
// History: 02-Sep-92 BartoszM Created
//
//----------------------------------------------------------------------------
CPBitStream::CPBitStream(CPhysStorage& phStorage) : CBitStream ( phStorage, CSmartBuffer::eWriteExisting )
{ _bitOff.SetPage(0); _bitOff.SetOff(0); ciDebugOut (( DEB_BITSTM, "CPBitStream::CPBitStream\n" )); }
//+---------------------------------------------------------------------------
//
// Member: CBitStream::CBitStream, public
//
// Synopsis: Constructor. Starts at the beginning of index
//
// Arguments: [physIndex] -- Physical index -- source of pages
//
// History: 08-Jul-91 KyleP Created.
//
//----------------------------------------------------------------------------
CBitStream::CBitStream(CPhysStorage& phStorage, BOOL fCreate) : _buffer(phStorage, fCreate), _oBuffer( 0 )
{ ciDebugOut (( DEB_BITSTM, "CBitStream::CBitStream\n" ));
_pCurPos = _buffer.Get(); _pEndBuf = _pCurPos + SMARTBUF_PAGE_SIZE_IN_DWORDS; _cbitLeftDW = ULONG_BITS; }
//+---------------------------------------------------------------------------
//
// Member: CBitStream::CBitStream, public
//
// Synopsis: Constructor. Seek to a specified position.
//
// Arguments: [physIndex] -- Physical index -- source of pages
// [off] -- starting bit offset
// [mode] -- Check access mode
// [fIncrSig] -- Indicates if signature has to be incremented.
//
// History: 08-Jul-91 KyleP Created.
//
//----------------------------------------------------------------------------
CBitStream::CBitStream(CPhysStorage& phStorage, const BitOffset& off, CSmartBuffer::EAccessMode mode, BOOL fIncrSig ) : _buffer(phStorage, off.Page(), mode, fIncrSig), _oBuffer( 0 )
{ ciDebugOut(( DEB_BITSTM, "CBitStream::CBitStream %d:%d\n", off.Page(), off.Offset() )); SetPosition(off.Offset()); }
//+---------------------------------------------------------------------------
//
// Member: CBitStream::LoadNextPage, private
//
// Synopsis: Loads next page, positions stream at its beginning
//
// Requires: Page must already exits
//
// History: 28-Aug-92 BartoszM Created.
//
//----------------------------------------------------------------------------
void CBitStream::LoadNextPage() { _pCurPos = _buffer.Next(); _pEndBuf = _pCurPos + SMARTBUF_PAGE_SIZE_IN_DWORDS; _cbitLeftDW = ULONG_BITS; }
//+---------------------------------------------------------------------------
//
// Member: CBitStream::LoadNewPage, private
//
// Synopsis: Creates and loads new page following the current one
// Positions stream at its beginning
//
// History: 28-Aug-92 BartoszM Created.
//
// Notice: Page should be zero filled
//
//----------------------------------------------------------------------------
void CBitStream::LoadNewPage() { _pCurPos = _buffer.NextNew(); _pEndBuf = _pCurPos + SMARTBUF_PAGE_SIZE_IN_DWORDS; _cbitLeftDW = ULONG_BITS;
#if CIDBG == 1
ULONG* p = _buffer.Get(); for (int i=0; i < SMARTBUF_PAGE_SIZE_IN_DWORDS; i++) if (p[i] != 0) break; Win4Assert(i == SMARTBUF_PAGE_SIZE_IN_DWORDS); #endif
}
//+---------------------------------------------------------------------------
//
// Function: Refill
//
// Synopsis: Invalidates the currently cached copy and gets a new
// copy of the buffer. This is needed during master merge
// because we unmap the buffer before flushing and it is
// possible that the re-mapped buffer may be in a physically
// different location.
//
// History: 4-20-94 srikants Created
//
// Notes:
//
//----------------------------------------------------------------------------
void CBitStream::Refill() { BitOffset bitOff; GetOffset(bitOff);
_buffer.Refill(bitOff.Page()); SetPosition( bitOff.Offset() ); }
//+---------------------------------------------------------------------------
//
// Member: CBitStream::SetPosition, private
//
// Synopsis: Set bit position within a freshly loaded page
//
// Arguments: [off] -- number of bits to skip
//
// History: 28-Aug-92 BartoszM Created.
//
//----------------------------------------------------------------------------
void CBitStream::SetPosition(ULONG off) { Win4Assert( off < SMARTBUF_PAGE_SIZE_IN_BITS );
Win4Assert( !_buffer.isEmpty() );
//ciDebugOut (( DEB_BITSTM, "SetPosition %d\n", off ));
_pCurPos = _buffer.Get() + off / ULONG_BITS; _pEndBuf = _buffer.Get() + SMARTBUF_PAGE_SIZE_IN_DWORDS; _cbitLeftDW = ULONG_BITS - ( off - ULONG_BITS * ( off / ULONG_BITS ) );
Win4Assert ( Position() == off ); }
//+---------------------------------------------------------------------------
//
// Member: CBitStream::CBitStream, public
//
// Synopsis: Copy Constructor (with pb as a clone of _pBuffer).
//
// Arguments: [pb] -- Pointer to memory for buffer.
//
// [orig] -- Original CBitStream to be copied.
//
// History: 13-Jan-92 AmyA Created.
//
//----------------------------------------------------------------------------
CBitStream::CBitStream(CBitStream & orig) : _buffer(orig._buffer, orig._buffer.PageNum()), _cbitLeftDW(orig._cbitLeftDW), _oBuffer( 0 )
{ _pCurPos = _buffer.Get() + ( orig._pCurPos - orig._buffer.Get() ); _pEndBuf = _buffer.Get() + SMARTBUF_PAGE_SIZE_IN_DWORDS; }
//+---------------------------------------------------------------------------
//
// Member: CPBitStream::OverwriteBits, public
//
// Synopsis: Store bits in the buffer. This call doesn't affect
// surrounding bits.
//
// Effects: OR the [cb] low bits in [ul] beginning at the 'bit-cursor'
//
// Arguments: [ul] -- A DWord containing data to store.
//
// [cb] -- The number of bits to store.
//
// History: 18-Jul-91 KyleP Created.
// 02-Sep-92 BartoszM Rewrote for lazy paging
//
// Notes: Bits are stored 'big-endian'.
//
//----------------------------------------------------------------------------
void CPBitStream::OverwriteBits(ULONG ul, unsigned cb) { ciDebugOut (( DEB_BITSTM , "OverwriteBits %d\n", cb )); Win4Assert(cb != 0 && cb <= ULONG_BITS);
// Fault in the page if necessary
if ( _buffer.isEmpty() || _buffer.PageNum() != _bitOff.Page()) { _buffer.Refill(_bitOff.Page()); }
SetPosition(_bitOff.Offset());
//
// The easy case is the one where all the data fits in the current dword
//
if (cb <= _cbitLeftDW) { // this much will be left after current write
_cbitLeftDW -= cb;
// zero out a segment within current dword
// first create a mask of cb bits by (ULONG_BITS - cb) shift right
// then shift this mask left by the number of bits to be left
*_pCurPos &= ~((0xFFFFFFFF >> (ULONG_BITS - cb)) << _cbitLeftDW);
// shift ul left by the number of bits to be left
*_pCurPos |= (ul << _cbitLeftDW);
// prepare for the next write
_bitOff += cb;
Win4Assert( _bitOff.Offset() < SMARTBUF_PAGE_SIZE_IN_BITS ); } else { IOverwriteBits( ul, cb ); } }
//+---------------------------------------------------------------------------
//
// Member: CWBitStream::IPutBits, private
//
// Synopsis: Store bits in the buffer. Internal version for multi-dword
// case.
//
// Effects: Store the [cb] low bits in [ul] beginning at the 'bit-cursor'
//
// Arguments: [ul] -- A DWord containing data to store.
//
// [cb] -- The number of bits to store.
//
// History: 08-Jul-91 KyleP Created.
//
// Notes: Bits are stored 'big-endian'.
//
//----------------------------------------------------------------------------
void CWBitStream::IPutBits(ULONG ul, unsigned cb) { Win4Assert ( cb > _cbitLeftDW );
// ciDebugOut (( DEB_BITSTM, "IPutBits %d\n", cb ));
if ( _cbitLeftDW != 0 ) { Win4Assert ( _pCurPos < EndBuf() ); //
// Save the high portion in the current dword and save the
// number of unwritten bits in cb
//
cb -= _cbitLeftDW; *_pCurPos |= (ul >> cb); }
//
// Increment to the next dword
//
NextDword();
//
// Store the remainder
//
_cbitLeftDW -= cb; *_pCurPos = ul << _cbitLeftDW; }
//+---------------------------------------------------------------------------
//
// Member: CWBitStream::ZeroToEndOfPage, public
//
// Synopsis: Writes zeros from the current bit offset to ther end of the
// page.
//
// History: 22-Apr-94 DwightKr Created.
//
// Notes: Bits are stored 'big-endian'.
//
//----------------------------------------------------------------------------
void CWBitStream::ZeroToEndOfPage() { ULONG * pCurPos = _pCurPos;
if ( (_cbitLeftDW != 0) && (_cbitLeftDW != 32) ) { *pCurPos &= (0xFFFFFFFF << _cbitLeftDW); pCurPos++; }
RtlZeroMemory( pCurPos, (EndBuf() - pCurPos) * sizeof(ULONG)); }
void CWBitStream::InitSignature() { _buffer.InitSignature(); }
//+---------------------------------------------------------------------------
//
// Member: CPBitStream::IOverwriteBits, private
//
// Synopsis: Store bits in the buffer. This call doesn't affect
// surrounding bits.
//
// Effects: OR the [cb] low bits in [ul] beginning at the 'bit-cursor'
//
// Arguments: [ul] -- A DWord containing data to store.
//
// [cb] -- The number of bits to store.
//
// History: 18-Jul-91 KyleP Created.
//
// Notes: Bits are stored 'big-endian'.
//
//----------------------------------------------------------------------------
void CPBitStream::IOverwriteBits(ULONG ul, unsigned cb) { Win4Assert ( cb > _cbitLeftDW );
// prepare for next write
_bitOff += cb;
Win4Assert( _bitOff.Offset() < SMARTBUF_PAGE_SIZE_IN_BITS );
if ( _cbitLeftDW > 0 ) { Win4Assert ( _pCurPos < EndBuf() ); // zero the remaining bits in the current dword
*_pCurPos &= 0xFFFFFFFF << _cbitLeftDW; // this much will go to the next dword
cb -= _cbitLeftDW; // shift away the part that goes to the next dword
// and or in the rest
*_pCurPos |= (ul >> cb); }
//
// Increment to the next dword
//
NextDword(); //
// Store the remainder
//
Win4Assert( cb <= ULONG_BITS );
if ( cb == ULONG_BITS ) { *_pCurPos = ul; } else { // zero the cb upper bits of the current dword
*_pCurPos &= (0xFFFFFFFF >> cb); // fill them with cb bits from the bottom of ul
*_pCurPos |= ul << (ULONG_BITS - cb); } }
const ULONG g_aMasks[33] = { 0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff, };
//+---------------------------------------------------------------------------
//
// Member: CBitStream::IGetBits, public
//
// Synopsis: Retrieve bits from the buffer. Internal version for multi-
// dword case.
//
// Arguments: [cb] -- Count of bits to retrieve.
//
// History: 12-Jul-91 KyleP Created.
//
//----------------------------------------------------------------------------
ULONG CBitStream::IGetBits(unsigned cb) { Win4Assert ( cb > _cbitLeftDW );
//ciDebugOut (( DEB_BITSTM, "IGetBits %d\n", cb ));
//
// Get the portion from the current DWord
//
ULONG ul;
if ( 0 != _cbitLeftDW ) { const ULONG mask = g_aMasks[ cb ]; cb -= _cbitLeftDW; ul = (*_pCurPos << cb) & mask; } else ul = 0L;
//
// And the portion from the next.
//
NextDword();
_cbitLeftDW -= cb; return ul | (*_pCurPos >> (ULONG_BITS - cb)); } //IGetBits
//+---------------------------------------------------------------------------
//
// Member: CWBitStream::PutBytes, public
//
// Synopsis: Store a number of bytes in the buffer.
//
// Arguments: [pb] -- Pointer to data to store.
//
// [cb] -- Number of bytes to store.
//
// History: 08-Jul-91 KyleP Created.
//
//----------------------------------------------------------------------------
void CWBitStream::PutBytes(const BYTE * pb, unsigned cb) { // ciDebugOut (( DEB_BITSTM, "IPutBytes %d\n", cb ));
while (cb > 0) { PutBits(*pb, 8); pb += 1; cb--; } }
//+---------------------------------------------------------------------------
//
// Member: CBitStream::GetBytes, public
//
// Synopsis: Retrieve bytes from the buffer.
//
// Arguments: [pb] -- Pointer to area where data is returned.
//
// [cb] -- Count of bytes to retrieve.
//
// History: 12-Jul-91 KyleP Created.
//
//----------------------------------------------------------------------------
void CBitStream::GetBytes(BYTE * pb, unsigned cb) { ciDebugOut (( DEB_BITSTM, "GetBytes %d\n", cb ));
while (cb > 0) { *pb = BYTE ( GetBits(8) ); pb++; cb--; } }
//+---------------------------------------------------------------------------
//
// Member: CBitStream::Seek, public
//
// Synopsis: Seeks to the specified bit offset
//
// Arguments: [off] -- bit offset
//
// History: 28-Aug-92 BartoszM Created.
//
//----------------------------------------------------------------------------
void CBitStream::Seek ( const BitOffset& off ) { ciDebugOut (( DEB_BITSTM , "CBitStream::Seek %d:%d\n", off.Page(), off.Offset() ));
if (_buffer.PageNum() != off.Page()) { _buffer.Refill(off.Page()); }
SetPosition(off.Offset()); }
#if CIDBG == 1
unsigned CBitStream::PeekBit() { if (_cbitLeftDW > 0) { ULONG ul = *_pCurPos; return( ul >> (_cbitLeftDW - 1)) & 1; } else { ULONG* pNewPos = _pCurPos + 1; if (pNewPos < EndBuf()) { return(*pNewPos >> (ULONG_BITS-1)); } else { Win4Assert ( 0 && "Untested" ); CSmartBuffer bufTmp( _buffer, _buffer.PageNum() + 1 );
ULONG* p = bufTmp.Get(); unsigned bit = *p >> (ULONG_BITS-1); return(bit); } } }
unsigned CPBitStream::PeekBit() { // Fault in the page if necessary
if (_buffer.isEmpty() || _buffer.PageNum() != _bitOff.Page()) _buffer.Refill(_bitOff.Page());
SetPosition(_bitOff.Offset());
return CBitStream::PeekBit(); }
void DumpDword ( ULONG* pul ) { ULONG ul = *pul;
for (int i = ULONG_BITS-1; i >= 0; i--) { ciDebugOut (( DEB_ITRACE | DEB_NOCOMPNAME,"%0d", (ul >> i) & 1 )); if (i %4 == 0) ciDebugOut (( DEB_ITRACE | DEB_NOCOMPNAME," " )); } ciDebugOut (( DEB_ITRACE | DEB_NOCOMPNAME,"\n" )); }
void CBitStream::Dump() { ciDebugOut (( DEB_ITRACE, "CBitStream:\n" "\tpage %d\n" "\t_pCurPos 0x%x dwords from beginning\n" "\t_cbitLeftDW %d\n", _buffer.PageNum(), _pCurPos - _buffer.Get(), _cbitLeftDW ));
if (_pCurPos > _buffer.Get()) DumpDword ( _pCurPos - 1 ); if (_pCurPos < EndBuf()) { DumpDword ( _pCurPos ); for (unsigned i = 1; i <= ULONG_BITS - _cbitLeftDW; i++ ) { ciDebugOut (( DEB_ITRACE | DEB_NOCOMPNAME," " )); if (i %4 == 0) ciDebugOut (( DEB_ITRACE | DEB_NOCOMPNAME," " )); } ciDebugOut (( DEB_ITRACE | DEB_NOCOMPNAME,"^\n" )); } if (_pCurPos + 1 < EndBuf()) DumpDword(_pCurPos + 1); }
void CPBitStream::Dump() { // Fault in the page if necessary
if (_buffer.isEmpty() || _buffer.PageNum() != _bitOff.Page()) { _buffer.Refill(_bitOff.Page()); }
SetPosition(_bitOff.Offset());
CBitStream::Dump(); }
#endif // CIDBG == 1
|