lowlevellibsandfws/pluginfw/Framework/Example/ExampleResolver.cpp
author William Roberts <williamr@symbian.org>
Fri, 23 Jul 2010 16:09:54 +0100
branchGCC_SURGE
changeset 47 d7383dba13ba
parent 0 e4d67989cc36
permissions -rw-r--r--
Reapply fix for EXPORT_C problem in backend.dll, which got lost in the merge - bug 2971

// Copyright (c) 1997-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:
// Implements a non-default resolver CExampleResolver.
// 
//

/**
 @internalComponent
*/

#include <ecom/ecom.h>

#include "ExampleResolver.h"
#include "RegistryData.h"

CExampleResolver* CExampleResolver::NewL(MPublicRegistry& aRegistry)
	{
	return new(ELeave) CExampleResolver(aRegistry);
	}

CExampleResolver::~CExampleResolver()
	{
	if(iImplementationInfoArray)
		{
		iImplementationInfoArray->Reset();
		delete iImplementationInfoArray;
		}
	}

CExampleResolver::CExampleResolver(MPublicRegistry& aRegistry)
: CResolver(aRegistry)
	{
	// Do nothing here
	}

TUid CExampleResolver::IdentifyImplementationL(TUid aInterfaceUid, 
											   const TEComResolverParams& aAdditionalParameters) const
	{
	RImplInfoArray& implementationsInfo = iRegistry.ListImplementationsL(aInterfaceUid);
	TUid found = KNullUid;
	if(implementationsInfo.Count())
		{
		found = Resolve(implementationsInfo, aAdditionalParameters);
		}
	return found;
	}

TUid CExampleResolver::Resolve(const RImplInfoArray& aImplementationsInfo, 
							   const TEComResolverParams& aAdditionalParameters) const
	{
	// Loop through the implementations matching on type
	const TInt count = aImplementationsInfo.Count();
	for(TInt index = 0; index < count; ++index)
		{
		const CImplementationInformation& impData = *aImplementationsInfo[index];
		// As soon as we get a match on the datatype then return uid of the 
		// implementation found.
		if (Match(impData.DataType(),						// The Datatype of this implementation
				  aAdditionalParameters.DataType(),			// The type we are trying to find
				  aAdditionalParameters.IsGenericMatch()))	// If wildcards should be used
			return impData.ImplementationUid();
		}

	return KNullUid;
	}

RImplInfoArray* CExampleResolver::ListAllL(TUid aInterfaceUid, 
										   const TEComResolverParams& aAdditionalParameters) const
	{
	//Simulation for INC054125 - ECOM cleanup stack error
	_LIT8(KCriteriaData, "INC054125");
	const TDesC8& dataType = aAdditionalParameters.DataType();
	if(aInterfaceUid.iUid == 0x10009DC8 && dataType.Compare(KCriteriaData) == 0)
		{
		User::Leave(KErrGeneral);
		}
	// Use the member var to create the array so that we get proper cleanup behaviour
	iImplementationInfoArray = new(ELeave) RImplInfoArray;
	RImplInfoArray* retList = iImplementationInfoArray;

	RImplInfoArray& fullList = iRegistry.ListImplementationsL(aInterfaceUid);

	const TBool useWildcards = aAdditionalParameters.IsGenericMatch();
	const TDesC8& matchType = aAdditionalParameters.DataType();
	const TInt numImps = fullList.Count();
	for(TInt index = 0; index < numImps; ++index)
		{
		if(Match(fullList[index]->DataType(), matchType, useWildcards))
			{
			User::LeaveIfError(retList->Append(fullList[index]));
			}
		}

	// Reset the member variable because we are passing ownership back
	iImplementationInfoArray = NULL;
	return retList;
	}

TBool CExampleResolver::Match(const TDesC8& aImplementationType, 
							  const TDesC8& aMatchType, 
							  TBool aUseWildcards) const
	{
	TInt matchPos = KErrNotFound;

	_LIT8(dataSeparator, "||");
	const TInt separatorLength = dataSeparator().Length();

	// Look for the section separator marker '||'
	TInt separatorPos = aImplementationType.Find(dataSeparator);
	if(separatorPos == KErrNotFound)
		{
		// Match against the whole string
		if(aUseWildcards)
			matchPos = aMatchType.Match(aImplementationType);
		else
			matchPos = aMatchType.Compare(aImplementationType);
		}
	else
		{
		// Find the first section, up to the separator
		TPtrC8 dataSection = aImplementationType.Left(separatorPos);
		TPtrC8 remainingData = aImplementationType.Mid(separatorPos + separatorLength);
		// Match against each section in turn
		while(separatorPos != KErrNotFound)
			{
			// Search this section
			if(aUseWildcards)
				matchPos = aMatchType.Match(dataSection);
			else
				matchPos = aMatchType.Compare(dataSection);

			// If we found it then no need to continue, so return
			if(matchPos != KErrNotFound)
				return ETrue;

			// Move on to the next section
			separatorPos = remainingData.Find(dataSeparator);
			if(separatorPos != KErrNotFound)
				{
				dataSection.Set(remainingData.Left(separatorPos));
				remainingData.Set(remainingData.Mid(separatorPos + separatorLength));
				}
			else
				dataSection.Set(remainingData);
			}

		// Check the final part
		if(aUseWildcards)
			matchPos = aMatchType.Match(dataSection);
		else
			matchPos = aMatchType.Compare(dataSection);

		}
	return matchPos != KErrNotFound;
	}