networkprotocols/iphook/inhook6/src/event.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // event.cpp - Event service implementation
       
    15 // Implementation of a event manager
       
    16 //
       
    17 
       
    18 
       
    19 
       
    20 /**
       
    21  @file event.cpp
       
    22 */
       
    23 
       
    24 #include <in6_event.h>
       
    25 
       
    26 
       
    27 class TListenerNode
       
    28 {
       
    29 public:
       
    30     MEventListener *iListener;
       
    31     TListenerNode *iNext;
       
    32 };
       
    33 
       
    34 #ifdef NONSHARABLE_CLASS
       
    35 	NONSHARABLE_CLASS(CEventManager);
       
    36 #endif
       
    37 
       
    38 class CEventManager : public MEventService, public CBase
       
    39 {
       
    40 public:
       
    41     CEventManager(TUint aNumClasses);
       
    42     virtual ~CEventManager();
       
    43 	void ConstructL();
       
    44     virtual TInt RegisterListener(MEventListener *aListener, TUint aEventClass);
       
    45     virtual TInt RemoveListener(MEventListener *aListener, TUint aEventClass = 0);
       
    46     virtual void Notify(TUint aEventClass, TUint aEventType, const void *aData);
       
    47     virtual TBool IsEmpty(TUint aEventClass);
       
    48 
       
    49 private:
       
    50     TUint iNumClasses;		//< Number of event classes handled by this event manager
       
    51     TListenerNode *iListeners;	//< Array of registered event listeners for each event class
       
    52 };
       
    53 
       
    54 
       
    55 CEventManager::CEventManager(TUint aNumClasses) : CBase(), iNumClasses(aNumClasses)
       
    56 	{
       
    57 	}
       
    58 
       
    59 
       
    60 CEventManager::~CEventManager()
       
    61 	{
       
    62 	TListenerNode *node = NULL;
       
    63 	TListenerNode *prev = NULL;
       
    64     for (TUint i = 0; i < iNumClasses; i++)
       
    65     	{
       
    66 		node = iListeners[i].iNext;
       
    67 		while (node)
       
    68 	  		{
       
    69 	    	prev = node;
       
    70 	    	node = node->iNext;
       
    71 	    	delete prev;
       
    72 	  		}
       
    73       	}
       
    74   
       
    75     delete[] iListeners;
       
    76 	}
       
    77 
       
    78 
       
    79 void CEventManager::ConstructL()
       
    80 	{
       
    81     iListeners = new TListenerNode[iNumClasses];
       
    82     if (!iListeners)
       
    83     	{
       
    84     	User::Leave(KErrNoMemory);
       
    85     	}
       
    86 
       
    87     for (TUint i = 0; i < iNumClasses; i++)
       
    88     	{
       
    89 		iListeners[i].iListener = 0;
       
    90 		iListeners[i].iNext = 0;
       
    91       	}
       
    92 	}
       
    93 
       
    94 
       
    95 TInt CEventManager::RegisterListener(MEventListener *aListener, TUint aEventClass)
       
    96 	{
       
    97     if (aEventClass > iNumClasses)
       
    98     	{
       
    99 		return KErrArgument;
       
   100 		}
       
   101 
       
   102     TListenerNode *iter = &iListeners[aEventClass-1];
       
   103     while (iter->iNext)
       
   104     	{
       
   105 		iter = iter->iNext;
       
   106 		}
       
   107 
       
   108     TListenerNode *node = new TListenerNode;
       
   109     if (!node)
       
   110     	{
       
   111     	return KErrNoMemory;
       
   112     	}
       
   113     
       
   114     iter->iNext = node;
       
   115     node->iListener = aListener;
       
   116     node->iNext = NULL;
       
   117     
       
   118 	/* Dynamically allocated memory node has been assigned to iter->iNext and managed through the list.
       
   119 	So CleanupStack::PopAndDestroy() will deallocate that memory. But, Coverity has misinterpreted it an issue.*/
       
   120 	// coverity [SYMBIAN.CLEANUP STACK]
       
   121 	// coverity [memory_leak]
       
   122     return KErrNone;
       
   123 	}
       
   124 
       
   125 
       
   126 TInt CEventManager::RemoveListener(MEventListener *aListener, TUint aEventClass)
       
   127 	{
       
   128     if (aEventClass > iNumClasses)
       
   129     	{
       
   130 		return KErrArgument;
       
   131 		}
       
   132 
       
   133     TListenerNode **iter = NULL;
       
   134     TBool found = EFalse;
       
   135     TListenerNode *n;
       
   136     // Start as an iterator, but if aEventClass was given, exit after first run
       
   137     for (TUint i = (aEventClass ? aEventClass-1 : 0); i < iNumClasses; i++)
       
   138     	{
       
   139 		found = EFalse;
       
   140 		
       
   141 		iter = &iListeners[i].iNext;
       
   142 		while (*iter)
       
   143 	  		{
       
   144 			n = *iter;
       
   145 	    	
       
   146 	    	if (n->iListener == aListener)
       
   147 	      		{
       
   148 				*iter = n->iNext;
       
   149 				delete n;
       
   150 				found = ETrue;
       
   151 				continue;
       
   152 	      		}
       
   153 
       
   154     		iter = &n->iNext;
       
   155 	  		}
       
   156 
       
   157 		if (aEventClass)
       
   158 	  		{
       
   159 	    	// If event class is given explicitly, we don't iterate through all event classes
       
   160 	    	if(found)
       
   161 				return KErrNone;  // Something was deleted, function exits succesfully
       
   162 	    	else
       
   163 				return KErrNotFound;  // Given listener was not found
       
   164 	  		}
       
   165 		}
       
   166 
       
   167     // If aEventClass was not given, this call always succeeds
       
   168 	return KErrNone;
       
   169 	}
       
   170 
       
   171 
       
   172 void CEventManager::Notify(TUint aEventClass, TUint aEventType, const void *aData)
       
   173 	{
       
   174     if (aEventClass > iNumClasses)
       
   175     	{
       
   176 		return;
       
   177 		}
       
   178 
       
   179     TListenerNode *iter = iListeners[aEventClass-1].iNext;
       
   180     while (iter)
       
   181 		{
       
   182 		iter->iListener->Notify(aEventClass, aEventType, aData);
       
   183 		iter = iter->iNext;
       
   184       	}
       
   185 	}
       
   186 
       
   187 
       
   188 TBool CEventManager::IsEmpty(TUint aEventClass)
       
   189 	{
       
   190     if (aEventClass > iNumClasses)
       
   191     	{
       
   192 		return ETrue;  // Inexisting class is always empty
       
   193 		}
       
   194 
       
   195     if (iListeners[aEventClass-1].iNext)
       
   196     	{
       
   197 		return EFalse;
       
   198 		}
       
   199     else
       
   200     	{
       
   201 		return ETrue;
       
   202 		}
       
   203 	}
       
   204 
       
   205 
       
   206 EXPORT_C MEventService *MEventService::CreateEventManager(TUint aNumClasses)
       
   207 	{
       
   208     CEventManager *es = new CEventManager(aNumClasses);
       
   209     if (!es)
       
   210     	{
       
   211     	return NULL;
       
   212     	}
       
   213     	
       
   214 	TInt err = KErrNone;
       
   215 	// coverity[leave_without_push]
       
   216 	// if ConstructL() leaves, the leave code is trapped in "err" and proper cleanup is done by freeing the memory alocated to "es"
       
   217     TRAP(err, es->ConstructL());
       
   218     if (err != KErrNone)
       
   219     	{
       
   220     	delete es;
       
   221     	return NULL;
       
   222     	}
       
   223     	
       
   224     return es;
       
   225 	}