datacommsserver/esockserver/ssock/ss_cmetaextensioncontainer.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2005-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 // ss_cmetaextensioncontainer.cpp 
       
    15 //
       
    16 
       
    17 
       
    18 #include "ss_cmetaextensioncontainer.h"
       
    19 #include <comms-infras/ss_log.h>
       
    20 
       
    21 using namespace ESock;
       
    22 
       
    23 const TInt KReservedContainerSlots = 4;
       
    24 const TInt KReservedExtensionSlots = 4;
       
    25 
       
    26 
       
    27 
       
    28 // ===========================================================
       
    29 // CMetaExtensionContainerImplBase
       
    30 // ===========================================================
       
    31 
       
    32 void CMetaExtensionContainerImplBase::DeletePtr()
       
    33     {
       
    34     }
       
    35 
       
    36 const Meta::SMetaData& CMetaExtensionContainerImplBase::FindExtensionL(const Meta::STypeId& aTypeId) const
       
    37     {
       
    38     const Meta::SMetaData* ext = FindExtension(aTypeId);
       
    39     if (!ext)
       
    40         {
       
    41         User::Leave(KErrNotFound);
       
    42         }
       
    43     return *ext;
       
    44     }
       
    45 
       
    46 
       
    47 
       
    48 // ===========================================================
       
    49 // CMetaExtensionContainer
       
    50 // ===========================================================
       
    51 
       
    52 CMetaExtensionContainer* CMetaExtensionContainer::NewLC(const CMetaExtensionContainerImplBase* aBaseContainer)
       
    53     {
       
    54     CMetaExtensionContainer* self = new(ELeave)CMetaExtensionContainer();
       
    55     CleanupStack::PushL(self);
       
    56     LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::NewLC() - [this=%x] [baseContainer=%x]"), self, aBaseContainer));
       
    57     self->ConstructL(aBaseContainer);
       
    58     return self;
       
    59     }
       
    60 
       
    61 
       
    62 CMetaExtensionContainer::~CMetaExtensionContainer()
       
    63     {
       
    64     iExtensions.ResetAndDestroy();
       
    65     iExtensions.Close();
       
    66     
       
    67 #ifndef MEC_UNITTEST
       
    68     LOG_NODE_DESTROY(KESockComponentTag, CMetaExtensionContainer);
       
    69 #endif
       
    70     }
       
    71 
       
    72 CMetaExtensionContainer::CMetaExtensionContainer()
       
    73 	: CMetaExtensionContainerImplBase(EMetaExtensionContainer)
       
    74     {
       
    75 #ifndef MEC_UNITTEST
       
    76     LOG_NODE_CREATE(KESockComponentTag, CMetaExtensionContainer);
       
    77 #endif
       
    78     }
       
    79 
       
    80 
       
    81 void CMetaExtensionContainer::ConstructL(const CMetaExtensionContainerImplBase* aBaseContainer)
       
    82 	{
       
    83 	iExtensions.ReserveL(KReservedExtensionSlots);
       
    84     if (aBaseContainer)
       
    85         {
       
    86         SetBaseContainer(aBaseContainer);
       
    87         }
       
    88 	}
       
    89 
       
    90 
       
    91 void CMetaExtensionContainer::DeletePtr()
       
    92     {
       
    93     // Releasing references to any base containers
       
    94     if (iBaseContainer)
       
    95         {
       
    96         const_cast<CMetaExtensionContainerImplBase*>(iBaseContainer)->Close();
       
    97         iBaseContainer = NULL;
       
    98         }    
       
    99     }
       
   100 
       
   101 
       
   102 const CMetaExtensionContainerImplBase* CMetaExtensionContainer::BaseContainer() const
       
   103     {
       
   104     return iBaseContainer;
       
   105     }
       
   106 
       
   107 
       
   108 void CMetaExtensionContainer::SetBaseContainer(const CMetaExtensionContainerImplBase* aBaseContainer)
       
   109     {
       
   110     ASSERT(aBaseContainer);
       
   111     ASSERT(!iBaseContainer);
       
   112     const_cast<CMetaExtensionContainerImplBase*>(aBaseContainer)->Open();
       
   113     iBaseContainer = aBaseContainer;
       
   114     }
       
   115 
       
   116 
       
   117 void CMetaExtensionContainer::RemoveBaseContainer()
       
   118     {
       
   119     // Only call this if the cleanup checks have been done and it makes sense
       
   120     ASSERT(iBaseContainer && iBaseContainer->Type() == EMetaExtensionContainer);
       
   121     
       
   122     const CMetaExtensionContainer* oldBaseMecImpl = static_cast<const CMetaExtensionContainer*>(iBaseContainer);
       
   123     const CMetaExtensionContainerImplBase* newBaseMecImpl = oldBaseMecImpl->iBaseContainer;
       
   124     if (newBaseMecImpl)
       
   125         {
       
   126         // Do this before assigning iBaseContainer to ensure the reference is there
       
   127         // to hold it open
       
   128         const_cast<CMetaExtensionContainerImplBase*>(newBaseMecImpl)->Open();
       
   129         }
       
   130     iBaseContainer = newBaseMecImpl;
       
   131     const_cast<CMetaExtensionContainer*>(oldBaseMecImpl)->Close();
       
   132     }
       
   133 
       
   134 
       
   135 const Meta::SMetaData* CMetaExtensionContainer::FindExtension(const Meta::STypeId& aTypeId) const
       
   136     {
       
   137 	const Meta::SMetaData* ext = FindExtensionInThisContainer(aTypeId);
       
   138 
       
   139     if (!ext && BaseContainer())
       
   140         {
       
   141         ext = BaseContainer()->FindExtension(aTypeId);
       
   142         }
       
   143     
       
   144     return ext;
       
   145     }
       
   146 
       
   147 
       
   148 const Meta::SMetaData* CMetaExtensionContainer::FindExtensionInThisContainer(const Meta::STypeId& aTypeId) const
       
   149 	{
       
   150     TInt length = iExtensions.Count();
       
   151     for (TUint i = 0; i < length; ++i)
       
   152          {
       
   153          if (iExtensions[i]->Object()->GetTypeId() == aTypeId)
       
   154              {
       
   155              return iExtensions[i]->Object();
       
   156              }
       
   157          }
       
   158 
       
   159 	return NULL;
       
   160 	}
       
   161 
       
   162 
       
   163 
       
   164 TInt CMetaExtensionContainer::AppendExtension(const Meta::SMetaData* aExtension)
       
   165     {
       
   166     TRAPD(err, AppendExtensionL(aExtension));
       
   167     return err;
       
   168     }
       
   169 
       
   170 
       
   171 void CMetaExtensionContainer::AppendExtensionL(const Meta::SMetaData* aExtension)
       
   172     {
       
   173     if (aExtension == NULL)
       
   174         {
       
   175         LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::AppendExtensionL() - NULL extension pointer [this=%x]"), this));
       
   176         User::Leave(KErrArgument);
       
   177         }
       
   178 
       
   179     if (FindExtensionInThisContainer(aExtension->GetTypeId()) != NULL)
       
   180         {        
       
   181         LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::AppendExtensionL() - duplicate extension (%08x) ID %x:%x added  [this=%x]"),
       
   182                 aExtension, aExtension->GetTypeId().iUid.iUid, aExtension->GetTypeId().iType, this));
       
   183 
       
   184 #if defined(_DEBUG) && !defined(MEC_UNITTEST)
       
   185         _LIT(KMECPanic, "esockmec");
       
   186         //Included in DEBUG mode as extension should not be added if already part of iExtensions
       
   187         //Brings attention to coding error that should be fixed before release.
       
   188         __ASSERT_DEBUG(EFalse, User::Panic(KMECPanic(), 0));
       
   189 #endif
       
   190         
       
   191         User::Leave(KErrAlreadyExists);
       
   192         }
       
   193 
       
   194     Meta::TMetaDataDeAllocator* deallocator = Meta::TMetaDataDeAllocator::NewLC(aExtension);
       
   195     TInt ret = iExtensions.Append(deallocator);
       
   196     if(KErrNone != ret)
       
   197         {
       
   198         deallocator->LeaveObject();
       
   199         User::Leave(ret);
       
   200         }
       
   201 
       
   202     LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::AppendExtensionL() - extension (%08x) ID %x:%x added  [this=%x]"),
       
   203             aExtension, aExtension->GetTypeId().iUid.iUid, aExtension->GetTypeId().iType, this));
       
   204 
       
   205     CleanupStack::Pop(deallocator);
       
   206     }
       
   207 
       
   208 
       
   209 void CMetaExtensionContainer::Compact()
       
   210     {
       
   211     const CMetaExtensionContainer* baseMecImpl = NULL;
       
   212     
       
   213     while (baseMecImpl != BaseContainer())
       
   214         {
       
   215         // We have a base container, and its the first time through the loop
       
   216         // or its not the same as the last execution of the loop 
       
   217         baseMecImpl = static_cast<const CMetaExtensionContainer*>(BaseContainer());
       
   218         
       
   219         if (!baseMecImpl || baseMecImpl->Type() != EMetaExtensionContainer
       
   220         		|| baseMecImpl->iExtensions.Count() > iExtensions.Count())
       
   221             {
       
   222             // There is no base container, OR the base container isn't an extension
       
   223             // container implementation, OR the immediate base container holds
       
   224             // more extensions than this container does and it cannot be removed
       
   225             // since there is no way this container can be overriding all of them.
       
   226             return;
       
   227             }
       
   228     
       
   229         // Check if all of the base container extensions are overridden by ours
       
   230         TInt count = baseMecImpl->iExtensions.Count();
       
   231         Meta::STypeId typeId; 
       
   232         for (TInt i=0; i<count; i++)
       
   233             {
       
   234             typeId = baseMecImpl->iExtensions[i]->Object()->GetTypeId();
       
   235             const Meta::SMetaData* ext = FindExtensionInThisContainer(typeId);
       
   236             if (!ext)
       
   237                 {
       
   238                 // Not all of the extensions in the base container are overridden
       
   239                 return;
       
   240                 }
       
   241             }
       
   242         
       
   243         // If we made it here this container overrides all of the extensions in the
       
   244         // immediate base container. We can remove it from our chain.
       
   245         RemoveBaseContainer();
       
   246         }
       
   247     }
       
   248 
       
   249 
       
   250 // ===========================================================
       
   251 // CMetaExtensionContainerArray
       
   252 // ===========================================================
       
   253 
       
   254 CMetaExtensionContainerArray* CMetaExtensionContainerArray::NewLC(const CMetaExtensionContainerImplBase* aBaseContainer)
       
   255     {
       
   256     CMetaExtensionContainerArray* self = new(ELeave)CMetaExtensionContainerArray();
       
   257     CleanupStack::PushL(self);
       
   258     LOG(ESockLog::Printf(_L8("CMetaExtensionContainerArray::NewLC() - [this=%x] [baseContainer=%x]"), self, aBaseContainer));
       
   259     self->ConstructL(aBaseContainer);
       
   260     return self;
       
   261     }
       
   262 
       
   263 
       
   264 CMetaExtensionContainerArray::~CMetaExtensionContainerArray()
       
   265     {
       
   266     iContainers.Close();
       
   267 
       
   268 #ifndef MEC_UNITTEST
       
   269     LOG_NODE_DESTROY(KESockComponentTag, CMetaExtensionContainerArray);
       
   270 #endif
       
   271     }
       
   272 
       
   273 
       
   274 CMetaExtensionContainerArray::CMetaExtensionContainerArray()
       
   275 	: CMetaExtensionContainerImplBase(EMetaExtensionContainerArray)
       
   276     {
       
   277 #ifndef MEC_UNITTEST
       
   278     LOG_NODE_CREATE(KESockComponentTag, CMetaExtensionContainerArray);
       
   279 #endif
       
   280     }
       
   281 
       
   282 
       
   283 void CMetaExtensionContainerArray::ConstructL(const CMetaExtensionContainerImplBase* aBaseContainer)
       
   284 	{
       
   285 	iContainers.ReserveL(KReservedContainerSlots);
       
   286 	if (aBaseContainer)
       
   287 		{
       
   288 		iContainers.AppendL(aBaseContainer);
       
   289 		const_cast<CMetaExtensionContainerImplBase*>(aBaseContainer)->Open();
       
   290 		}
       
   291 	}
       
   292 
       
   293 
       
   294 void CMetaExtensionContainerArray::DeletePtr()
       
   295     {
       
   296 	TInt i = iContainers.Count();
       
   297 	while (i--)
       
   298 		{
       
   299 		const_cast<CMetaExtensionContainerImplBase*>(iContainers[i])->Close();
       
   300 		}  
       
   301     }
       
   302 
       
   303 
       
   304 const Meta::SMetaData* CMetaExtensionContainerArray::FindExtension(const Meta::STypeId& aTypeId) const
       
   305 	{
       
   306 	const Meta::SMetaData* ext = NULL;
       
   307 	
       
   308 	TInt i = iContainers.Count();
       
   309 	while (!ext && i--)
       
   310 		{
       
   311 		ext = iContainers[i]->FindExtension(aTypeId);
       
   312 		}
       
   313 	
       
   314 	return ext;
       
   315 	}    
       
   316 
       
   317 
       
   318 TInt CMetaExtensionContainerArray::AppendContainer(const CMetaExtensionContainerImplBase& aContainer)
       
   319 	{
       
   320     TInt length = iContainers.Count();
       
   321     for (TUint i = 0; i < length; ++i)
       
   322          {
       
   323          if (iContainers[i] == &aContainer)
       
   324              {
       
   325              return KErrAlreadyExists;
       
   326              }
       
   327          }
       
   328 
       
   329 	TInt err = iContainers.Append(&aContainer);
       
   330 	if (err == KErrNone)
       
   331 		{
       
   332 		// Add a reference to the container
       
   333 		const_cast<CMetaExtensionContainerImplBase&>(aContainer).Open();
       
   334 		}
       
   335 	return err;
       
   336 	}
       
   337 
       
   338 
       
   339 
       
   340