--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/ssock/ss_cmetaextensioncontainer.cpp Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,340 @@
+// Copyright (c) 2005-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:
+// ss_cmetaextensioncontainer.cpp
+//
+
+
+#include "ss_cmetaextensioncontainer.h"
+#include <comms-infras/ss_log.h>
+
+using namespace ESock;
+
+const TInt KReservedContainerSlots = 4;
+const TInt KReservedExtensionSlots = 4;
+
+
+
+// ===========================================================
+// CMetaExtensionContainerImplBase
+// ===========================================================
+
+void CMetaExtensionContainerImplBase::DeletePtr()
+ {
+ }
+
+const Meta::SMetaData& CMetaExtensionContainerImplBase::FindExtensionL(const Meta::STypeId& aTypeId) const
+ {
+ const Meta::SMetaData* ext = FindExtension(aTypeId);
+ if (!ext)
+ {
+ User::Leave(KErrNotFound);
+ }
+ return *ext;
+ }
+
+
+
+// ===========================================================
+// CMetaExtensionContainer
+// ===========================================================
+
+CMetaExtensionContainer* CMetaExtensionContainer::NewLC(const CMetaExtensionContainerImplBase* aBaseContainer)
+ {
+ CMetaExtensionContainer* self = new(ELeave)CMetaExtensionContainer();
+ CleanupStack::PushL(self);
+ LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::NewLC() - [this=%x] [baseContainer=%x]"), self, aBaseContainer));
+ self->ConstructL(aBaseContainer);
+ return self;
+ }
+
+
+CMetaExtensionContainer::~CMetaExtensionContainer()
+ {
+ iExtensions.ResetAndDestroy();
+ iExtensions.Close();
+
+#ifndef MEC_UNITTEST
+ LOG_NODE_DESTROY(KESockComponentTag, CMetaExtensionContainer);
+#endif
+ }
+
+CMetaExtensionContainer::CMetaExtensionContainer()
+ : CMetaExtensionContainerImplBase(EMetaExtensionContainer)
+ {
+#ifndef MEC_UNITTEST
+ LOG_NODE_CREATE(KESockComponentTag, CMetaExtensionContainer);
+#endif
+ }
+
+
+void CMetaExtensionContainer::ConstructL(const CMetaExtensionContainerImplBase* aBaseContainer)
+ {
+ iExtensions.ReserveL(KReservedExtensionSlots);
+ if (aBaseContainer)
+ {
+ SetBaseContainer(aBaseContainer);
+ }
+ }
+
+
+void CMetaExtensionContainer::DeletePtr()
+ {
+ // Releasing references to any base containers
+ if (iBaseContainer)
+ {
+ const_cast<CMetaExtensionContainerImplBase*>(iBaseContainer)->Close();
+ iBaseContainer = NULL;
+ }
+ }
+
+
+const CMetaExtensionContainerImplBase* CMetaExtensionContainer::BaseContainer() const
+ {
+ return iBaseContainer;
+ }
+
+
+void CMetaExtensionContainer::SetBaseContainer(const CMetaExtensionContainerImplBase* aBaseContainer)
+ {
+ ASSERT(aBaseContainer);
+ ASSERT(!iBaseContainer);
+ const_cast<CMetaExtensionContainerImplBase*>(aBaseContainer)->Open();
+ iBaseContainer = aBaseContainer;
+ }
+
+
+void CMetaExtensionContainer::RemoveBaseContainer()
+ {
+ // Only call this if the cleanup checks have been done and it makes sense
+ ASSERT(iBaseContainer && iBaseContainer->Type() == EMetaExtensionContainer);
+
+ const CMetaExtensionContainer* oldBaseMecImpl = static_cast<const CMetaExtensionContainer*>(iBaseContainer);
+ const CMetaExtensionContainerImplBase* newBaseMecImpl = oldBaseMecImpl->iBaseContainer;
+ if (newBaseMecImpl)
+ {
+ // Do this before assigning iBaseContainer to ensure the reference is there
+ // to hold it open
+ const_cast<CMetaExtensionContainerImplBase*>(newBaseMecImpl)->Open();
+ }
+ iBaseContainer = newBaseMecImpl;
+ const_cast<CMetaExtensionContainer*>(oldBaseMecImpl)->Close();
+ }
+
+
+const Meta::SMetaData* CMetaExtensionContainer::FindExtension(const Meta::STypeId& aTypeId) const
+ {
+ const Meta::SMetaData* ext = FindExtensionInThisContainer(aTypeId);
+
+ if (!ext && BaseContainer())
+ {
+ ext = BaseContainer()->FindExtension(aTypeId);
+ }
+
+ return ext;
+ }
+
+
+const Meta::SMetaData* CMetaExtensionContainer::FindExtensionInThisContainer(const Meta::STypeId& aTypeId) const
+ {
+ TInt length = iExtensions.Count();
+ for (TUint i = 0; i < length; ++i)
+ {
+ if (iExtensions[i]->Object()->GetTypeId() == aTypeId)
+ {
+ return iExtensions[i]->Object();
+ }
+ }
+
+ return NULL;
+ }
+
+
+
+TInt CMetaExtensionContainer::AppendExtension(const Meta::SMetaData* aExtension)
+ {
+ TRAPD(err, AppendExtensionL(aExtension));
+ return err;
+ }
+
+
+void CMetaExtensionContainer::AppendExtensionL(const Meta::SMetaData* aExtension)
+ {
+ if (aExtension == NULL)
+ {
+ LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::AppendExtensionL() - NULL extension pointer [this=%x]"), this));
+ User::Leave(KErrArgument);
+ }
+
+ if (FindExtensionInThisContainer(aExtension->GetTypeId()) != NULL)
+ {
+ LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::AppendExtensionL() - duplicate extension (%08x) ID %x:%x added [this=%x]"),
+ aExtension, aExtension->GetTypeId().iUid.iUid, aExtension->GetTypeId().iType, this));
+
+#if defined(_DEBUG) && !defined(MEC_UNITTEST)
+ _LIT(KMECPanic, "esockmec");
+ //Included in DEBUG mode as extension should not be added if already part of iExtensions
+ //Brings attention to coding error that should be fixed before release.
+ __ASSERT_DEBUG(EFalse, User::Panic(KMECPanic(), 0));
+#endif
+
+ User::Leave(KErrAlreadyExists);
+ }
+
+ Meta::TMetaDataDeAllocator* deallocator = Meta::TMetaDataDeAllocator::NewLC(aExtension);
+ TInt ret = iExtensions.Append(deallocator);
+ if(KErrNone != ret)
+ {
+ deallocator->LeaveObject();
+ User::Leave(ret);
+ }
+
+ LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::AppendExtensionL() - extension (%08x) ID %x:%x added [this=%x]"),
+ aExtension, aExtension->GetTypeId().iUid.iUid, aExtension->GetTypeId().iType, this));
+
+ CleanupStack::Pop(deallocator);
+ }
+
+
+void CMetaExtensionContainer::Compact()
+ {
+ const CMetaExtensionContainer* baseMecImpl = NULL;
+
+ while (baseMecImpl != BaseContainer())
+ {
+ // We have a base container, and its the first time through the loop
+ // or its not the same as the last execution of the loop
+ baseMecImpl = static_cast<const CMetaExtensionContainer*>(BaseContainer());
+
+ if (!baseMecImpl || baseMecImpl->Type() != EMetaExtensionContainer
+ || baseMecImpl->iExtensions.Count() > iExtensions.Count())
+ {
+ // There is no base container, OR the base container isn't an extension
+ // container implementation, OR the immediate base container holds
+ // more extensions than this container does and it cannot be removed
+ // since there is no way this container can be overriding all of them.
+ return;
+ }
+
+ // Check if all of the base container extensions are overridden by ours
+ TInt count = baseMecImpl->iExtensions.Count();
+ Meta::STypeId typeId;
+ for (TInt i=0; i<count; i++)
+ {
+ typeId = baseMecImpl->iExtensions[i]->Object()->GetTypeId();
+ const Meta::SMetaData* ext = FindExtensionInThisContainer(typeId);
+ if (!ext)
+ {
+ // Not all of the extensions in the base container are overridden
+ return;
+ }
+ }
+
+ // If we made it here this container overrides all of the extensions in the
+ // immediate base container. We can remove it from our chain.
+ RemoveBaseContainer();
+ }
+ }
+
+
+// ===========================================================
+// CMetaExtensionContainerArray
+// ===========================================================
+
+CMetaExtensionContainerArray* CMetaExtensionContainerArray::NewLC(const CMetaExtensionContainerImplBase* aBaseContainer)
+ {
+ CMetaExtensionContainerArray* self = new(ELeave)CMetaExtensionContainerArray();
+ CleanupStack::PushL(self);
+ LOG(ESockLog::Printf(_L8("CMetaExtensionContainerArray::NewLC() - [this=%x] [baseContainer=%x]"), self, aBaseContainer));
+ self->ConstructL(aBaseContainer);
+ return self;
+ }
+
+
+CMetaExtensionContainerArray::~CMetaExtensionContainerArray()
+ {
+ iContainers.Close();
+
+#ifndef MEC_UNITTEST
+ LOG_NODE_DESTROY(KESockComponentTag, CMetaExtensionContainerArray);
+#endif
+ }
+
+
+CMetaExtensionContainerArray::CMetaExtensionContainerArray()
+ : CMetaExtensionContainerImplBase(EMetaExtensionContainerArray)
+ {
+#ifndef MEC_UNITTEST
+ LOG_NODE_CREATE(KESockComponentTag, CMetaExtensionContainerArray);
+#endif
+ }
+
+
+void CMetaExtensionContainerArray::ConstructL(const CMetaExtensionContainerImplBase* aBaseContainer)
+ {
+ iContainers.ReserveL(KReservedContainerSlots);
+ if (aBaseContainer)
+ {
+ iContainers.AppendL(aBaseContainer);
+ const_cast<CMetaExtensionContainerImplBase*>(aBaseContainer)->Open();
+ }
+ }
+
+
+void CMetaExtensionContainerArray::DeletePtr()
+ {
+ TInt i = iContainers.Count();
+ while (i--)
+ {
+ const_cast<CMetaExtensionContainerImplBase*>(iContainers[i])->Close();
+ }
+ }
+
+
+const Meta::SMetaData* CMetaExtensionContainerArray::FindExtension(const Meta::STypeId& aTypeId) const
+ {
+ const Meta::SMetaData* ext = NULL;
+
+ TInt i = iContainers.Count();
+ while (!ext && i--)
+ {
+ ext = iContainers[i]->FindExtension(aTypeId);
+ }
+
+ return ext;
+ }
+
+
+TInt CMetaExtensionContainerArray::AppendContainer(const CMetaExtensionContainerImplBase& aContainer)
+ {
+ TInt length = iContainers.Count();
+ for (TUint i = 0; i < length; ++i)
+ {
+ if (iContainers[i] == &aContainer)
+ {
+ return KErrAlreadyExists;
+ }
+ }
+
+ TInt err = iContainers.Append(&aContainer);
+ if (err == KErrNone)
+ {
+ // Add a reference to the container
+ const_cast<CMetaExtensionContainerImplBase&>(aContainer).Open();
+ }
+ return err;
+ }
+
+
+
+