354 lines
6.8 KiB
C++
354 lines
6.8 KiB
C++
// CallBkQ.cpp -- Implementation for class CCallbackQueue
|
|
|
|
#include "stdafx.h"
|
|
#include "CallBkQ.h"
|
|
#include "AbrtSrch.h"
|
|
|
|
CCallbackQueue *CCallbackQueue::NewInputCallQueue (PFNQCallBack pfn, PVOID pv)
|
|
{
|
|
CCallbackQueue *pcbq= NULL;
|
|
|
|
__try
|
|
{
|
|
pcbq= New CCallbackQueue();
|
|
|
|
pcbq->Initial(pfn, pv, FALSE);
|
|
}
|
|
__finally
|
|
{
|
|
if (_abnormal_termination() && pcbq)
|
|
{
|
|
delete pcbq; pcbq= NULL;
|
|
}
|
|
}
|
|
|
|
return pcbq;
|
|
}
|
|
|
|
CCallbackQueue *CCallbackQueue::NewOutputCallQueue(PFNQCallBack pfn, PVOID pv)
|
|
{
|
|
CCallbackQueue *pcbq= NULL;
|
|
|
|
__try
|
|
{
|
|
pcbq= New CCallbackQueue();
|
|
|
|
pcbq->Initial(pfn, pv, TRUE);
|
|
}
|
|
__finally
|
|
{
|
|
if (_abnormal_termination() && pcbq)
|
|
{
|
|
delete pcbq; pcbq= NULL;
|
|
}
|
|
}
|
|
|
|
return pcbq;
|
|
}
|
|
|
|
void CCallbackQueue::Initial(PFNQCallBack pfn, PVOID pv, BOOL fOutput)
|
|
{
|
|
m_pfn = pfn;
|
|
m_pvEnvironment = pv;
|
|
|
|
Enable(fOutput);
|
|
}
|
|
|
|
const UINT *CCallbackQueue::RawNextDWordsIn(PUINT pcdw)
|
|
{
|
|
ASSERT(!Writable());
|
|
|
|
CAbortSearch::CheckContinueState();
|
|
|
|
m_pfn(m_pvEnvironment, RequestInput, &m_pdwLast, &m_cdwReserved, *pcdw);
|
|
|
|
*pcdw= m_cdwReserved;
|
|
|
|
return m_pdwLast;
|
|
}
|
|
|
|
BOOL CCallbackQueue::RawEmptyRing()
|
|
{
|
|
ASSERT(!Writable());
|
|
|
|
BOOL fEmpty= m_cdwReserved;
|
|
|
|
m_pfn(m_pvEnvironment, QueryForEmptyRing, &m_pdwLast, PUINT(&fEmpty), 0);
|
|
|
|
return fEmpty;
|
|
}
|
|
|
|
UINT *CCallbackQueue::RawNextDWordsOut(PUINT pcdw)
|
|
{
|
|
ASSERT(Writable());
|
|
|
|
CAbortSearch::CheckContinueState();
|
|
|
|
m_pfn(m_pvEnvironment, RequestOutput, &m_pdwLast, &m_cdwReserved, *pcdw);
|
|
|
|
*pcdw= m_cdwReserved;
|
|
|
|
return m_pdwLast;
|
|
}
|
|
|
|
void CCallbackQueue::RawFlushOutput(BOOL fForceAll)
|
|
{
|
|
ASSERT(Writable());
|
|
|
|
CAbortSearch::CheckContinueState();
|
|
|
|
m_pfn(m_pvEnvironment, Flush, &m_pdwLast, &m_cdwReserved, fForceAll);
|
|
}
|
|
|
|
CDWInputQueue *CDWInputQueue::NewInputCallQueue (PFNPerDWordI pfn, PVOID pv)
|
|
{
|
|
CDWInputQueue *piq= NULL;
|
|
|
|
__try
|
|
{
|
|
piq= New CDWInputQueue();
|
|
|
|
piq->Initial(pfn, pv);
|
|
}
|
|
__finally
|
|
{
|
|
if (_abnormal_termination() && piq)
|
|
{
|
|
delete piq; piq= NULL;
|
|
}
|
|
}
|
|
|
|
return piq;
|
|
}
|
|
|
|
CDWInputQueue::CDWInputQueue()
|
|
{
|
|
m_pvEnvironment = NULL;
|
|
m_pfnI = NULL;
|
|
m_fEndOfInput = FALSE;
|
|
m_pdwLimit = m_adwBuffer;
|
|
}
|
|
|
|
void CDWInputQueue::Initial(PFNPerDWordI pfn, PVOID pv)
|
|
{
|
|
m_pfnI = pfn;
|
|
m_pvEnvironment = pv;
|
|
|
|
CCallbackQueue::Initial(CDWInputQueue::InputCallback, this);
|
|
|
|
UINT cdwActive= CDW_BUFFER;
|
|
|
|
if (pfn(pv, m_adwBuffer, &cdwActive)) m_fEndOfInput= TRUE;
|
|
|
|
m_pdwLimit= m_adwBuffer + cdwActive;
|
|
}
|
|
|
|
void CDWInputQueue::InputCallback(PVOID pv, CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
|
|
{
|
|
((CDWInputQueue *) pv)->Callback(cbt, ppdwLast, pcdwLast, cdwRequest);
|
|
}
|
|
|
|
void CDWInputQueue::Callback(CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
|
|
{
|
|
ASSERT(m_pfnI);
|
|
|
|
PUINT pdw;
|
|
UINT cdw;
|
|
|
|
switch(cbt)
|
|
{
|
|
case RequestInput:
|
|
|
|
pdw= *ppdwLast;
|
|
|
|
if (!pdw) pdw= m_adwBuffer;
|
|
|
|
pdw += *pcdwLast;
|
|
|
|
if (!cdwRequest) { *ppdwLast= pdw; *pcdwLast= 0; return; }
|
|
|
|
if (pdw == m_pdwLimit)
|
|
{
|
|
pdw= m_adwBuffer;
|
|
|
|
if (m_fEndOfInput) { *ppdwLast= NULL; *pcdwLast= 0; return; }
|
|
else
|
|
{
|
|
UINT cdwActive= CDW_BUFFER;
|
|
|
|
CAbortSearch::CheckContinueState();
|
|
|
|
if (m_pfnI(m_pvEnvironment, pdw, &cdwActive)) m_fEndOfInput= TRUE;
|
|
|
|
if (cdwActive) m_pdwLimit= pdw + cdwActive;
|
|
else { ASSERT(m_fEndOfInput); *ppdwLast= NULL; *pcdwLast= 0; return; }
|
|
}
|
|
}
|
|
|
|
cdw= m_pdwLimit - pdw;
|
|
|
|
*ppdwLast= pdw;
|
|
*pcdwLast= (cdw > cdwRequest)? cdwRequest : cdw;
|
|
|
|
return;
|
|
|
|
case QueryForEmptyRing:
|
|
|
|
pdw= *ppdwLast;
|
|
|
|
if (!pdw) pdw= m_adwBuffer;
|
|
|
|
pdw += *pcdwLast;
|
|
|
|
if (pdw < m_pdwLimit) { *pcdwLast= FALSE; return; }
|
|
|
|
if (m_fEndOfInput) { *pcdwLast= TRUE; return; }
|
|
|
|
return;
|
|
|
|
case RequestOutput:
|
|
|
|
ASSERT(FALSE); // Shouldn't be called for output functions...
|
|
|
|
return;
|
|
|
|
case Flush:
|
|
|
|
ASSERT(FALSE); // Shouldn't be called for output functions...
|
|
|
|
return;
|
|
|
|
case Disconnect:
|
|
|
|
return; // Don't have any disconnect actions to perform
|
|
|
|
default:
|
|
|
|
ASSERT(FALSE); // Unknown transaction type
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
CDWOutputQueue::CDWOutputQueue()
|
|
{
|
|
m_pvEnvironment = NULL;
|
|
m_pfnO = NULL;
|
|
}
|
|
|
|
CDWOutputQueue::~CDWOutputQueue()
|
|
{
|
|
// FlushOutput(TRUE);
|
|
|
|
// Disable();
|
|
}
|
|
|
|
void CDWOutputQueue::Initial(PFNPerDWordO pfn, PVOID pv)
|
|
{
|
|
m_pfnO = pfn;
|
|
m_pvEnvironment = pv;
|
|
|
|
CCallbackQueue::Initial(OutputCallback, this, TRUE);
|
|
}
|
|
|
|
CDWOutputQueue *CDWOutputQueue::NewOutputCallQueue(PFNPerDWordO pfn, PVOID pv)
|
|
{
|
|
CDWOutputQueue *poq= NULL;
|
|
|
|
__try
|
|
{
|
|
poq= New CDWOutputQueue();
|
|
|
|
poq->Initial(pfn, pv);
|
|
}
|
|
__finally
|
|
{
|
|
if (_abnormal_termination() && poq)
|
|
{
|
|
delete poq; poq= NULL;
|
|
}
|
|
}
|
|
|
|
return poq;
|
|
}
|
|
|
|
void CDWOutputQueue::OutputCallback(PVOID pv, CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
|
|
{
|
|
((CDWOutputQueue *) pv)->Callback(cbt, ppdwLast, pcdwLast, cdwRequest);
|
|
}
|
|
|
|
void CDWOutputQueue::Callback(CallBackTransaction cbt, PUINT *ppdwLast, PUINT pcdwLast, UINT cdwRequest)
|
|
{
|
|
ASSERT(m_pfnO);
|
|
|
|
PUINT pdw;
|
|
UINT cdw;
|
|
|
|
switch(cbt)
|
|
{
|
|
case RequestInput:
|
|
|
|
ASSERT(FALSE); // Shouldn't get any input transactions;
|
|
|
|
return;
|
|
|
|
case QueryForEmptyRing:
|
|
|
|
ASSERT(FALSE); // Shouldn't get any input transactions;
|
|
|
|
return;
|
|
|
|
case RequestOutput:
|
|
|
|
pdw= *ppdwLast;
|
|
|
|
if (!pdw) pdw= m_adwBuffer;
|
|
|
|
pdw += *pcdwLast;
|
|
|
|
cdw= CDW_BUFFER - (pdw - m_adwBuffer);
|
|
|
|
if (!cdw)
|
|
{
|
|
CAbortSearch::CheckContinueState();
|
|
|
|
m_pfnO(m_pvEnvironment, m_adwBuffer, CDW_BUFFER);
|
|
|
|
pdw = m_adwBuffer;
|
|
cdw = CDW_BUFFER;
|
|
}
|
|
|
|
if (cdw > cdwRequest) cdw= cdwRequest;
|
|
|
|
*ppdwLast= pdw;
|
|
*pcdwLast= cdw;
|
|
|
|
return;
|
|
|
|
case Flush:
|
|
|
|
pdw= *ppdwLast;
|
|
|
|
if (!pdw) pdw= m_adwBuffer;
|
|
|
|
pdw += *pcdwLast;
|
|
|
|
m_pfnO(m_pvEnvironment, m_adwBuffer, pdw - m_adwBuffer);
|
|
|
|
*ppdwLast= m_adwBuffer;
|
|
*pcdwLast= 0;
|
|
|
|
return;
|
|
|
|
case Disconnect:
|
|
|
|
return; // Don't have any disconnect actions to perform
|
|
|
|
default:
|
|
|
|
ASSERT(FALSE); // Unknown transaction type
|
|
|
|
return;
|
|
}
|
|
}
|