151 lines
3.2 KiB
C++
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;
|
|
}
|
|
|