imagingandcamerafws/imagingfws/ImageDisplay/src/Resolver/ImageDisplayResolver.cpp
branchRCL_3
changeset 50 948c7f65f6d4
parent 0 40261b775718
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingandcamerafws/imagingfws/ImageDisplay/src/Resolver/ImageDisplayResolver.cpp	Wed Sep 01 12:38:50 2010 +0100
@@ -0,0 +1,326 @@
+// Copyright (c) 2004-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:
+//
+
+/** @file
+	@internalComponent */
+#include <ecom/ecom.h>
+#include <ecom/ecomerrorcodes.h>
+#include <ecom/implementationinformation.h>
+
+#include "ImageDisplayResolver.h"
+#include "ImageDisplayResolvrUtils.h"
+
+_LIT(KIclResolverPanicCategory, "ImageDisplayResolver");
+
+// To save some space, we don't support IdentifyImplementationL()
+
+GLDEF_C void Panic(TInt aReason)
+	{
+	User::Panic(KIclResolverPanicCategory, aReason);
+	}
+
+/** 
+ * Constructs and initialises a new instance of CImageDisplayResolver.
+ *
+ * @param     "MPublicRegistry& aRegistry"
+ *            A reference to the registry on which it will operate
+ * @return    "CImageDisplayResolver*"
+ *            A pointer to the newly constructed resolver
+ */
+CImageDisplayResolver* CImageDisplayResolver::NewL(MPublicRegistry& aRegistry)
+	{
+	return new(ELeave) CImageDisplayResolver(aRegistry);
+	}
+
+/** 
+ *
+ * Default destructor
+ *
+ */
+CImageDisplayResolver::~CImageDisplayResolver()
+	{
+	}
+
+/** 
+ *
+ * Default constructor
+ *
+ * @param     "MPublicRegistry& aRegistry"
+ *            A reference to the registry on which it will operate
+ */
+CImageDisplayResolver::CImageDisplayResolver(MPublicRegistry& aRegistry)
+	: CResolver(aRegistry)
+	{
+	}
+
+/** 
+ *
+ * Request that the resolver identify the most appropriate interface
+ * implementation.
+ *
+ * @param     "TUid aInterfaceUid"
+ *            The Uid of the interface you want to match against
+ * @param     "const TEComResolverParams& aAdditionalParameters"
+ *            A passed in reference to the parameters on which to match
+ * @return    "TUid"
+ *            The implementation Uid of the single best match found
+ */
+TUid CImageDisplayResolver::IdentifyImplementationL(TUid /*aInterfaceUid*/, const TEComResolverParams& /*aAdditionalParameters*/) const
+	{
+	// To save some space, we don't support IdentifyImplementationL()
+	return KNullUid;
+	}
+
+/**
+ *
+ * List all the implementations which satisfy the specified interface, ignoring 
+ * any implementations that have their Disabled flag set or are not of the 
+ * current framework version.
+ *
+ * The list is sorted:
+ * 1) For EMatchString in desending order of number of bytes matched and version number.
+ * 2) For EMatchMIMEType in asending order of the MIME position that matched and
+ *    desending version number.
+ * 3) All others - desending version numbers.
+ *
+ * @param     "TUid aInterfaceUid"
+ *            The Uid of the interface you want to match against
+ * @param     "const TEComResolverParams& aAdditionalParameters"
+ *            A passed in reference to the parameters on which to match
+ * @return    "RImplInfoArray*"
+ *            The list of matches found
+ */
+ RImplInfoArray* CImageDisplayResolver::ListAllL(TUid aInterfaceUid, const TEComResolverParams& aAdditionalParameters) const
+	{
+
+	// Retrieve the match data from the descriptor
+	CCustomMatchData* customMatch = CCustomMatchData::NewLC(aAdditionalParameters.DataType());
+
+	TResolverMatchType matchType = customMatch->MatchType();
+	// get the flags that the plugin must support
+	TPluginFlagsNeeded pluginFlagsNeeded = customMatch->PluginFlagsNeeded();
+
+	TUid baseType = customMatch->BaseType();
+	TUid subType = customMatch->SubType();
+	TUid implementationUid = customMatch->ImplementationType();
+	HBufC8* matchString = customMatch->MatchString().AllocLC();
+	HBufC* fileSuffix = customMatch->FileSuffix().AllocLC();
+
+	// Use the member var to create the array so that we get proper cleanup behaviour
+	RImplInfoArray& fullList = iRegistry.ListImplementationsL(aInterfaceUid);
+
+	RArray<TSortImplInfo> sortList;
+	CleanupClosePushL(sortList);
+
+	TInt matchLevel = 0;
+
+	// Loop through the implementations matching on appropriate info
+	const TInt count = fullList.Count();
+	TInt index;
+
+	for(index = 0; index < count; index++)
+		{
+		const CImplementationInformation& impData = *(fullList[index]);
+		COpaqueDataParse* parse = NULL;
+		TRAPD(error, parse = COpaqueDataParse::NewL(impData.OpaqueData()));
+		if (error!=KErrNone)
+			{
+			if (error==KErrNotSupported)
+				{
+				// means that the resource entry was not valid
+				continue;
+				}
+			else
+				User::Leave(error);
+			}
+
+		CleanupStack::PushL(parse);
+
+		// we can assume the version is valid as it is checked in 
+		// COpaqueDataParse::ConstructL() which leaves if not valid
+		ASSERT(parse->Version() <= KIclPluginFrameworkVersionMax);
+		
+		// get the plugin's flags
+		TBool flagsSupported = ETrue;
+		if ((pluginFlagsNeeded & ESetSourceRectSupportNeeded) &&
+			!parse->IsSetSourceRectSupported())
+			{
+			flagsSupported = EFalse;
+			}
+
+		if (!impData.Disabled() && flagsSupported)
+			{
+			TBool matchFound = EFalse;
+			switch(matchType)
+				{
+				case EMatchMIMEType:
+					{
+					if(!parse->OnlyUidsAvail())
+						{ //If codec has no MIME types ignore it
+						parse->EnsureMIMETypesReadL();
+						const TInt numMimeTypes = parse->MIMETypesCount();
+						for (TInt index2 = 0; index2 < numMimeTypes; index2++)
+							{
+							const TDesC8& mimeType = parse->MIMEType(index2);
+							if (COpaqueDataParse::CompareMIMETypes(*matchString, mimeType))
+								{
+								matchFound = ETrue;
+								matchLevel = index2;
+								break;
+								}
+							}
+						}
+
+					break;
+					}
+
+				case EMatchString:
+					{ // Match the match strings
+					if (CImageDisplayResolverUtils::Match(*matchString, impData.DataType(), matchLevel))
+						matchFound = ETrue;
+					break;
+					}
+
+				case EMatchUids:
+					{ // match on UIDs
+					if (implementationUid != KNullUid)
+						{// We're matching on codec implementation uid
+						if (implementationUid == impData.ImplementationUid())
+							matchFound = ETrue;
+						}
+					else
+						{ // We're matching on image type (and sub-type)
+						if (parse->CompareUids(baseType, subType))
+							matchFound = ETrue;
+						}
+					break;
+					}
+
+				case EMatchFileSuffix:
+					{
+					if(!parse->OnlyUidsAvail() && parse->IsOpenAgainstSuffix())
+						{ //If codec has file extensions and allow matching on them
+						parse->EnsureExtnsReadL();
+						const TInt numExtns = parse->ExtnsCount();
+						for (TInt index2 = 0; index2 < numExtns; index2++)
+							{
+							const TDesC8& extn = parse->Extn(index2);
+							if (COpaqueDataParse::CompareFileSuffixL(*fileSuffix, extn))
+								{
+								matchFound = ETrue;
+								matchLevel = index2;
+								break;
+								}
+							}
+						}
+
+					break;
+					}
+
+				default:
+					{//unknown match type
+					Panic(KErrArgument);
+					}
+				}
+			if (matchFound)
+				{
+				TSortImplInfo sortInfo(fullList[index],matchLevel);
+				User::LeaveIfError(sortList.Append(sortInfo));
+				}
+			}
+		CleanupStack::PopAndDestroy(parse);
+		}
+
+	TLinearOrder<TSortImplInfo>* sortFunction = NULL;
+	if(matchType==EMatchMIMEType)
+		sortFunction = new (ELeave) TLinearOrder<TSortImplInfo>(SortAsending);
+	else
+		sortFunction = new (ELeave) TLinearOrder<TSortImplInfo>(SortDesending);
+
+	sortList.Sort(*sortFunction);
+	delete sortFunction;
+
+	RImplInfoArray* retList = new (ELeave) RImplInfoArray;
+	CleanupStack::PushL(retList);
+	// coverity[double_push]
+	CleanupClosePushL(*retList); // note the double PushL - will Close and delete on PopAndDestroy(2)
+
+	TInt noEntries = sortList.Count();
+	for(index = 0; index < noEntries; index++)
+		User::LeaveIfError(retList->Append(sortList[index].iImplInfo));
+
+	CleanupStack::Pop(2, retList); // retList x2
+
+	CleanupStack::PopAndDestroy(4, customMatch); //sortList, fileSuffix, matchString, customMatch
+
+	return retList;
+	}
+
+/**
+ * Function to sort an array of TSortImplInfo in asending order of the match level and
+ * then in desending order of version numbers.
+ *
+ * @param	"const TSortImplInfo& aImpInfo1"
+ *			First element.
+ * @param	"const TSortImplInfo& aImpInfo2"
+ *			Second element.
+ * @return	"TInt"
+ *			Indication of element swapping order.
+ */
+TInt CImageDisplayResolver::SortAsending(const TSortImplInfo& aImpInfo1, const TSortImplInfo& aImpInfo2)
+	{
+	TInt result = aImpInfo1.iMatchLevel - aImpInfo2.iMatchLevel;
+
+	if(result == 0)
+		result = aImpInfo2.iImplInfo->Version() - aImpInfo1.iImplInfo->Version();
+
+	return result;
+	}
+
+/**
+ * Function to sort an array of TSortImplInfo in desending order of the match level 
+ * and version numbers.
+ *
+ * @param	"const TSortImplInfo& aImpInfo1"
+ *			First element.
+ * @param	"const TSortImplInfo& aImpInfo2"
+ *			Second element.
+ * @return	"TInt"
+ *			Indication of element swapping order.
+ */
+TInt CImageDisplayResolver::SortDesending(const TSortImplInfo& aImpInfo1, const TSortImplInfo& aImpInfo2)
+	{
+	TInt result = aImpInfo2.iMatchLevel - aImpInfo1.iMatchLevel;
+
+	if(result == 0)
+		result = aImpInfo2.iImplInfo->Version() - aImpInfo1.iImplInfo->Version();
+
+	return result;
+	}
+
+/**
+ * Construtor for the TSortImplInfo class
+ *
+ * @param	"CImplementationInformation *const aImplInfo"
+ *			A implementation information element to be soreted.
+ * @param	"TInt aMatchLevel"
+ *			The matching level of the entry
+ */
+TSortImplInfo::TSortImplInfo(CImplementationInformation *const aImplInfo, TInt aMatchLevel):
+	iImplInfo(aImplInfo),
+	iMatchLevel(aMatchLevel)
+	{
+	}
+