--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/ssock/ss_rmetaextensioncontainer.cpp Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,332 @@
+// 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_rmetaextensioncontainer.cpp
+//
+
+
+#include "ss_rmetaextensioncontainer.h"
+#include "ss_cmetaextensioncontainer.h"
+
+using namespace ESock;
+
+_LIT(KMecPanic, "mecpanic");
+
+void PanicMec(TMecPanic aCode)
+ {
+ User::Panic(KMecPanic, aCode);
+ }
+
+// ===========================================================
+// RMetaExtensionContainerC
+// ===========================================================
+
+EXPORT_C RMetaExtensionContainerC::RMetaExtensionContainerC()
+ : iContainerImpl(NULL)
+ {
+ }
+
+EXPORT_C RMetaExtensionContainerC::~RMetaExtensionContainerC()
+ {
+ }
+
+EXPORT_C void RMetaExtensionContainerC::Open()
+ {
+ __ASSERT_ALWAYS(iContainerImpl, PanicMec(ENoImplementation));
+ iContainerImpl->Open();
+ }
+
+EXPORT_C void RMetaExtensionContainerC::Open(const RMetaExtensionContainerC& aSource)
+ {
+ __ASSERT_ALWAYS(&aSource != this, PanicMec(EInvalidSelfReference));
+ __ASSERT_ALWAYS(aSource.Container(), PanicMec(ENoImplementation));
+ __ASSERT_ALWAYS(!iContainerImpl, PanicMec(EAlreadyOpen));
+
+ aSource.Container()->Open();
+ iContainerImpl = aSource.Container();
+ }
+
+EXPORT_C void RMetaExtensionContainerC::Close()
+ {
+ if (iContainerImpl)
+ {
+ iContainerImpl->Close();
+ iContainerImpl = NULL;
+ }
+ }
+
+EXPORT_C const Meta::SMetaData* RMetaExtensionContainerC::FindExtension(const Meta::STypeId& aTypeId) const
+ {
+ __ASSERT_ALWAYS(iContainerImpl, PanicMec(ENoImplementation));
+ return iContainerImpl->FindExtension(aTypeId);
+ }
+
+
+EXPORT_C const Meta::SMetaData& RMetaExtensionContainerC::FindExtensionL(const Meta::STypeId& aTypeId) const
+ {
+ __ASSERT_ALWAYS(iContainerImpl, PanicMec(ENoImplementation));
+ return iContainerImpl->FindExtensionL(aTypeId);
+ }
+
+
+// ===========================================================
+// RMetaExtensionContainer
+// ===========================================================
+
+EXPORT_C RMetaExtensionContainer::RMetaExtensionContainer()
+ : iIsLazyCreationDone(EFalse), iIsOpen(EFalse), iCurrentExtensionContainer(NULL)
+ {
+ }
+
+
+EXPORT_C void RMetaExtensionContainer::Open()
+ {
+ __ASSERT_ALWAYS(!iIsOpen, PanicMec(EAlreadyOpen));
+
+ // Using lazy creation of the implementation so that Open() is infallible
+ // This boolean ensures that Open() is still called before use of the container
+ iIsOpen = ETrue;
+ }
+
+
+EXPORT_C void RMetaExtensionContainer::Open(const RMetaExtensionContainerC& aBaseContainer)
+ {
+ __ASSERT_ALWAYS(!iIsOpen, PanicMec(EAlreadyOpen));
+ RMetaExtensionContainerC::Open(aBaseContainer);
+ iIsOpen = ETrue;
+ }
+
+
+EXPORT_C void RMetaExtensionContainer::Close()
+ {
+ if (iIsOpen)
+ {
+ if (AppendableExtensionContainer())
+ {
+ AppendableExtensionContainer()->Compact();
+ }
+ iIsOpen = EFalse;
+ }
+
+ RMetaExtensionContainerC::Close();
+ }
+
+
+void RMetaExtensionContainer::CreateExtensionContainerL()
+ {
+ // Don't call it unless it should be created
+ __ASSERT_DEBUG(!AppendableExtensionContainer(), PanicMec(EIllegalState));
+
+ CMetaExtensionContainerImplBase* pendingBaseContainerImpl = NULL;
+ if (!iIsLazyCreationDone)
+ {
+ // Retrieve the pending base container implementation if there is one
+ pendingBaseContainerImpl = Container();
+ }
+
+ CMetaExtensionContainer* mecImpl = CMetaExtensionContainer::NewLC(pendingBaseContainerImpl);
+ if (!iIsLazyCreationDone)
+ {
+ // If there is no proper container implementation this normal extension container
+ // will become it.
+ // Base class takes ownership of the new container implementation reference
+ SetContainer(mecImpl);
+
+ if (pendingBaseContainerImpl)
+ {
+ // Remove the holding reference - the new container implementation has its own
+ pendingBaseContainerImpl->Close();
+ }
+
+ iIsLazyCreationDone = ETrue;
+ }
+ else
+ {
+ // There is an existing container implementation. Given the fact that the
+ // CreateExtensionContainerL method has been called it must be of the
+ // container array type. This will own (the reference on) our new extension
+ // container.
+ __ASSERT_DEBUG(Container()->Type() == CMetaExtensionContainerImplBase::EMetaExtensionContainerArray, PanicMec(EIllegalState));
+ __ASSERT_DEBUG(!pendingBaseContainerImpl, PanicMec(EIllegalState));
+ User::LeaveIfError(AppendableContainerArray()->AppendContainer(*mecImpl));
+ }
+
+ __ASSERT_DEBUG(!iCurrentExtensionContainer, PanicMec(EIllegalState));
+ iCurrentExtensionContainer = mecImpl;
+ CleanupStack::Pop(mecImpl);
+ }
+
+
+void RMetaExtensionContainer::CreateContainerArrayL()
+ {
+ ASSERT(!AppendableContainerArray()); // Don't call it unless it should be created
+
+ CMetaExtensionContainerImplBase* pendingBaseContainerImpl = NULL;
+ if (!iIsLazyCreationDone)
+ {
+ // Retrieve the pending base container implementation if there is one
+ pendingBaseContainerImpl = Container();
+ }
+
+ CMetaExtensionContainerArray* mecImpl = CMetaExtensionContainerArray::NewLC(pendingBaseContainerImpl);
+ if (!iIsLazyCreationDone)
+ {
+ // If there is no proper container implementation this container array implementation
+ // will become it.
+ // Base class takes ownership of the new container implementation reference
+ SetContainer(mecImpl);
+
+ if (pendingBaseContainerImpl)
+ {
+ // Remove the holding reference - the new container implementation has its own
+ pendingBaseContainerImpl->Close();
+ }
+
+ iIsLazyCreationDone = ETrue;
+ }
+ else
+ {
+ // There is an existing container implementation. Given the fact that the
+ // CreateContainerArrayL method has been called it must be of the
+ // normal extension container type. This will be replaced with a container
+ // array implementation which will own (the reference on) the existing
+ // container.
+ __ASSERT_DEBUG(Container()->Type() == CMetaExtensionContainerImplBase::EMetaExtensionContainer, PanicMec(EIllegalState));
+ __ASSERT_DEBUG(!pendingBaseContainerImpl, PanicMec(EIllegalState));
+ __ASSERT_DEBUG(iCurrentExtensionContainer, PanicMec(EIllegalState));
+ User::LeaveIfError(mecImpl->AppendContainer(*iCurrentExtensionContainer));
+
+ // Close our reference on the extension container, the container array will open its own
+ iCurrentExtensionContainer->Close();
+ iCurrentExtensionContainer = NULL;
+ SetContainer(mecImpl);
+ }
+
+ CleanupStack::Pop(mecImpl);
+ }
+
+
+EXPORT_C const Meta::SMetaData* RMetaExtensionContainer::FindExtension(const Meta::STypeId& aTypeId) const
+ {
+ __ASSERT_ALWAYS(iIsOpen, PanicMec(ENoImplementation));
+ if (Container())
+ {
+ return Container()->FindExtension(aTypeId);
+ }
+ return NULL;
+ }
+
+
+EXPORT_C const Meta::SMetaData& RMetaExtensionContainer::FindExtensionL(const Meta::STypeId& aTypeId) const
+ {
+ __ASSERT_ALWAYS(iIsOpen, PanicMec(ENoImplementation));
+ if (!Container())
+ {
+ User::Leave(KErrNotFound);
+ }
+ return Container()->FindExtensionL(aTypeId);
+ }
+
+
+EXPORT_C TInt RMetaExtensionContainer::AppendExtension(const Meta::SMetaData* aExtension)
+ {
+ __ASSERT_ALWAYS(iIsOpen, PanicMec(ENoImplementation));
+
+ if (!aExtension)
+ {
+ return KErrArgument;
+ }
+
+ CMetaExtensionContainer* mecImpl = AppendableExtensionContainer();
+ if (!mecImpl)
+ {
+ // Do lazy creation
+ TRAPD(err, CreateExtensionContainerL());
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ mecImpl = AppendableExtensionContainer();
+ }
+
+ return mecImpl->AppendExtension(aExtension);
+ }
+
+
+EXPORT_C void RMetaExtensionContainer::AppendExtensionL(const Meta::SMetaData* aExtension)
+ {
+ __ASSERT_ALWAYS(iIsOpen, PanicMec(ENoImplementation));
+
+ if (!aExtension)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ CMetaExtensionContainer* mecImpl = AppendableExtensionContainer();
+ if (!mecImpl)
+ {
+ // Do lazy creation
+ CreateExtensionContainerL();
+ mecImpl = AppendableExtensionContainer();
+ }
+
+ mecImpl->AppendExtensionL(aExtension);
+ }
+
+
+EXPORT_C void RMetaExtensionContainer::AppendContainerL(const RMetaExtensionContainerC& aContainer)
+ {
+ __ASSERT_ALWAYS(&aContainer != this, PanicMec(EInvalidSelfReference));
+ __ASSERT_ALWAYS(iIsOpen, PanicMec(ENoImplementation));
+
+ CMetaExtensionContainerImplBase* containerImpl = static_cast<const RMetaExtensionContainer&>(aContainer).Container();
+ __ASSERT_ALWAYS(containerImpl, PanicMec(ENoImplementation));
+ __ASSERT_ALWAYS(containerImpl != Container(), PanicMec(EInvalidSelfReference));
+
+ CMetaExtensionContainerArray* mecImpl = AppendableContainerArray();
+ if (!mecImpl)
+ {
+ // Do lazy creation
+ CreateContainerArrayL();
+ mecImpl = AppendableContainerArray();
+ }
+
+ const RMetaExtensionContainer& containerIfc = static_cast<const RMetaExtensionContainer&>(aContainer);
+ User::LeaveIfError(mecImpl->AppendContainer(*containerIfc.Container()));
+
+ // Null the current extension container pointer forcing a new extension container to be
+ // created and appended to the array after the one that has been added
+ iCurrentExtensionContainer = NULL;
+ }
+
+
+CMetaExtensionContainer* RMetaExtensionContainer::AppendableExtensionContainer() const
+ {
+ return iIsLazyCreationDone ? iCurrentExtensionContainer : NULL;
+ }
+
+
+CMetaExtensionContainerArray* RMetaExtensionContainer::AppendableContainerArray() const
+ {
+ if (iIsLazyCreationDone)
+ {
+ const CMetaExtensionContainerImplBase* mecImpl = Container();
+ if (mecImpl && mecImpl->Type() == CMetaExtensionContainerImplBase::EMetaExtensionContainerArray)
+ {
+ return const_cast<CMetaExtensionContainerArray*>(static_cast<const CMetaExtensionContainerArray*>(mecImpl));
+ }
+ }
+ return NULL;
+ }
+
+