lowlevellibsandfws/pluginfw/Framework/frame/DefaultResolver.cpp
author hgs
Tue, 20 Jul 2010 16:35:53 +0530
changeset 44 97b0fb8a2cc2
parent 0 e4d67989cc36
permissions -rw-r--r--
201025

// 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 the default CDefaultResolver class.
// 
//

/**
 @file
 @internalComponent
*/

#include <ecom/ecom.h>
#include <ecom/ecomerrorcodes.h>
#include <ecom/ecomresolverparams.h>
#include <ecom/implementationinformation.h>

#include "TestUtilities.h"	// For __FILE__LINE__
#include "DefaultResolver.h"

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

// Default d'tor

CDefaultResolver::~CDefaultResolver()
	{
	}

// Default c'tor

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


TUid CDefaultResolver::IdentifyImplementationL(TUid aInterfaceUid, 
											   const TEComResolverParams& aAdditionalParameters) const
	{
	RImplInfoArray* implementationsInfo = ListAllL(aInterfaceUid, aAdditionalParameters);
	TUid found = Resolve(*implementationsInfo, aAdditionalParameters);
	implementationsInfo->Reset();
	delete implementationsInfo;
	return found;
	}


TUid CDefaultResolver::Resolve(const RImplInfoArray& aImplementationsInfo, 
							   const TEComResolverParams& aAdditionalParameters) const
	{
	// Place to store the result if we get a wildcard match
	TUid wildMatched = KNullUid;
	TInt wildConfidence = KErrNotFound;
	const TDesC8& matchType = aAdditionalParameters.DataType();

	// Loop through the implementations matching on type
	const TInt count = aImplementationsInfo.Count();
	TBool isGenericMatch=aAdditionalParameters.IsGenericMatch();
	for(TInt index = 0; index < count; ++index)
		{
		const CImplementationInformation& impData = *aImplementationsInfo[index];
		const TDesC8& dataType = impData.DataType();

		// As soon as we get a match on the datatype then return uid of the 
		// implementation found.
		if(Match(dataType,	// The Datatype of this implementation
				 matchType,	// The type we are trying to find
				 EFalse))	// Don't use wildcards first
			{
			// We have got an exact match so return this
			return impData.ImplementationUid();
			}
		else if(isGenericMatch) // If the client wants us to use wildcards
			{
			if(Match(dataType,
					 matchType,
					 ETrue))
				{
				// We have matched using wildcards so work out a confidence value
				TInt confidence = 0;
				TInt length = Min(matchType.Length(), dataType.Length());
				while((matchType[confidence] == dataType[confidence]) && 
					  (++confidence < length))
					{
					}
				if(confidence > wildConfidence)
					{
					wildConfidence = confidence;
					wildMatched = impData.ImplementationUid();
					}
				}
			}
		}

	return wildMatched;
	}

void CloseAndDeleteRArray(TAny* aObject)
	{
	RImplInfoArray* array=reinterpret_cast<RImplInfoArray*>(aObject);
	if (array)
		array->Close();
	delete array;
	}


RImplInfoArray* CDefaultResolver::ListAllL(TUid aInterfaceUid, 
										   const TEComResolverParams& aAdditionalParameters) const
	{
	// Use the member var to create the array so that we get proper cleanup behaviour
	RImplInfoArray* retList = new (ELeave) RImplInfoArray;
	
	CleanupStack::PushL(TCleanupItem(CloseAndDeleteRArray,retList));
	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
	CleanupStack::Pop();
	return retList;
	}

TBool CDefaultResolver::Match(const TDesC8& aImplementationType, 
							  const TDesC8& aMatchType, 
							  TBool aUseWildcards) const
	{
	// In this function if allowing wildcards then TDesC8::Match is used which returns 
	// the position of the match or KErrNotFound
	// If not allowing wildcards then TDesC8::Compare is used which returns a TInt which
	// indicates if one descriptor is bigger than the other (0 if they are identical)

	TBool gotMatch = ETrue;
	
	if(aMatchType.Length()!=0)
	{
		gotMatch = EFalse;
		
		_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)
				gotMatch = aMatchType.Match(aImplementationType) != KErrNotFound;
			else
				gotMatch = aMatchType.Compare(aImplementationType) == 0;
			}
		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)
					gotMatch = aMatchType.Match(dataSection) != KErrNotFound;
				else
					gotMatch = aMatchType.Compare(dataSection) == 0;

				// If we found it then no need to continue, so return
				if(gotMatch)
					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)
				gotMatch = aMatchType.Match(dataSection) != KErrNotFound;
			else
				gotMatch = aMatchType.Compare(dataSection) == 0;
			}
		}
		return gotMatch;
	}