cmmanager/cmmgr/Framework/Src/cmobjectpool.cpp
changeset 20 9c97ad6591ae
parent 18 fcbbe021d614
child 21 b8e8e15e80f2
child 23 7ec726f93df1
child 28 860702281757
equal deleted inserted replaced
18:fcbbe021d614 20:9c97ad6591ae
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of CCMObjectPool.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "cmobjectpool.h"
       
    20 #include "cmmanagerimpl.h"
       
    21 #include <cmpluginbaseeng.h>
       
    22 #include <cmpluginbase.h>
       
    23 #include <cmconnectionmethoddef.h>
       
    24 
       
    25 #include <e32def.h>
       
    26 #include <e32std.h>
       
    27 
       
    28 
       
    29 //////////////////////////////////////////////////////////////////////
       
    30 // Construction/Destruction
       
    31 //////////////////////////////////////////////////////////////////////
       
    32 const TInt KDestGranularity     = 20;
       
    33 const TInt KCMethodGranularity  = 20;
       
    34 CCMObjectPool::CCMObjectPool(CCmManagerImpl& aCmManagerImpl) :
       
    35         iCmManagerImpl(aCmManagerImpl),    
       
    36         iDestinationArray(KDestGranularity, 
       
    37             _FOFF(TObjectPoolDestinationItem,iDestinationId)),
       
    38         iConnectionMethodArray(KCMethodGranularity, 
       
    39             _FOFF(TObjectPoolCMItem,iConnectionMethodId))
       
    40     {
       
    41     }
       
    42 
       
    43 CCMObjectPool::~CCMObjectPool()
       
    44     {
       
    45     // The get and remove functions must be used in pairs
       
    46     // If the arrays have any element here than the client 
       
    47     // of this class made a programming error
       
    48     for (TInt index = 0; index < iDestinationArray.Count(); index++)
       
    49         {
       
    50         delete iDestinationArray[index].iDestinationItem;
       
    51         }    
       
    52     for (TInt index = 0; index < iConnectionMethodArray.Count(); index++)
       
    53         {
       
    54         delete iConnectionMethodArray[index].iConnectionMethodItem;
       
    55         }
       
    56     iDestinationArray.Close();
       
    57     iConnectionMethodArray.Close();
       
    58     }
       
    59 
       
    60 CCMObjectPool::TObjectPoolDestinationItem::TObjectPoolDestinationItem(
       
    61                         CCmDestinationData*   aDestinationItem, 
       
    62                         TUint32               aDestinationId) : 
       
    63                             iDestinationId(aDestinationId),
       
    64                             iDestinationItem(aDestinationItem)
       
    65     {
       
    66     }
       
    67     
       
    68 CCMObjectPool::TObjectPoolCMItem::TObjectPoolCMItem(
       
    69                         CCmPluginBaseEng* aConnectionMethodItem, 
       
    70                         TUint32           aConnectionMethodId) : 
       
    71                             iConnectionMethodId(aConnectionMethodId),
       
    72                             iConnectionMethodItem(aConnectionMethodItem)
       
    73     {
       
    74     }
       
    75 
       
    76 CCmDestinationImpl* CCMObjectPool::GetDestinationL( TUint32 aDestinationId )
       
    77     {
       
    78     TUint32 destinationId( aDestinationId );
       
    79     if ( destinationId > 0 && destinationId < 255 )
       
    80         {
       
    81         destinationId += KCmDefaultDestinationAPTagId;
       
    82         }
       
    83     TObjectPoolDestinationItem findD( NULL, destinationId );
       
    84     TInt index = iDestinationArray.FindInUnsignedKeyOrder(findD);
       
    85     if (index == KErrNotFound)
       
    86         {
       
    87         // If the destinaton is not in the pool create it than return it.
       
    88         CCmDestinationImpl* dest = CCmDestinationImpl::NewL( iCmManagerImpl, 
       
    89                                                              destinationId );
       
    90         TObjectPoolDestinationItem aDest( 
       
    91             dest->GetData(),
       
    92             destinationId );
       
    93         User::LeaveIfError(
       
    94             iDestinationArray.InsertInUnsignedKeyOrder(aDest));
       
    95         dest->IncrementRefCounter();
       
    96         return dest;
       
    97         }
       
    98     else
       
    99         {
       
   100         // If the destination is allready in the pool than return it.
       
   101         CCmDestinationImpl* dest = CCmDestinationImpl::NewL( iCmManagerImpl, 
       
   102                                 iDestinationArray[index].iDestinationItem );
       
   103         iDestinationArray[index].iDestinationItem->IncrementRefCounter();
       
   104         return dest;    
       
   105         }
       
   106     }
       
   107 
       
   108 CCmPluginBase* CCMObjectPool::GetConnectionMethodL( TUint32 aCmId, 
       
   109                                         CCmDestinationImpl* aParentDest )
       
   110     {
       
   111     CCmPluginBase* connMethod = NULL;
       
   112     TObjectPoolCMItem findCM( NULL, aCmId );
       
   113     TInt index = iConnectionMethodArray.FindInUnsignedKeyOrder(findCM);
       
   114     if (index == KErrNotFound)
       
   115         {
       
   116         CCmPluginBaseEng* pluginBaseEng = iCmManagerImpl.DoFindConnMethL(
       
   117                                                         aCmId, aParentDest);        
       
   118         if (!pluginBaseEng) User::Leave(KErrNotFound); //There is no such plugin
       
   119         CleanupStack::PushL( pluginBaseEng );        
       
   120         connMethod = new (ELeave) CCmPluginBase(pluginBaseEng); 
       
   121         CleanupStack::PushL( connMethod );        
       
   122         TObjectPoolCMItem aCM( pluginBaseEng, aCmId );
       
   123         User::LeaveIfError(
       
   124             iConnectionMethodArray.InsertInUnsignedKeyOrder(aCM));
       
   125         pluginBaseEng->IncrementRefCounter();
       
   126         CleanupStack::Pop( connMethod );
       
   127         CleanupStack::Pop( pluginBaseEng );
       
   128         }
       
   129     else
       
   130         {
       
   131         // If the cm is allready in the pool than return it.
       
   132         iConnectionMethodArray[index].iConnectionMethodItem->IncrementRefCounter();
       
   133         connMethod = new (ELeave) CCmPluginBase(
       
   134                 iConnectionMethodArray[index].iConnectionMethodItem); 
       
   135         }
       
   136     return connMethod;            
       
   137     }
       
   138 
       
   139 CCmPluginBase* CCMObjectPool::CreateConnectionMethodL( CCmPluginBaseEng* pluginBaseEng )
       
   140     {
       
   141     CCmPluginBase* connMethod = new (ELeave) CCmPluginBase(pluginBaseEng); 
       
   142     CleanupStack::PushL( connMethod );        
       
   143     TObjectPoolCMItem aCM( pluginBaseEng, 0 );//The new id is zero till update
       
   144     User::LeaveIfError(
       
   145         iConnectionMethodArray.InsertInUnsignedKeyOrderAllowRepeats(aCM));
       
   146     pluginBaseEng->IncrementRefCounter();
       
   147     CleanupStack::Pop( connMethod );
       
   148     return connMethod;            
       
   149     }
       
   150 
       
   151 void CCMObjectPool::InsertConnectionMethodL( CCmPluginBaseEng* pluginBaseEng )
       
   152     {       
       
   153     TObjectPoolCMItem aCM( pluginBaseEng, 0 );//The new id is zero till update
       
   154     User::LeaveIfError(
       
   155         iConnectionMethodArray.InsertInUnsignedKeyOrderAllowRepeats(aCM));
       
   156     pluginBaseEng->IncrementRefCounter();
       
   157     }
       
   158 
       
   159 CCmPluginBase* CCMObjectPool::CreateConnectionMethodL( TUint32 aImplementationUid, 
       
   160                                         TCmPluginInitParam& aParams )
       
   161     {
       
   162     CCmPluginBaseEng* pluginBaseEng = iCmManagerImpl.DoCreateConnectionMethodL(
       
   163                                             aImplementationUid, aParams);
       
   164     CleanupStack::PushL( pluginBaseEng );        
       
   165     CCmPluginBase* connMethod = new (ELeave) CCmPluginBase(pluginBaseEng); 
       
   166     CleanupStack::PushL( connMethod );        
       
   167     TObjectPoolCMItem aCM( pluginBaseEng, 0 );//The new id is zero till update
       
   168     User::LeaveIfError(
       
   169         iConnectionMethodArray.InsertInUnsignedKeyOrderAllowRepeats(aCM));
       
   170     pluginBaseEng->IncrementRefCounter();
       
   171     CleanupStack::Pop( connMethod );
       
   172     CleanupStack::Pop( pluginBaseEng );
       
   173     return connMethod;            
       
   174     }
       
   175 
       
   176 CCmPluginBase* CCMObjectPool::CreateConnectionMethodL( TUint32 aImplementationUid, 
       
   177                                                        TCmPluginInitParam& aParams,
       
   178                                                        TUint32 aConnMethodId )
       
   179 	{
       
   180     CCmPluginBaseEng* pluginBaseEng = iCmManagerImpl.DoCreateConnectionMethodL(
       
   181                                             aImplementationUid, 
       
   182                                             aParams,
       
   183                                             aConnMethodId);
       
   184     CleanupStack::PushL( pluginBaseEng );
       
   185     CCmPluginBase* connMethod = new (ELeave) CCmPluginBase(pluginBaseEng); 
       
   186     CleanupStack::PushL( connMethod );        
       
   187     TObjectPoolCMItem aCM( pluginBaseEng, 0 );//The new id is zero till update
       
   188     User::LeaveIfError(
       
   189         iConnectionMethodArray.InsertInUnsignedKeyOrderAllowRepeats(aCM));
       
   190     pluginBaseEng->IncrementRefCounter();
       
   191     CleanupStack::Pop( connMethod );
       
   192     CleanupStack::Pop( pluginBaseEng );
       
   193     return connMethod;            
       
   194 	}
       
   195 
       
   196 CCmDestinationImpl* CCMObjectPool::GetDestinationL( const TDesC& aName )
       
   197     {
       
   198     // CmManagerImpl.GetDestinationL will leave with KErrAlreadyExists 
       
   199     // if the destination already exists
       
   200     CCmDestinationImpl* destImpl = CCmDestinationImpl::NewL( iCmManagerImpl,
       
   201          aName );
       
   202     // Yet destImpl->Id() == 0
       
   203     TObjectPoolDestinationItem aDest( destImpl->GetData(), destImpl->Id() );
       
   204     // InsertInUnsignedKeyOrderAllowRepeats is used because all
       
   205     // new destinations' Id is zero   
       
   206     User::LeaveIfError(
       
   207         iDestinationArray.InsertInUnsignedKeyOrderAllowRepeats(aDest) );
       
   208     destImpl->IncrementRefCounter();
       
   209     return destImpl;            
       
   210     }
       
   211 
       
   212 CCmDestinationImpl* CCMObjectPool::CreateDestinationL( const TDesC& aName,
       
   213                                                        TUint32 aDestId )
       
   214     {
       
   215     // CmManagerImpl.GetDestinationL will leave with KErrAlreadyExists 
       
   216     // if the destination already exists
       
   217     CCmDestinationImpl* destImpl = CCmDestinationImpl::NewL( iCmManagerImpl,
       
   218                                                              aName,
       
   219                                                              aDestId);
       
   220     // Yet destImpl->Id() == 0
       
   221     TObjectPoolDestinationItem aDest( destImpl->GetData(), destImpl->Id() );
       
   222     // InsertInUnsignedKeyOrderAllowRepeats is used because all
       
   223     // new destinations' Id is zero   
       
   224     User::LeaveIfError(
       
   225                    iDestinationArray.InsertInUnsignedKeyOrderAllowRepeats(aDest) );
       
   226     destImpl->IncrementRefCounter();
       
   227     return destImpl;            
       
   228     }
       
   229 
       
   230 
       
   231 void CCMObjectPool::RemoveDestination( CCmDestinationData* aDestination )
       
   232     {
       
   233     if (aDestination->IdIsValid())
       
   234         {
       
   235         aDestination->DecrementRefCounter();
       
   236         if (!aDestination->GetRefCounter())
       
   237             {// this was the last reference -> must delete        
       
   238             TObjectPoolDestinationItem findD( NULL, aDestination->Id() );
       
   239             TInt index = iDestinationArray.FindInUnsignedKeyOrder(findD);
       
   240             iDestinationArray.Remove(index);
       
   241             delete aDestination;
       
   242             }        
       
   243         }
       
   244     else
       
   245         { // this is a new destination which hasn't been updated yet
       
   246         // there may be more than one dest with id 0 -> must search by 
       
   247         // iDestinationItem        
       
   248         for (TInt index = 0; index < iDestinationArray.Count(); index++)
       
   249             {
       
   250             if ( iDestinationArray[index].iDestinationItem == 
       
   251                  aDestination )
       
   252                 {
       
   253                 aDestination->DecrementRefCounter();
       
   254                 if (!aDestination->GetRefCounter())
       
   255                     {// this was the last reference -> must delete        
       
   256                     iDestinationArray.Remove(index);
       
   257                     delete aDestination;
       
   258                     }
       
   259                 break;    
       
   260                 }
       
   261             }                
       
   262         }
       
   263     }
       
   264 
       
   265 void CCMObjectPool::RemoveDestination( CCmDestinationImpl* aDestination )
       
   266     {
       
   267     RemoveDestination(aDestination->GetData());
       
   268     aDestination->SetData(NULL);
       
   269     }
       
   270 
       
   271 void CCMObjectPool::DestinationUpdated( CCmDestinationImpl* aDestination )
       
   272     {
       
   273     // there may be more than one dest with id 0 -> must search by 
       
   274     // iDestinationItem        
       
   275     for (TInt index = 0; index < iDestinationArray.Count(); index++)
       
   276         {
       
   277         if ( iDestinationArray[index].iDestinationItem == 
       
   278                 aDestination->GetData() )
       
   279             {
       
   280             if (aDestination->IdIsValid()) break; //allready updated
       
   281             iDestinationArray[index].iDestinationId = aDestination->Id();
       
   282             iDestinationArray.SortUnsigned();
       
   283             break;    
       
   284             }
       
   285         }        
       
   286     }
       
   287 
       
   288 void CCMObjectPool::ConnMethodUpdatedL( CCmPluginBaseEng* aCM )
       
   289     {
       
   290     // there may be more than one dest with id 0 -> must search by 
       
   291     // iDestinationItem        
       
   292     for (TInt index = 0; index < iConnectionMethodArray.Count(); index++)
       
   293         {
       
   294         if ( iConnectionMethodArray[index].iConnectionMethodItem == 
       
   295                 aCM )
       
   296             {
       
   297             TInt cmId = aCM->GetIntAttributeL(CMManager::ECmId);
       
   298             iConnectionMethodArray[index].iConnectionMethodId = cmId;
       
   299             iConnectionMethodArray.SortUnsigned();
       
   300             break;    
       
   301             }
       
   302         }        
       
   303     }
       
   304 
       
   305 void CCMObjectPool::RemoveConnectionMethodL( CCmPluginBase* aCM)
       
   306     {
       
   307     RemoveConnectionMethodL(aCM->Plugin());
       
   308     aCM->SetPlugin(NULL);
       
   309     }
       
   310 
       
   311 void CCMObjectPool::RemoveConnectionMethodL( CCmPluginBaseEng* aCM)
       
   312     {
       
   313     if (aCM->IdIsValid())
       
   314         {
       
   315         aCM->DecrementRefCounter();
       
   316         if (!aCM->GetRefCounter())
       
   317             {// this was the last reference -> must delete        
       
   318             TUint32 cmId = aCM->GetIntAttributeL(CMManager::ECmId);
       
   319             TObjectPoolCMItem findD( NULL, cmId );
       
   320             TInt index = iConnectionMethodArray.FindInUnsignedKeyOrder(findD);
       
   321             iConnectionMethodArray.Remove(index);
       
   322             delete aCM;
       
   323             }        
       
   324         }
       
   325     else
       
   326         { // this is a new cm which hasn't been updated yet
       
   327         // there may be more than one cm with id 0 -> must search by pointer
       
   328         for (TInt index = 0; index < iConnectionMethodArray.Count(); index++)
       
   329             {
       
   330             if ( iConnectionMethodArray[index].iConnectionMethodItem == aCM )
       
   331                 {
       
   332                 aCM->DecrementRefCounter();
       
   333                 if (!aCM->GetRefCounter())
       
   334                     {// this was the last reference -> must delete        
       
   335                     iConnectionMethodArray.Remove(index);
       
   336                     delete aCM;
       
   337                     }
       
   338                 break;    
       
   339                 }
       
   340             }
       
   341         }
       
   342     }
       
   343