#include "CNiNodeList.h"
#include "CNetInfoPI.h"
#include "DSUtils.h"
#include "ServerModuleLib.h"
CNiNodeList::CNiNodeList ( void )
{
}
CNiNodeList::~CNiNodeList ( void )
{
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
for (aNiNodeMapI = fNiNodeMap.begin(); aNiNodeMapI != fNiNodeMap.end(); ++aNiNodeMapI)
{
aNode = aNiNodeMapI->second;
if (aNode->listPtr != nil)
{
::dsDataListDeallocatePriv( aNode->listPtr );
free( aNode->listPtr );
aNode->listPtr = nil;
}
if (aNode->fDomain != nil)
{
aNode->fDomain = nil;
}
if (aNode->fDomainName != nil)
{
free(aNode->fDomainName);
aNode->fDomainName = nil;
}
free(aNode);
}
fNiNodeMap.clear();
}
void CNiNodeList::Lock ( void )
{
fMutex.Wait();
}
void CNiNodeList::UnLock ( void )
{
fMutex.Signal();
}
sInt32 CNiNodeList::AddNode ( const char *inStr, tDataList *inListPtr, bool inRegistered, uInt32 inLocalOrParent )
{
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI == fNiNodeMap.end()) {
aNode = (sNode *)::calloc( sizeof( sNode ), sizeof( char ) );
aNode->listPtr = inListPtr;
aNode->refCount = 1;
aNode->bisDirty = false;
aNode->fDomain = nil;
aNode->fDomainName = nil;
aNode->bRegistered = inRegistered;
aNode->localOrParent= inLocalOrParent;
fNiNodeMap[aNodeName] = aNode;
}
else {
aNode = aNiNodeMapI->second;
if (aNode->bisDirty)
{
aNode->bisDirty = false;
if (inRegistered)
{
aNode->bRegistered = true;
aNode->localOrParent= inLocalOrParent;
if (aNode->fDomainName != nil)
{
free(aNode->fDomainName);
aNode->fDomainName = nil;
}
if (aNode->fDomain != nil)
{
aNode->fDomain = nil;
}
}
}
else
{
if (inRegistered)
{
if (!(aNode->bRegistered))
{
aNode->bRegistered = true; aNode->refCount++; }
}
else {
aNode->refCount++;
}
}
if (aNode->listPtr == nil)
{
aNode->listPtr = inListPtr;
}
else
{
::dsDataListDeallocatePriv( inListPtr );
free( inListPtr );
inListPtr = nil;
}
}
fMutex.Signal();
return( eDSNoErr );
}
void* CNiNodeList::DeleteNode ( const char *inStr )
{
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
void *domain = nil;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
aNode->refCount--;
if ( aNode->refCount < 1 )
{
if (aNode->listPtr != nil)
{
::dsDataListDeallocatePriv( aNode->listPtr );
free( aNode->listPtr );
aNode->listPtr = nil;
}
if ( (aNode->fDomain != nil) && !(aNode->bisDirty) )
{
domain = aNode->fDomain;
aNode->fDomain = nil;
}
if (aNode->fDomainName != nil)
{
free(aNode->fDomainName);
aNode->fDomainName = nil;
}
fNiNodeMap.erase(aNodeName);
free(aNode);
}
}
fMutex.Signal();
return( domain );
}
bool CNiNodeList::IsPresent ( const char *inStr )
{
bool found = false;
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
if (!(aNode->bisDirty))
{
found = true;
}
}
fMutex.Signal();
return( found );
}
bool CNiNodeList::IsPresent ( const char *inStr, tDataList **inListPtr )
{
bool found = false;
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
if (!(aNode->bisDirty))
{
found = true;
if ( inListPtr != nil )
{
*inListPtr = aNode->listPtr;
}
}
}
fMutex.Signal();
return( found );
}
bool CNiNodeList::IsOpen ( const char *inStr,
void **outDomain,
char **outDomName,
ni_id *outDirID )
{
bool isOpen = false;
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
if ( !(aNode->bisDirty) && (aNode->fDomain != nil) && (aNode->fDomainName != nil) )
{
*outDomain = aNode->fDomain;
*outDomName = strdup(aNode->fDomainName);
::memcpy( outDirID, &aNode->fDirID, sizeof( ni_id ) );
isOpen = true;
aNode->refCount++;
}
}
fMutex.Signal();
return( isOpen );
}
bool CNiNodeList::SetDomainInfo ( const char *inStr,
void *inDomain,
char *inDomainName,
ni_id *inDirID )
{
bool found = false;
string aNodeName(inStr);
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI == fNiNodeMap.end()) {
this->AddNode(inStr, nil, false); aNiNodeMapI = fNiNodeMap.find(aNodeName);
}
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
if ( ( inDomain != nil ) && ( inDomainName != nil ) )
{
aNode->fDomain = inDomain;
aNode->fDomainName = inDomainName;
::memcpy( &aNode->fDirID, inDirID, sizeof( ni_id ) );
aNode->refCount++;
found = true;
}
}
fMutex.Signal();
return( found );
}
void CNiNodeList::SetAllDirty ( void )
{
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
fMutex.Wait();
for (aNiNodeMapI = fNiNodeMap.begin(); aNiNodeMapI != fNiNodeMap.end(); ++aNiNodeMapI)
{
aNode = aNiNodeMapI->second;
if (aNode->bRegistered) {
aNode->bisDirty = true;
}
}
fMutex.Signal();
}
void CNiNodeList::CleanAllDirty ( const uInt32 inSignature )
{
sNode *aNode = nil;
NiNodeMapI aNiNodeMapI;
NiNodeMapI delNiNodeMapI;
string aString;
fMutex.Wait();
for (aNiNodeMapI = fNiNodeMap.begin(); aNiNodeMapI != fNiNodeMap.end();)
{
aNode = aNiNodeMapI->second;
delNiNodeMapI = aNiNodeMapI;
++aNiNodeMapI;
if ( (aNode->bisDirty) && (aNode->bRegistered) && (aNode->listPtr != nil) )
{
if (CNetInfoPI::UnregisterNode( inSignature, aNode->listPtr ) == eDSNoErr)
{
aNode->refCount--;
if (aNode->refCount == 0)
{
if (aNode->listPtr != nil)
{
::dsDataListDeallocatePriv( aNode->listPtr );
free( aNode->listPtr );
aNode->listPtr = nil;
}
if (aNode->fDomain != nil)
{
aNode->fDomain = nil;
}
if (aNode->fDomainName != nil)
{
free(aNode->fDomainName);
aNode->fDomainName = nil;
}
fNiNodeMap.erase(delNiNodeMapI);
free(aNode);
}
}
}
}
fMutex.Signal();
}
uInt32 CNiNodeList::CheckForLocalOrParent ( const char *inName )
{
string aNodeName(inName);
uInt32 localOrParent = 0;
NiNodeMapI aNiNodeMapI;
sNode *aNode = nil;
fMutex.Wait();
aNiNodeMapI = fNiNodeMap.find(aNodeName);
if (aNiNodeMapI != fNiNodeMap.end()) {
aNode = aNiNodeMapI->second;
localOrParent = aNode->localOrParent;
}
fMutex.Signal();
return (localOrParent);
}