networkprotocols/iphook/inhook6/src/event.cpp
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networkprotocols/iphook/inhook6/src/event.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,225 @@
+// Copyright (c) 2004-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:
+// event.cpp - Event service implementation
+// Implementation of a event manager
+//
+
+
+
+/**
+ @file event.cpp
+*/
+
+#include <in6_event.h>
+
+
+class TListenerNode
+{
+public:
+    MEventListener *iListener;
+    TListenerNode *iNext;
+};
+
+#ifdef NONSHARABLE_CLASS
+	NONSHARABLE_CLASS(CEventManager);
+#endif
+
+class CEventManager : public MEventService, public CBase
+{
+public:
+    CEventManager(TUint aNumClasses);
+    virtual ~CEventManager();
+	void ConstructL();
+    virtual TInt RegisterListener(MEventListener *aListener, TUint aEventClass);
+    virtual TInt RemoveListener(MEventListener *aListener, TUint aEventClass = 0);
+    virtual void Notify(TUint aEventClass, TUint aEventType, const void *aData);
+    virtual TBool IsEmpty(TUint aEventClass);
+
+private:
+    TUint iNumClasses;		//< Number of event classes handled by this event manager
+    TListenerNode *iListeners;	//< Array of registered event listeners for each event class
+};
+
+
+CEventManager::CEventManager(TUint aNumClasses) : CBase(), iNumClasses(aNumClasses)
+	{
+	}
+
+
+CEventManager::~CEventManager()
+	{
+	TListenerNode *node = NULL;
+	TListenerNode *prev = NULL;
+    for (TUint i = 0; i < iNumClasses; i++)
+    	{
+		node = iListeners[i].iNext;
+		while (node)
+	  		{
+	    	prev = node;
+	    	node = node->iNext;
+	    	delete prev;
+	  		}
+      	}
+  
+    delete[] iListeners;
+	}
+
+
+void CEventManager::ConstructL()
+	{
+    iListeners = new TListenerNode[iNumClasses];
+    if (!iListeners)
+    	{
+    	User::Leave(KErrNoMemory);
+    	}
+
+    for (TUint i = 0; i < iNumClasses; i++)
+    	{
+		iListeners[i].iListener = 0;
+		iListeners[i].iNext = 0;
+      	}
+	}
+
+
+TInt CEventManager::RegisterListener(MEventListener *aListener, TUint aEventClass)
+	{
+    if (aEventClass > iNumClasses)
+    	{
+		return KErrArgument;
+		}
+
+    TListenerNode *iter = &iListeners[aEventClass-1];
+    while (iter->iNext)
+    	{
+		iter = iter->iNext;
+		}
+
+    TListenerNode *node = new TListenerNode;
+    if (!node)
+    	{
+    	return KErrNoMemory;
+    	}
+    
+    iter->iNext = node;
+    node->iListener = aListener;
+    node->iNext = NULL;
+    
+	/* Dynamically allocated memory node has been assigned to iter->iNext and managed through the list.
+	So CleanupStack::PopAndDestroy() will deallocate that memory. But, Coverity has misinterpreted it an issue.*/
+	// coverity [SYMBIAN.CLEANUP STACK]
+	// coverity [memory_leak]
+    return KErrNone;
+	}
+
+
+TInt CEventManager::RemoveListener(MEventListener *aListener, TUint aEventClass)
+	{
+    if (aEventClass > iNumClasses)
+    	{
+		return KErrArgument;
+		}
+
+    TListenerNode **iter = NULL;
+    TBool found = EFalse;
+    TListenerNode *n;
+    // Start as an iterator, but if aEventClass was given, exit after first run
+    for (TUint i = (aEventClass ? aEventClass-1 : 0); i < iNumClasses; i++)
+    	{
+		found = EFalse;
+		
+		iter = &iListeners[i].iNext;
+		while (*iter)
+	  		{
+			n = *iter;
+	    	
+	    	if (n->iListener == aListener)
+	      		{
+				*iter = n->iNext;
+				delete n;
+				found = ETrue;
+				continue;
+	      		}
+
+    		iter = &n->iNext;
+	  		}
+
+		if (aEventClass)
+	  		{
+	    	// If event class is given explicitly, we don't iterate through all event classes
+	    	if(found)
+				return KErrNone;  // Something was deleted, function exits succesfully
+	    	else
+				return KErrNotFound;  // Given listener was not found
+	  		}
+		}
+
+    // If aEventClass was not given, this call always succeeds
+	return KErrNone;
+	}
+
+
+void CEventManager::Notify(TUint aEventClass, TUint aEventType, const void *aData)
+	{
+    if (aEventClass > iNumClasses)
+    	{
+		return;
+		}
+
+    TListenerNode *iter = iListeners[aEventClass-1].iNext;
+    while (iter)
+		{
+		iter->iListener->Notify(aEventClass, aEventType, aData);
+		iter = iter->iNext;
+      	}
+	}
+
+
+TBool CEventManager::IsEmpty(TUint aEventClass)
+	{
+    if (aEventClass > iNumClasses)
+    	{
+		return ETrue;  // Inexisting class is always empty
+		}
+
+    if (iListeners[aEventClass-1].iNext)
+    	{
+		return EFalse;
+		}
+    else
+    	{
+		return ETrue;
+		}
+	}
+
+
+EXPORT_C MEventService *MEventService::CreateEventManager(TUint aNumClasses)
+	{
+    CEventManager *es = new CEventManager(aNumClasses);
+    if (!es)
+    	{
+    	return NULL;
+    	}
+    	
+	TInt err = KErrNone;
+	// coverity[leave_without_push]
+	// if ConstructL() leaves, the leave code is trapped in "err" and proper cleanup is done by freeing the memory alocated to "es"
+    TRAP(err, es->ConstructL());
+    if (err != KErrNone)
+    	{
+    	delete es;
+    	return NULL;
+    	}
+    	
+    return es;
+	}