NT4/private/windows/win4help/ftsrch/iolist.cpp
2020-09-30 17:12:29 +02:00

151 lines
3.2 KiB
C++

// IOList.cpp -- Implementation for class CIOList
#include "stdafx.h"
#include "IOList.h"
CIOList::CIOList() : CIOQueue()
{
m_pfbVector = NULL;
m_ppfbFree = NULL;
m_cBlocks = 0;
m_pcdw = NULL;
m_ppfbNextBlock = NULL;
m_fDestructive = FALSE;
}
CIOList::~CIOList()
{
if (Writable()) FlushOutput(TRUE);
}
CIOList *CIOList::NewIOList(CUnbufferedIO* puio, PFileBlockLink pfbVector,
PFileBlockLink *ppfbFree
)
{
ASSERT(puio);
ASSERT(pfbVector);
CIOList *piol= NULL;
__try
{
piol= New CIOList;
piol->InitialIOList(puio, pfbVector, ppfbFree);
}
__finally
{
if (_abnormal_termination() && piol)
{
delete piol; piol= NULL;
}
}
return piol;
}
BOOL CIOList::InitialIOList(CUnbufferedIO* puio, PFileBlockLink pfbVector,
PFileBlockLink *ppfbFree
)
{
ASSERT(puio);
ASSERT(pfbVector);
if (!InitialIOQueue(puio)) return FALSE;
m_pfbVector = pfbVector;
m_ppfbFree = ppfbFree;
return TRUE;
}
void CIOList::AttachStream(PRefStream prs, BOOL fWritable, BOOL fDestructive)
{
ASSERT(Initialed());
ASSERT(prs);
if (Writable()) FlushOutput(TRUE);
m_fDestructive = fDestructive;
m_pcdw = &(prs->cdw);
m_ppfbNextBlock = &(prs->pFirstBlock);
m_cBlocks = BlocksFor(*m_pcdw * sizeof(UINT), CbBlockSize());
EnableStream(fWritable);
}
BOOL CIOList::NextFileAddress(PUINT pibFileLow, PUINT pibFileHigh, PUINT pcdw)
{
if (*pcdw > CbBlockSize() / sizeof(UINT))
*pcdw = CbBlockSize() / sizeof(UINT);
if (Writable())
{
PFileBlockLink pfbl= *m_ppfbFree;
ASSERT(pfbl); // This problem must be avoided by the
// environment which sets up the free list.
*m_ppfbFree= pfbl->pNextBlock; pfbl->pNextBlock= NULL;
UINT iBlock= pfbl - m_pfbVector;
*pibFileLow = iBlock * CbBlockSize();
*pibFileHigh = 0;
*m_ppfbNextBlock= pfbl; m_ppfbNextBlock= &(pfbl->pNextBlock);
*m_pcdw += *pcdw;
return FALSE;
}
if (!m_cBlocks)
{
*pcdw= 0; return TRUE;
}
PFileBlockLink pfbl= *m_ppfbNextBlock;
ASSERT(pfbl);
*m_ppfbNextBlock= pfbl->pNextBlock;
ASSERT(pfbl->pNextBlock || m_cBlocks == 1);
UINT iBlock= pfbl - m_pfbVector;
*pibFileLow = iBlock * CbBlockSize();
*pibFileHigh = 0;
if (--m_cBlocks)
{
*pcdw = CbBlockSize() / sizeof(UINT);
*m_pcdw -= CbBlockSize() / sizeof(UINT);
return FALSE;
}
else // The last block won't necessarily be full.
{
*pcdw= *m_pcdw; *m_pcdw= 0;
return TRUE;
}
}
void CIOList::ReleaseFileBlock(UINT ibFileLow, UINT ibFileHigh)
{
ASSERT(!ibFileHigh);
if (!m_fDestructive) return;
UINT iBlock= ibFileLow / CbBlockSize();
PFileBlockLink pfbl= m_pfbVector + iBlock;
pfbl->pNextBlock= *m_ppfbFree;
*m_ppfbFree= pfbl;
}