datacommsserver/esockserver/ssock/ss_apiext_register.cpp
changeset 0 dfb7c4ff071f
--- /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 <ecom/ecom.h>
+#include <comms-infras/ss_thread.h>
+#include <ss_glob.h>
+#include <comms-infras/ss_api_ext.h>
+
+
+#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<Meta::STypeId*>(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;
+	}
+
+