diff -r 735348f59235 -r 948c7f65f6d4 imagingandcamerafws/imagingfws/ImageDisplay/src/Resolver/ImageDisplayResolver.cpp --- /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 +#include +#include + +#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 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* sortFunction = NULL; + if(matchType==EMatchMIMEType) + sortFunction = new (ELeave) TLinearOrder(SortAsending); + else + sortFunction = new (ELeave) TLinearOrder(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) + { + } +