diff -r 000000000000 -r dfb7c4ff071f datacommsserver/esockserver/ssock/ss_apiext_register.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datacommsserver/esockserver/ssock/ss_apiext_register.cpp Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,185 @@ +// Copyright (c) 2006-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: +// + +#include "ss_apiext_register.h" +#include +#include +#include +#include + + +#ifdef _DEBUG +// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module +// (if it could happen through user error then you should give it an explicit, documented, category + code) +_LIT(KSpecAssert_ESockSSockspxtrg, "ESockSSockspxtrg"); +#endif + +using namespace ESock; +using namespace Messages; + +TCommsApiExtTable::TCommsApiExtTable(TInt aExtensionId, const Meta::STypeId& aMsgImplTid) +: iExtensionId(aExtensionId), + iMsgImplTid(aMsgImplTid), + iMsgPluginInfo(NULL) + { + } + +//static +void TCommsApiExtTable::DeregisterInterfaceOnCleanup(TAny* aTid) + { + Meta::STypeId* tid = static_cast(aTid); + TlsGlobals::Get().DeregisterInterface(tid->iUid); + } + +void TCommsApiExtTable::AddClientL(TSubSessionUniqueId aClientId, CGlobals& aGlobals) + { + __ASSERT_DEBUG(iMsgImplTid.iUid.iUid!=0, User::Panic(KSpecAssert_ESockSSockspxtrg, 1)); + User::LeaveIfError(iClients.FindInOrder(aClientId)!=KErrNotFound? KErrAlreadyExists : KErrNone); + + //For the first client we need to register messages + TBool isFirst = iClients.Count()==0; + if (isFirst) + { + __ASSERT_DEBUG(iMsgPluginInfo==NULL, User::Panic(KSpecAssert_ESockSSockspxtrg, 2)); + iMsgPluginInfo = CExtItfMsgPluginInfo::NewInstanceL(iMsgImplTid); + CleanupStack::PushL(iMsgPluginInfo); + + aGlobals.RegisterInterfaceL(iMsgImplTid.iUid, iMsgPluginInfo->ImplementationProxyTableSize(), iMsgPluginInfo->ImplementationProxy()); + CleanupStack::PushL(TCleanupItem(&TCommsApiExtTable::DeregisterInterfaceOnCleanup, (TAny*)&iMsgImplTid)); + } + + iClients.InsertInOrderL(aClientId); + + if (isFirst) + { + CleanupStack::Pop(); //DeregisterInterfaceOnCleanup + CleanupStack::Pop(iMsgPluginInfo); + } + } + +//If aClientId==0 we will remove all interfaces for all clients! +TBool TCommsApiExtTable::RemoveClient(TSubSessionUniqueId aClientId, CGlobals& aGlobals) + { + TInt index = KErrNotFound; + if (aClientId!=0) + { + index = iClients.FindInOrder(aClientId); + if(index!=KErrNotFound) + { + iClients.Remove(index); + } + } + else + { + iClients.Reset(); + } + + //If no clients, deregister messages + if (iClients.Count()==0) + { + iClients.Close(); + aGlobals.DeregisterInterface(iMsgImplTid.iUid); + delete iMsgPluginInfo; + iMsgPluginInfo = NULL; + index = 0; + } + + if (index != KErrNotFound && index < iClients.Count()) + { + return iClients[index]; + } + + return EFalse; + } + + +TCommsApiExtRegister::TCommsApiExtRegister(CGlobals& aGlobals) +: iGlobals(aGlobals) + { + } + +TCommsApiExtRegister::~TCommsApiExtRegister() + { + //We should not have anything to cleanup here, if we do, some interface hasn't been closed properly + __ASSERT_DEBUG(iApiExtList.Count()==0, User::Panic(KSpecAssert_ESockSSockspxtrg, 3)); //Panic in debug + for (TInt i = iApiExtList.Count() - 1; i >= 0; --i) + { + TCommsApiExtTable& ref = iApiExtList[i]; + if (!ref.RemoveClient(0, iGlobals)) + { + iApiExtList.Remove(i); + } + } + iApiExtList.Close(); + } + +TInt TCommsApiExtRegister::FindApiExtClientsTable(TInt aExtItfId) + { + TCommsApiExtTable entry(aExtItfId, Meta::STypeId::CreateSTypeId()); + return iApiExtList.FindInUnsignedKeyOrder(entry); + } + +void TCommsApiExtRegister::RegisterInterfaceL(TInt aExtItfId, const Meta::STypeId& aMsgImplTid, TSubSessionUniqueId aClientId) + { + TInt index = FindApiExtClientsTable(aExtItfId); + if (index!=KErrNotFound) + { + TCommsApiExtTable& ref = iApiExtList[index]; + ref.AddClientL(aClientId, iGlobals); + } + else + { + TCommsApiExtTable entry(aExtItfId, aMsgImplTid); + entry.AddClientL(aClientId, iGlobals); + if (iApiExtList.InsertInUnsignedKeyOrder(entry)!=KErrNone) + { + entry.RemoveClient(aClientId, iGlobals); + } + } + } + +TSubSessionUniqueId TCommsApiExtRegister::FirstClient(TInt aExtItfId) + { + TCommsApiExtTable entry(aExtItfId, Meta::STypeId::CreateSTypeId()); + TInt index = iApiExtList.FindInUnsignedKeyOrder(entry); + TSubSessionUniqueId firstClient = 0; + if (index!=KErrNotFound) + { + TCommsApiExtTable& ref = iApiExtList[index]; + __ASSERT_DEBUG(ref.iClients.Count(), User::Panic(KSpecAssert_ESockSSockspxtrg, 4)); //Would not be here otherwise + firstClient = ref.iClients[0]; + } + return firstClient; + } + +//If aClientId==0 we will deregister this itf for all all clients! +TSubSessionUniqueId TCommsApiExtRegister::DeRegisterInterface(TInt aExtItfId, TSubSessionUniqueId aClientId) + { + TCommsApiExtTable entry(aExtItfId, Meta::STypeId::CreateSTypeId()); + TInt index = iApiExtList.FindInUnsignedKeyOrder(entry); + TSubSessionUniqueId nextClient = 0; + if (index!=KErrNotFound) + { + TCommsApiExtTable& ref = iApiExtList[index]; + nextClient = ref.RemoveClient(aClientId, iGlobals); + if (nextClient==0) + { + iApiExtList.Remove(index); + } + } + return nextClient; + } + +