#include "CPlugInRef.h"
#include <stdlib.h>
#include <string.h>
CPlugInRef::CPlugInRef ( DeallocateProc *inProcPtr ) : fMutex("CPluginRef::fMutex")
{
fHashArrayLength = 128;
fRefNumCount = 0;
fLookupTable = (sDSTableEntry**)calloc(fHashArrayLength, sizeof(sDSTableEntry*));
fDeallocProcPtr = inProcPtr;
}
CPlugInRef::CPlugInRef ( DeallocateProc *inProcPtr, UInt32 inHashArrayLength ) : fMutex("CPluginRef::fMutex")
{
fHashArrayLength = inHashArrayLength;
fRefNumCount = 0;
fLookupTable = (sDSTableEntry**)calloc(fHashArrayLength, sizeof(sDSTableEntry*));
fDeallocProcPtr = inProcPtr;
}
CPlugInRef::~CPlugInRef ( void )
{
}
SInt32 CPlugInRef::AddItem ( UInt32 inRefNum, void *inData )
{
SInt32 siResult = eDSNoErr;
UInt32 uiSlot = 0;
sDSTableEntry *pNewEntry = nil;
sDSTableEntry *pCurrEntry = nil;
fMutex.WaitLock();
pNewEntry = (sDSTableEntry *)::calloc( 1, sizeof( sDSTableEntry ) );
if ( pNewEntry != nil )
{
pNewEntry->fRefNum = inRefNum;
pNewEntry->fData = inData;
}
else
{
siResult = eMemoryError;
}
if ( siResult == eDSNoErr )
{
uiSlot = inRefNum % fHashArrayLength;
if ( fLookupTable[ uiSlot ] == nil )
{
fLookupTable[ uiSlot ] = pNewEntry;
fRefNumCount++;
}
else
{
pCurrEntry = fLookupTable[ uiSlot ];
while ( pCurrEntry != nil )
{
if ( pCurrEntry->fRefNum == inRefNum )
{
siResult = eDSInvalidIndex;
free( pNewEntry );
pNewEntry = nil;
break;
}
pCurrEntry = pCurrEntry->fNext;
}
if ( siResult == eDSNoErr )
{
pCurrEntry = fLookupTable[ uiSlot ];
pNewEntry->fNext = pCurrEntry;
fLookupTable[ uiSlot ] = pNewEntry;
fRefNumCount++;
}
}
}
fMutex.SignalLock();
return( siResult );
}
void *CPlugInRef::GetItemData ( UInt32 inRefNum )
{
void *pvResult = nil;
UInt32 uiSlot = 0;
sDSTableEntry *pEntry = nil;
fMutex.WaitLock();
uiSlot = inRefNum % fHashArrayLength;
pEntry = fLookupTable[ uiSlot ];
while ( pEntry != nil )
{
if ( pEntry->fRefNum == inRefNum )
{
pvResult = pEntry->fData;
break;
}
pEntry = pEntry->fNext;
}
fMutex.SignalLock();
return( pvResult );
}
SInt32 CPlugInRef::RemoveItem ( UInt32 inRefNum )
{
SInt32 siResult = eDSIndexNotFound;
UInt32 uiSlot = 0;
sDSTableEntry *pCurrEntry = nil;
sDSTableEntry *pPrevEntry = nil;
fMutex.WaitLock();
uiSlot = inRefNum % fHashArrayLength;
pCurrEntry = fLookupTable[ uiSlot ];
pPrevEntry = fLookupTable[ uiSlot ];
while ( pCurrEntry != nil )
{
if ( pCurrEntry->fRefNum == inRefNum )
{
if ( pCurrEntry == pPrevEntry )
{
fLookupTable[ uiSlot ] = pCurrEntry->fNext;
}
else
{
pPrevEntry->fNext = pCurrEntry->fNext;
}
if ( (fDeallocProcPtr != nil) && (pCurrEntry->fData != nil) )
{
fMutex.SignalLock();
(fDeallocProcPtr)( pCurrEntry->fData );
fMutex.WaitLock();
}
free( pCurrEntry );
pCurrEntry = nil;
fRefNumCount--;
siResult = eDSNoErr;
break;
}
if ( pCurrEntry != nil )
{
pPrevEntry = pCurrEntry;
pCurrEntry = pPrevEntry->fNext;
}
}
fMutex.SignalLock();
return( siResult );
}
void CPlugInRef:: DoOnAllItems ( OperationProc *inProcPtr )
{
UInt32 uiSlot = 0;
sDSTableEntry *pEntry = nil;
if (inProcPtr == nil)
{
return;
}
fMutex.WaitLock();
for (uiSlot = 0; uiSlot < fHashArrayLength; uiSlot++)
{
pEntry = fLookupTable[ uiSlot ];
while ( pEntry != nil )
{
if ( pEntry->fData != nil )
{
(inProcPtr)(pEntry->fData);
}
pEntry = pEntry->fNext;
}
}
fMutex.SignalLock();
}