#include "CContinue.h"
#include "DirServicesTypes.h"
#include <stdlib.h>
#include <string.h>
CContinue::CContinue ( DeallocateProc *inProcPtr )
{
::memset( fLookupTable, 0, sizeof( fLookupTable ) );
fDeallocProcPtr = inProcPtr;
}
CContinue::~CContinue ( void )
{
}
sInt32 CContinue::AddItem ( void *inData, uInt32 inRefNum )
{
sInt32 siResult = eDSNoErr;
uInt32 uiSlot = 0;
uInt32 uiTmpRef = 0;
sTableEntry *pNewEntry = nil;
sTableEntry *pCurrEntry = nil;
fMutex.Wait();
uiTmpRef = (uInt32)inData;
pNewEntry = (sTableEntry *)::malloc( sizeof( sTableEntry ) );
if ( pNewEntry != nil )
{
::memset( pNewEntry, 0, sizeof( sTableEntry ) );
pNewEntry->fRefNum = inRefNum;
pNewEntry->fData = inData;
pNewEntry->fTimeStamp = ::time( nil );
}
else
{
siResult = eMemoryError;
}
if ( siResult == eDSNoErr )
{
uiSlot = uiTmpRef % kTableSize;
if ( fLookupTable[ uiSlot ] == nil )
{
fLookupTable[ uiSlot ] = pNewEntry;
}
else
{
pCurrEntry = fLookupTable[ uiSlot ];
while ( pCurrEntry != nil )
{
if ( pCurrEntry->fData == inData )
{
siResult = kErrDuplicateFound;
free( pNewEntry );
pNewEntry = nil;
break;
}
pCurrEntry = pCurrEntry->fNext;
}
if ( siResult == eDSNoErr )
{
pCurrEntry = fLookupTable[ uiSlot ];
pNewEntry->fNext = pCurrEntry;
fLookupTable[ uiSlot ] = pNewEntry;
}
}
}
fMutex.Signal();
return( siResult );
}
bool CContinue::VerifyItem ( void *inData )
{
bool bResult = false;
uInt32 uiTmpRef = 0;
uInt32 uiSlot = 0;
sTableEntry *pEntry = nil;
fMutex.Wait();
uiTmpRef = (uInt32)inData;
uiSlot = uiTmpRef % kTableSize;
pEntry = fLookupTable[ uiSlot ];
while ( pEntry != nil )
{
if ( pEntry->fData == inData )
{
bResult = true;
break;
}
pEntry = pEntry->fNext;
}
fMutex.Signal();
return( bResult );
}
sInt32 CContinue::RemoveItem ( void *inData )
{
sInt32 siResult = kErrItemNotFound;
uInt32 uiTmpRef = 0;
uInt32 uiSlot = 0;
sTableEntry *pCurrEntry = nil;
sTableEntry *pPrevEntry = nil;
fMutex.Wait();
uiTmpRef = (uInt32)inData;
uiSlot = uiTmpRef % kTableSize;
pCurrEntry = fLookupTable[ uiSlot ];
pPrevEntry = fLookupTable[ uiSlot ];
while ( pCurrEntry != nil )
{
if ( pCurrEntry->fData == inData )
{
if ( pCurrEntry == pPrevEntry )
{
fLookupTable[ uiSlot ] = pCurrEntry->fNext;
}
else
{
pPrevEntry->fNext = pCurrEntry->fNext;
}
if ( (fDeallocProcPtr != nil) && (pCurrEntry->fData != nil) )
{
fMutex.Signal();
(fDeallocProcPtr)( pCurrEntry->fData );
fMutex.Wait();
}
free( pCurrEntry );
pCurrEntry = nil;
siResult = eDSNoErr;
break;
}
if ( pCurrEntry != nil )
{
pPrevEntry = pCurrEntry;
pCurrEntry = pPrevEntry->fNext;
}
}
fMutex.Signal();
return( siResult );
}
sInt32 CContinue::RemoveItems ( uInt32 inRefNum )
{
bool bGetNext = true;
uInt32 i = 0;
sInt32 siResult = kErrItemNotFound;
sTableEntry *pCurrEntry = nil;
sTableEntry *pPrevEntry = nil;
sTableEntry *pDeadEntry = nil;
fMutex.Wait();
for ( i = 0; i < kTableSize; i++ )
{
pCurrEntry = fLookupTable[ i ];
pPrevEntry = fLookupTable[ i ];
while ( pCurrEntry != nil )
{
bGetNext = true;
if ( pCurrEntry->fRefNum == inRefNum )
{
pDeadEntry = pCurrEntry;
if ( pCurrEntry == pPrevEntry )
{
fLookupTable[ i ] = pCurrEntry->fNext;
pCurrEntry = fLookupTable[ i ];
pPrevEntry = fLookupTable[ i ];
bGetNext = false;
}
else
{
pPrevEntry->fNext = pCurrEntry->fNext;
pCurrEntry = pPrevEntry;
}
if ( (fDeallocProcPtr != nil) && (pDeadEntry->fData != nil) )
{
fMutex.Signal();
(fDeallocProcPtr)( pDeadEntry->fData );
fMutex.Wait();
}
free( pDeadEntry );
pDeadEntry = nil;
siResult = eDSNoErr;
}
if ( pCurrEntry != nil )
{
if ( bGetNext == true )
{
pPrevEntry = pCurrEntry;
pCurrEntry = pPrevEntry->fNext;
}
}
}
}
fMutex.Signal();
return( siResult );
}