#include "CContinue.h"
#include <stdlib.h>
#include <string.h>
#include <vector>
using std::vector;
struct sContinueEntry
{
UInt32 fRefNum;
void *fPointer;
};
CContinue::CContinue ( DeallocateProc *inProcPtr ) : fMutex("CContinue::fMutex")
{
fDeallocProcPtr = inProcPtr;
fNextContextID = 1;
}
CContinue::~CContinue ( void )
{
}
tContextData CContinue::AddPointer( void *inPointer, UInt32 inRefNum )
{
tContextData contextValue = 0;
if ( inPointer != NULL && inRefNum != 0 )
{
fMutex.WaitLock();
sContinueEntry *entry = new sContinueEntry;
entry->fPointer = inPointer;
entry->fRefNum = inRefNum;
while ( fContextMap.find(fNextContextID) != fContextMap.end() )
{
if ( 0 == ++fNextContextID )
fNextContextID++;
}
contextValue = fNextContextID;
fContextMap[contextValue] = entry;
fNextContextID++;
fMutex.SignalLock();
}
return contextValue;
}
void CContinue::RemovePointer( void *inPointer )
{
void *thePointer = NULL;
fMutex.WaitLock();
map<tContextData, sContinueEntry *>::iterator iter;
for ( iter = fContextMap.begin(); iter != fContextMap.end(); iter++ )
{
sContinueEntry *entry = iter->second;
if ( entry->fPointer == inPointer )
{
thePointer = inPointer;
fContextMap.erase( iter++ );
DSDelete( entry );
break;
}
}
fMutex.SignalLock();
if ( fDeallocProcPtr != NULL && thePointer != NULL )
(fDeallocProcPtr)( thePointer );
}
void CContinue::RemovePointersForRefNum( UInt32 inRefNum )
{
vector<void *> entryDataPendingDelete;
fMutex.WaitLock();
map<tContextData, sContinueEntry *>::iterator iter = fContextMap.begin();
while ( iter != fContextMap.end() )
{
sContinueEntry *entry = iter->second;
if ( entry->fRefNum == inRefNum )
{
entryDataPendingDelete.push_back( entry->fPointer );
fContextMap.erase( iter++ );
DSDelete( entry );
}
else
{
iter++;
}
}
fMutex.SignalLock();
if ( fDeallocProcPtr != NULL )
{
while ( entryDataPendingDelete.size() != 0 )
{
(fDeallocProcPtr)( (void *) entryDataPendingDelete.back() );
entryDataPendingDelete.pop_back();
}
}
}
tDirStatus CContinue::RemoveContext( tContextData inContextData )
{
tDirStatus siResult = eDSInvalidContinueData;
if ( inContextData != 0 )
{
void *thePointer = NULL;
fMutex.WaitLock();
map<tContextData, sContinueEntry *>::iterator iter = fContextMap.find( inContextData );
if ( iter != fContextMap.end() )
{
thePointer = iter->second->fPointer;
DSDelete( iter->second );
fContextMap.erase( iter );
siResult = eDSNoErr;
}
fMutex.SignalLock();
if ( fDeallocProcPtr != NULL && thePointer != NULL )
{
(fDeallocProcPtr)( thePointer );
}
}
else
{
siResult = eDSNoErr;
}
return siResult;
}
void *CContinue::GetPointer( tContextData inContextData )
{
void *thePointer = NULL;
fMutex.WaitLock();
map<tContextData, sContinueEntry *>::iterator iter = fContextMap.find( inContextData );
if ( iter != fContextMap.end() )
thePointer = iter->second->fPointer;
fMutex.SignalLock();
return thePointer;
}
UInt32 CContinue::GetRefNum( tContextData inContextData )
{
UInt32 refNum = 0;
fMutex.WaitLock();
map<tContextData, sContinueEntry *>::iterator iter = fContextMap.find( inContextData );
if ( iter != fContextMap.end() )
refNum = iter->second->fRefNum;
fMutex.SignalLock();
return refNum;
}