--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/ClientResolver/Server/src/CSIPCRRoutingTable.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,338 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name : CSIPCRRoutingTable.cpp
+// Part of : SIP Client Resolver
+// Version : 1.0
+//
+
+
+
+// INCLUDES
+#include <e32base.h>
+#include "CSIPCRRoutingTable.h"
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::CSIPCRRoutingTable
+// -----------------------------------------------------------------------------
+//
+CSIPCRRoutingTable::CSIPCRRoutingTable()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::NewL
+// -----------------------------------------------------------------------------
+//
+CSIPCRRoutingTable* CSIPCRRoutingTable::NewL()
+ {
+ CSIPCRRoutingTable* self = new (ELeave) CSIPCRRoutingTable();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSIPCRRoutingTable::ConstructL()
+ {
+ //create the entry object for find operations with dummy id 0
+ iFindEntry = CSIPCRRoutingEntry::NewL(TUid::Uid(0));
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::~CSIPCRRoutingTable
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CSIPCRRoutingTable::~CSIPCRRoutingTable()
+ {
+ iTable.ResetAndDestroy();
+ delete iFindEntry;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::AddL
+// -----------------------------------------------------------------------------
+//
+void CSIPCRRoutingTable::AddL( const TUid& aUid )
+ {
+ // first check that this top level uid does not exist already,
+ // if it does then we leave with error code KErrAlreadyExists
+ if (FindEntryIndex(aUid)!=KErrNotFound)
+ {
+ User::Leave (KErrAlreadyExists);
+ }
+
+ TUid topLevelUid;
+ if (FindToplevelMatch(aUid,topLevelUid))
+ {
+ // This entry is already in the tree, increase reference count
+ TInt topLevelIndex = FindEntryIndex(topLevelUid);
+ CSIPCRRoutingEntry* topLevelEntry = iTable[topLevelIndex];
+ CSIPCRRoutingEntry* entry = topLevelEntry->FindEntryInTree(aUid);
+ if (entry)
+ {
+ entry->ReferenceCount()++;
+ }
+ }
+ else
+ {
+ // Add a new entry in the top level
+ CSIPCRRoutingEntry* entry = CSIPCRRoutingEntry::NewL(aUid);
+ CleanupStack::PushL(entry);
+ iTable.AppendL(entry);
+ CleanupStack::Pop(entry);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::FindEntryIndex
+// -----------------------------------------------------------------------------
+//
+TInt CSIPCRRoutingTable::FindEntryIndex(const TUid& aUid)
+ {
+ TIdentityRelation<CSIPCRRoutingEntry> compareId(CSIPCRRoutingEntry::Compare);
+ iFindEntry->SetUID(aUid);
+ return (iTable.Find(iFindEntry, compareId));
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::AssociateL
+// -----------------------------------------------------------------------------
+//
+void CSIPCRRoutingTable::AssociateL( const TUid& aUid, const TUid& aAssociatedUid )
+ {
+ TUid associatedUidTop;
+ TUid parentUidTop;
+ TInt index;
+ CSIPCRRoutingEntry* topLevelEntry = NULL;
+ CSIPCRRoutingEntry* associatedEntryObject = NULL;
+ CSIPCRRoutingEntry* uidEntry = NULL;
+ TBool alreadyExists = EFalse;
+
+ // first check that the parent uid exists..
+ // if it does not then we leave with error code KErrNotFound
+ if (!FindToplevelMatch(aUid, parentUidTop))
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ // first check if the associated uid exists
+ // if it does then we may have to move it under the right entry
+ alreadyExists = FindToplevelMatch(aAssociatedUid, associatedUidTop);
+ if (alreadyExists)
+ {
+ CSIPCRRoutingEntry* currentParent = NULL;
+
+ // search the top level entry
+ index = FindEntryIndex(associatedUidTop);
+ topLevelEntry = iTable[index];
+ // get associated uid's current parent entry..
+
+ currentParent = topLevelEntry->FindParent(aAssociatedUid);
+
+ // if the current parent entry is the same
+ // as the one given, then dont do anything..
+ if (currentParent->UID() == aUid)
+ {
+ return;
+ }
+
+ // we need to move the existing associated entry
+ // to the new location, first remove the old
+ associatedEntryObject = currentParent->Detach(aAssociatedUid);
+ CleanupStack::PushL(associatedEntryObject);
+ }
+
+ // search the parent top level entry
+ index = FindEntryIndex(parentUidTop);
+ topLevelEntry = iTable[index];
+
+ //now get the uid entry if it is not at the top level
+ if (topLevelEntry->UID() == aUid)
+ {
+ uidEntry = topLevelEntry;
+ }
+ else
+ {
+ uidEntry = topLevelEntry->FindEntryInTree(aUid);
+ }
+
+ //Finally, add the associated entry
+ if (associatedEntryObject)
+ {
+ // moving the already allocated entry object
+ // to a new location
+ uidEntry->AddL(associatedEntryObject);
+ CleanupStack::Pop(associatedEntryObject);
+ }
+ else
+ {
+ // first time inserting this uid..
+ // no object created yet
+ uidEntry->AddL(aAssociatedUid);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::Remove
+// -----------------------------------------------------------------------------
+//
+TInt CSIPCRRoutingTable::Remove( const TUid& aUid )
+ {
+ TUid topLevelUid(TUid::Null());
+ if (!FindToplevelMatch(aUid, topLevelUid))
+ {
+ return KErrNotFound;
+ }
+
+ TInt topLevelIndex = FindEntryIndex(topLevelUid);
+ CSIPCRRoutingEntry* topLevelEntry = iTable[topLevelIndex];
+
+ if (topLevelEntry->UID() == aUid)
+ {
+ iTable.Remove(topLevelIndex);
+ delete topLevelEntry;
+ return KErrNone;
+ }
+
+ CSIPCRRoutingEntry* entry = topLevelEntry->FindEntryInTree(aUid);
+ if (--entry->ReferenceCount() == 0)
+ {
+ CSIPCRRoutingEntry* parent = topLevelEntry->FindParent(aUid);
+ return (parent->Remove(aUid));
+ }
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::FindMatch
+// -----------------------------------------------------------------------------
+//
+TBool CSIPCRRoutingTable::FindMatch( const TUid& aClientUid,
+ const TUid& aParentUid,
+ TUid& aNextHopUid )
+ {
+ TUid clientUidTop;
+ TBool match = EFalse;
+ TBool fContinue = ETrue;
+
+ // first check that the leaf uid exists..
+ // if it does not then return false
+ if (!FindToplevelMatch(aClientUid, clientUidTop))
+ {
+ return EFalse;
+ }
+
+ // search the top level entry
+ TInt index = FindEntryIndex(clientUidTop);
+ CSIPCRRoutingEntry* topLevelEntry = iTable[index];
+
+ CSIPCRRoutingEntry*uidEntry = NULL;
+ TUid uid = aClientUid;
+
+ while (fContinue)
+ {
+ uidEntry = topLevelEntry->FindParent(uid);
+ if (!uidEntry)
+ {
+ // no match
+ return EFalse;
+ }
+
+ if (uidEntry->UID() == aParentUid)
+ {
+ // match..
+ match = ETrue;
+ aNextHopUid = uid;
+ fContinue = EFalse;
+ }
+ else if (uidEntry->UID() == clientUidTop)
+ {
+ // we are at the top level..
+ // no match
+ match = EFalse;
+ fContinue = EFalse;
+ }
+ else
+ {
+ // no match yet..
+ // continue climbing up
+ uid = uidEntry->UID();
+ }
+ }
+
+ return match;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::HasUid
+// -----------------------------------------------------------------------------
+//
+TBool CSIPCRRoutingTable::HasUid( const TUid& aClientUid )
+ {
+ TBool found = EFalse;
+ TInt count = iTable.Count();
+
+ for ( TInt i=0; i < count && !found; i++ )
+ {
+ CSIPCRRoutingEntry* entry = iTable[i];
+ if ( entry->UID() == aClientUid ||
+ entry->HasClient( aClientUid ) )
+ {
+ found = ETrue;
+ }
+ }
+
+ return found;
+ }
+
+// -----------------------------------------------------------------------------
+// CSIPCRRoutingTable::FindToplevelMatch
+// -----------------------------------------------------------------------------
+//
+TBool CSIPCRRoutingTable::FindToplevelMatch( const TUid& aUid, TUid& aTopLevelUid )
+ {
+ TInt count = iTable.Count();
+
+ if (count > 0)
+ {
+ CSIPCRRoutingEntry* entry = NULL;
+ TInt index;
+ for (index = 0; index < count; index++)
+ {
+ entry = iTable[index];
+
+ // if the requested uid is top level uid itself, return it..
+ if (entry->UID() == aUid)
+ {
+ aTopLevelUid = entry->UID();
+ return ETrue;
+ }
+
+ // or else check the clients..
+ if (entry->HasClient(aUid))
+ {
+ aTopLevelUid = entry->UID();
+ return ETrue;
+ }
+ }
+ }
+
+ return EFalse;
+ }