CPlugInObjectRef.h [plain text]
#ifndef __CPlugInObjectRef_h__
#define __CPlugInObjectRef_h__
#include <DirectoryServiceCore/PrivateTypes.h>
#include <DirectoryServiceCore/SharedConsts.h>
#include <DirectoryServiceCore/DSSemaphore.h>
template <class CObjectClass> class CPlugInObjectRef
{
struct sObjectTableEntry {
UInt32 fRefNum;
CObjectClass fObject;
struct sObjectTableEntry *fNext;
sObjectTableEntry( UInt32 inRefNum, CObjectClass inObject, struct sObjectTableEntry *inNext = NULL )
{
fRefNum = inRefNum;
fObject = inObject->Retain();
fNext = inNext;
}
~sObjectTableEntry( void )
{
fObject->Release();
}
};
public:
CPlugInObjectRef ( uint32_t inHashArrayLength = 128 )
{
fHashArrayLength = inHashArrayLength;
fRefNumCount = 0;
fLookupTable = (sObjectTableEntry **) calloc( fHashArrayLength, sizeof(sObjectTableEntry *) );
}
~CPlugInObjectRef ( void )
{
for ( uint32_t ii = 0; ii < fHashArrayLength; ii++ )
{
sObjectTableEntry *pCurrEntry = fLookupTable[ii];
while ( pCurrEntry != NULL )
{
sObjectTableEntry *pDelEntry = pCurrEntry;
pCurrEntry = pCurrEntry->fNext;
DSDelete( pDelEntry );
}
fLookupTable[ii] = NULL;
}
DSFree( fLookupTable );
}
tDirStatus AddObjectForRefNum ( UInt32 inRefNum, CObjectClass inObject )
{
tDirStatus siResult = eDSNoErr;
if ( inObject == NULL )
siResult = eDSNullParameter;
if ( siResult == eDSNoErr )
{
uint32_t uiSlot = inRefNum % fHashArrayLength;
fMutex.WaitLock();
sObjectTableEntry *pCurrEntry = fLookupTable[uiSlot];
while ( pCurrEntry != NULL )
{
if ( pCurrEntry->fRefNum == inRefNum )
{
siResult = eDSInvalidIndex;
break;
}
pCurrEntry = pCurrEntry->fNext;
}
if ( siResult == eDSNoErr )
{
fLookupTable[ uiSlot ] = new sObjectTableEntry( inRefNum, inObject, fLookupTable[uiSlot] );
fRefNumCount++;
}
fMutex.SignalLock();
}
return siResult;
}
tDirStatus RemoveRefNum ( UInt32 inRefNum )
{
tDirStatus siResult = eDSIndexNotFound;
uint32_t uiSlot = inRefNum % fHashArrayLength;
fMutex.WaitLock();
sObjectTableEntry *pCurrEntry = fLookupTable[ uiSlot ];
sObjectTableEntry *pPrevEntry = pCurrEntry;
while ( pCurrEntry != NULL )
{
if ( pCurrEntry->fRefNum == inRefNum )
break;
pPrevEntry = pCurrEntry;
pCurrEntry = pCurrEntry->fNext;
}
if ( pCurrEntry != NULL )
{
if ( pCurrEntry == pPrevEntry )
fLookupTable[ uiSlot ] = pCurrEntry->fNext;
else
pPrevEntry->fNext = pCurrEntry->fNext;
fRefNumCount--;
siResult = eDSNoErr;
}
fMutex.SignalLock();
DSDelete( pCurrEntry );
return siResult;
}
CObjectClass GetObjectForRefNum ( UInt32 inRefNum )
{
CObjectClass pResult = NULL;
fMutex.WaitLock();
sObjectTableEntry *pEntry = fLookupTable[ inRefNum % fHashArrayLength ];
while ( pEntry != NULL )
{
if ( pEntry->fRefNum == inRefNum )
{
pResult = pEntry->fObject->Retain();
break;
}
pEntry = pEntry->fNext;
}
fMutex.SignalLock();
return pResult;
}
private:
sObjectTableEntry **fLookupTable;
uint32_t fHashArrayLength;
uint32_t fRefNumCount;
DSSemaphore fMutex;
};
#endif