|
|
// 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; } }
|