diff -r 000000000000 -r bde4ae8d615e os/mm/mmlibs/mmfw/src/ControllerFramework/mmfcontrollerpluginresolver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/mm/mmlibs/mmfw/src/ControllerFramework/mmfcontrollerpluginresolver.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,1805 @@ +// Copyright (c) 2002-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: +// + +#include +#include +#include +#include +#include +#include +#include "mmfmatchdata.h" +#include +#include "MMFFormatImplementationInformationBody.h" +#include + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#endif + +_LIT8(KSupplier, ""); +_LIT8(KMediaId, ""); +_LIT8(KUriScheme,""); +_LIT8(KNonNetwork,""); +_LIT8(KPlayFormatCollectionUid, "

"); +_LIT8(KRecordFormatCollectionUid, ""); +_LIT8(KFormatFileExtension, ""); +_LIT8(KFormatMimeType, ""); +_LIT8(KFormatHeaderData, ""); +_LIT8(KHeapSize, ""); +_LIT8(KCustomInterfaceSupport, ""); +_LIT8(KSecureDRMProcessMode, ""); +_LIT8(KStackSize, ""); +_LIT8(KTagMatch, "**"); +_LIT8(KTagYes,"yes"); + +const TInt KTagLength = 3; + +const TInt KMaxExtLen = 5 ; +const TInt KDesCArrayGranularity = 1; + +const TInt KUriPriorityHigh = 3; +const TInt KUriPriorityMedium = 2; +const TInt KUriPriorityLow = 1; +const TInt KUriPriorityNone = 0; + +static const TUid KUidInterfaceFormatDecode = {KMmfUidPluginInterfaceFormatDecode}; +static const TUid KUidInterfaceFormatEncode = {KMmfUidPluginInterfaceFormatEncode}; +static const TUid KUidInterfaceMMFController = {KMmfUidPluginInterfaceController}; + + +EXPORT_C CMMFFormatSelectionParameters* CMMFFormatSelectionParameters::NewL() + { + CMMFFormatSelectionParameters* s = CMMFFormatSelectionParameters::NewLC(); + CleanupStack::Pop(s); + return s; + } + +EXPORT_C CMMFFormatSelectionParameters* CMMFFormatSelectionParameters::NewLC() + { + CMMFFormatSelectionParameters* s = new(ELeave) CMMFFormatSelectionParameters; + CleanupStack::PushL(s); + return s; + } + +CMMFFormatSelectionParameters* CMMFFormatSelectionParameters::NewL(const CMMFFormatSelectionParameters& aParams) + { + CMMFFormatSelectionParameters* s = CMMFFormatSelectionParameters::NewLC(); + s->ConstructL(aParams); + CleanupStack::Pop(s); + return s; + } + +void CMMFFormatSelectionParameters::ConstructL(const CMMFFormatSelectionParameters& aParams) + { + iMatchReqData = CMatchData::CreateL(); + iMatchReqData->SetMatchDataL(aParams.MatchData()); + iMatchReqData->SetMatchUriSchemeL(aParams.MatchUriScheme()); + iMatchDataType = aParams.MatchDataType(); + } + +CMMFFormatSelectionParameters::~CMMFFormatSelectionParameters() + { + delete iMatchReqData; + iMatchReqData= NULL; + } + +CMMFFormatSelectionParameters::CMMFFormatSelectionParameters() + { + iMatchDataType = EMatchAny; + } + +EXPORT_C void CMMFFormatSelectionParameters::SetMatchToFileNameL(const TDesC& aFileName) + { + delete iMatchReqData; + iMatchReqData = NULL; + iMatchDataType = EMatchAny; + // Extract the extension from the data passed in + + // Parse the path and extract the extension + _LIT( KDot, "." ) ; + _LIT8( KDot8, "." ); + + // If there is no dot "." in aFileName then assume that we have been passed the extension only (if KMaxExtLen or less) + if ( (aFileName.Length() <= KMaxExtLen) && (aFileName.Find( KDot ) == KErrNotFound) ) + { + RBuf8 temp; + CleanupClosePushL(temp); + temp.CreateL(aFileName.Length()+1); + User::LeaveIfError(CnvUtfConverter::ConvertFromUnicodeToUtf8(temp, aFileName)); + temp.Insert(0,KDot8); + + iMatchReqData = CMatchData::CreateL(); + iMatchReqData->SetMatchDataL(temp); + + CleanupStack::PopAndDestroy(&temp); + + } + else if ( aFileName.Find( KDot ) == 0 ) // the first character is dot so assume extension only + { + RBuf8 temp; + CleanupClosePushL(temp); + temp.CreateL(aFileName.Length()); + User::LeaveIfError(CnvUtfConverter::ConvertFromUnicodeToUtf8(temp, aFileName)); + + iMatchReqData = CMatchData::CreateL(); + iMatchReqData->SetMatchDataL(temp); + + CleanupStack::PopAndDestroy(&temp); + + } + else // We have been given the whole filename. Use TParse to extract the extension. + { + TParse parser ; + parser.Set( aFileName, NULL, NULL ) ; + if ( !( parser.NamePresent() ) ) + User::Leave( KErrBadName ) ; + if ( !( parser.PathPresent() ) ) + { + RFs fsSession ; + User::LeaveIfError(fsSession.Connect()); + TInt error = fsSession.Parse(aFileName, parser); + fsSession.Close(); + User::LeaveIfError(error); + } + // Parser should now have the full filename and path + TPtrC extension = parser.Ext(); + + RBuf8 temp; + CleanupClosePushL(temp); + temp.CreateL(extension.Length()); + User::LeaveIfError(CnvUtfConverter::ConvertFromUnicodeToUtf8(temp, extension)); + + iMatchReqData = CMatchData::CreateL(); + iMatchReqData->SetMatchDataL(temp); + + CleanupStack::PopAndDestroy(&temp); + + } + + // If we're here, we must now have the file extension + iMatchDataType = EMatchFileExtension; + } + +EXPORT_C void CMMFFormatSelectionParameters::SetMatchToUriL(const TDesC& aUrl) + { + delete iMatchReqData; + iMatchReqData = NULL; + iMatchDataType = EMatchAny; + + CUri8* uri = UriUtils::CreateUriL(aUrl); //Converts the TDesC16 aUrl to TDesC8 type + CleanupStack::PushL(uri); + const TDesC8& path = uri->Uri().Extract(EUriPath); + + // Now parse the file name + TInt pos = path.LocateReverse('.'); + + if(pos != KErrNotFound) // if not found, then by default match data is NULL + { + TPtrC8 extension(path.Right(path.Length()-pos)); + iMatchReqData = CMatchData::CreateL(); + iMatchReqData->SetMatchDataL(extension); + } + CleanupStack::PopAndDestroy(uri); + + // If we're here, we must now have the file extension + // Use match file extension, because we are matching to the file extension of the file specified by the URI + iMatchDataType = EMatchFileExtension; + } + +/** + @publishedPartner + @prototype + + Sets this object to match to uri scheme and file extension specified by a URI. + + The Uri scheme and extension are saved in iMatchReqData. Further,iMatchData contains uri extension, + iMatchUriScheme contains uri scheme. + + @param aUri + The URI containing the scheme and uri extension to be matched. + +*/ +EXPORT_C void CMMFFormatSelectionParameters::SetMatchToUriSupportL(const TDesC& aUrl) + { + delete iMatchReqData; + iMatchReqData = NULL; + iMatchDataType = EMatchAny; + + CUri8* uri = UriUtils::CreateUriL(aUrl); //Converts the TDesC16 aUrl to TDesC8 type + CleanupStack::PushL(uri); + + const TDesC8& scheme = uri->Uri().Extract(EUriScheme); //get the uri scheme + iMatchReqData = CMatchData::CreateL(); + iMatchReqData->SetMatchUriSchemeL(scheme); + + const TDesC8& path = uri->Uri().Extract(EUriPath); + // Now parse the file name + TInt pos = path.LocateReverse('.'); + + if(pos != KErrNotFound) // if not found, by default match data is NULL + { + TPtrC8 extension(path.Right(path.Length()-pos)); + iMatchReqData->SetMatchDataL(extension); + } + + CleanupStack::PopAndDestroy(uri); + // If we're here, we must now have the uri saved in iMatchData. Now, set match type + // to EMatchUri for checking schema and uri extension + iMatchDataType = EMatchUri; + } + + + +EXPORT_C void CMMFFormatSelectionParameters::SetMatchToMimeTypeL(const TDesC8& aMimeType) + { + delete iMatchReqData; + iMatchReqData = NULL; + iMatchDataType = EMatchAny; + + iMatchReqData = CMatchData::CreateL(); + iMatchReqData->SetMatchDataL(aMimeType); + iMatchDataType = EMatchMimeType; + } + +EXPORT_C void CMMFFormatSelectionParameters::SetMatchToHeaderDataL(const TDesC8& aHeaderData) + { + delete iMatchReqData; + iMatchReqData = NULL; + iMatchDataType = EMatchAny; + + iMatchReqData = CMatchData::CreateL(); + iMatchReqData->SetMatchDataL(aHeaderData); + iMatchDataType = EMatchHeaderData; + } + +EXPORT_C const TDesC8& CMMFFormatSelectionParameters::MatchData() const + { + if (iMatchReqData) + { + return iMatchReqData->MatchData(); + } + else + { + return KNullDesC8; + } + } + +/** + @publishedPartner + @prototype + + Returns the uri scheme used to perform the plugin match. + + @return The uri scheme. + +*/ +EXPORT_C const TDesC8& CMMFFormatSelectionParameters::MatchUriScheme() const + { + if (iMatchReqData) + { + return iMatchReqData->MatchUriScheme(); + } + else + { + return KNullDesC8; + } + } + +EXPORT_C CMMFFormatSelectionParameters::TMatchDataType CMMFFormatSelectionParameters::MatchDataType() const + { + return iMatchDataType; + } + +CMMFPluginSelectionParameters::CMMFPluginSelectionParameters(TUid aPluginInterfaceUid) : + iPluginInterfaceUid(aPluginInterfaceUid) + { + iPreferredSupplierMatchType = ENoPreferredSupplierMatch; + iMediaIdMatchType = ENoMediaIdMatch; + } + +CMMFPluginSelectionParameters::~CMMFPluginSelectionParameters() + { + delete iPreferredSupplier; + iMediaIds.Reset(); + iMediaIds.Close(); + } + +EXPORT_C void CMMFPluginSelectionParameters::SetPreferredSupplierL(const TDesC& aPreferredSupplier, TPreferredSupplierMatchType aMatchType) + { + delete iPreferredSupplier; + iPreferredSupplier = NULL; + iPreferredSupplier = aPreferredSupplier.AllocL(); + iPreferredSupplierMatchType = aMatchType; + } + +EXPORT_C void CMMFPluginSelectionParameters::SetMediaIdsL(const RArray& aMediaIds, TMediaIdMatchType aMatchType) + { + iMediaIds.Reset(); + for (TInt i=0; i& CMMFPluginSelectionParameters::MediaIds() const + { + return iMediaIds; + } + +EXPORT_C CMMFPluginSelectionParameters::TMediaIdMatchType CMMFPluginSelectionParameters::MediaIdMatchType() const + { + return iMediaIdMatchType; + } + +EXPORT_C TUid CMMFPluginSelectionParameters::InterfaceUid() const + { + return iPluginInterfaceUid; + } + + +TBool CMMFPluginSelectionParameters::CheckMediaIdSupportL(const CMMFPluginImplementationInformation& aPlugin) const + { + TBool ret = EFalse; + switch (MediaIdMatchType()) + { + case CMMFPluginSelectionParameters::ENoMediaIdMatch: + // No match required so suitable + ret = ETrue; + break; + case CMMFPluginSelectionParameters::EAllowOtherMediaIds: + // Just check that the requested media id is supported by the plugin + { + for (TInt i=0; iGetPlayFormatsL(); + } + if (iRequiredRecordFormatSupport) + { + c->GetRecordFormatsL(); + } + + // Find out whether this controller matches the client's requirements... + TBool suitable = EFalse; + TInt arrayPos; + suitable = CheckUriSupport(iRequiredPlayFormatSupport, c, c->PlayFormats()); + if(suitable) + { + suitable = CheckUriSupport(iRequiredRecordFormatSupport, c, c->RecordFormats()); + } + if(suitable) + { + MatchImplementationToSelectParamsL(aImplementations, *c, arrayPos); + } + else + { + arrayPos = -1; + } + + if (arrayPos >=0) + { + // This plugin is suitable - insert it into the array at the suggested position + User::LeaveIfError(aImplementations.Insert(c, arrayPos)); + CleanupStack::Pop(c); + } + else + { + // This plugin isn't suitable so just destroy it + CleanupStack::PopAndDestroy(c); + } + } + else if (error != KErrCorrupt) + { + // Ignore the plugin if it is corrupt. Otherwise, leave. + // if error !=KErrNone, c hasn't been constructed so it is safe to leave + User::Leave(error); + } + } + + CleanupStack::PopAndDestroy();//ecomArray + } + +void CMMFControllerPluginSelectionParameters::MatchImplementationToSelectParamsL(RMMFControllerImplInfoArray& aImplementations, const CMMFControllerImplementationInformation& aPlugin, TInt& aArrayPos) const + { + TBool suitable = EFalse; + + // First, check whether the plugin supports the required play formats + suitable = CheckFormatSupportL(iRequiredPlayFormatSupport, aPlugin.PlayFormats()); + + // Next, check the record formats + if (suitable) + suitable = CheckFormatSupportL(iRequiredRecordFormatSupport, aPlugin.RecordFormats()); + + // Next, check for correct media id support + if (suitable) + suitable = CheckMediaIdSupportL(aPlugin); + + // Finally, calculate the position the plugin should take in aImplementations depending on the preferred supplier and version number. + if (suitable) + aArrayPos = CheckPreferredSupplierL(aImplementations, aPlugin); + else + aArrayPos = -1; + } + +/** + Checks the given Controller for uri support. Uri support may be there + if either requiredscheme or extension matches with that given controller + + @param aSelectParams + Describes the selection parameter which a controller needs to + support in order to be selected + + @param aPlugin + The controller plugin which is checked for uri support + + @param aFormats + The play or record formats looked for extension match +*/ +TBool CMMFControllerPluginSelectionParameters::CheckUriSupport(CMMFFormatSelectionParameters* aSelectParams, CMMFControllerImplementationInformation* aPlugin, const RMMFFormatImplInfoArray& aFormats) const + { + // If aSelectParams are NULL (ie none were set) then the plugin must be suitable! + if (aSelectParams == NULL) + return ETrue; + + //If EMatchUri not set then the plugin might be suitable! + if(aSelectParams->MatchDataType() != CMMFFormatSelectionParameters::EMatchUri) + { + return ETrue; + } + + TBool suitable = EFalse; + TInt index; + + //If yes is there in the aPlugin's opaque data, + //URI support not assumed. So, don't load the controller + if(!aPlugin->SupportsNetworkCapability()) + { + return EFalse; + } + + //the uri scheme to be matched for + if (aPlugin->SupportsUriScheme(aSelectParams->MatchUriScheme())) + { + aPlugin->SetUriPriority(KUriPriorityMedium); + suitable = ETrue; + } + else + { + //if other uri scheme support declared, but not the required one, + // even then controller not supported + if(aPlugin->SupportedUriSchemes().Count() > 0) + { + return EFalse; + } + } + + + //then match Uri extension. . + + //if ctrl has no network capability, then lowest priority given on matching file extension + for (index=0;index SupportsFileExtension(aSelectParams->MatchData())) + { + if(!suitable) + { + aPlugin->SetUriPriority(KUriPriorityLow); + } + else + { + aPlugin->SetUriPriority(KUriPriorityHigh); + } + + suitable = ETrue; + break; + } + } + + return suitable; + } + +TInt CMMFControllerPluginSelectionParameters::CheckPreferredSupplierL(RMMFControllerImplInfoArray& aImplementations, const CMMFControllerImplementationInformation& aPlugin) const + { + // Set the return value to indicated the plugin is not suitable. + TBool pluginSuitable = EFalse; + TBool needToPlaceInVersionOrder = EFalse; + TBool needToPlaceInUriPriorityOrder = EFalse; + + if((iRequiredPlayFormatSupport && (iRequiredPlayFormatSupport->MatchDataType() == CMMFFormatSelectionParameters::EMatchUri)) + || (iRequiredRecordFormatSupport && (iRequiredRecordFormatSupport->MatchDataType() == CMMFFormatSelectionParameters::EMatchUri))) + { + needToPlaceInUriPriorityOrder = ETrue; + } + + switch (PreferredSupplierMatchType()) + { + case ENoPreferredSupplierMatch: + // No match, so suitable. + pluginSuitable = ETrue; + break; + case EPreferredSupplierPluginsFirstInList: + pluginSuitable = ETrue; + if (aPlugin.SupportsSupplier(PreferredSupplier())) + needToPlaceInVersionOrder = ETrue; + break; + case EOnlyPreferredSupplierPluginsReturned: + if (aPlugin.SupportsSupplier(PreferredSupplier())) + { + pluginSuitable = ETrue; + needToPlaceInVersionOrder = ETrue; + } + break; + default: + User::Leave(KErrNotSupported); + } + + TInt arrayPos; + + if (!pluginSuitable) + { + arrayPos = -1; + } + + else + { + if(needToPlaceInUriPriorityOrder) + { + arrayPos = aImplementations.Count(); + // Cycle through aImplementations to find the first plugin with a uri priority LOWER than aPlugin's + for (TInt i=0; iUriPriority() < aPlugin.UriPriority()) + { + arrayPos = i;//plugin will be inserted before c in the array + break; + } + } + else + { + if(!needToPlaceInVersionOrder) //case 2 + { + /** + This reflects the case EPreferredSupplierPluginsFirstInList and + aPlugin supplier not matching. + Place the plugin based on its Uri Priority after the required suppliers plugin. + If priority is equal, new plugin will be placed last. + */ + if( (c->Supplier() != PreferredSupplier()) && (c->UriPriority() < aPlugin.UriPriority())) + { + arrayPos = i;//plugin will be inserted before c in the array + break; + } + } + else //case 3 + { + /** + This reflects the case where + Supplier matches and EPreferredSupplierPluginsFirstInList is specified. + OR + Supplier matches and EOnlyPreferredSupplierPluginsReturned is specified. + */ + if(c->Supplier() == PreferredSupplier()) + { + if(c->UriPriority() == aPlugin.UriPriority()) + { + if(c->Version() <= aPlugin.Version()) + { + arrayPos = i;//plugin will be inserted before c in the array + break; + } + } + else + { + if(c->UriPriority() < aPlugin.UriPriority()) + { + arrayPos = i;//plugin will be inserted before c in the array + break; + } + } + } + else + { + /** + This is a case of aImplementations now having unpreferred suppliers + when EPreferredSupplierPluginsFirstInList is specified and aPlugin is + of preferred supplier but least priority. + */ + arrayPos = i;//plugin will be inserted before c in the array + break; + } + } + } + } + } + + else + { + if (!needToPlaceInVersionOrder) + { + /** + place it at the end. + */ + arrayPos = aImplementations.Count(); + } + else + { + // Insert the plugin at the beginning of the array, in version order if possible. + // Make an assumption: if we've been asked for format support, then only plugins + // that support the same format will be in the array - so ordering them by version + // will be meaningful. Otherwise, there's no point. + if ((iRequiredPlayFormatSupport && (iRequiredPlayFormatSupport->MatchDataType() != CMMFFormatSelectionParameters::EMatchAny)) + || (iRequiredRecordFormatSupport && (iRequiredRecordFormatSupport->MatchDataType() != CMMFFormatSelectionParameters::EMatchAny))) + { + // Put the plugin in version order at the beginning of the list + + // Set aArrayPos to the end of the array in case this plugin has the lowest version number + arrayPos = aImplementations.Count(); + // Cycle through aImplementations to find the first plugin with a version number LOWER than aPlugin + for (TInt i=0; iSupplier() == aPlugin.Supplier()) + { + if (c->Version() <= aPlugin.Version()) + { + arrayPos = i;//plugin will be inserted before c in the array + break; + } + } + else + { + arrayPos = i; //c has wrong supplier so this plugin must go before c + break; + } + } + } + else + { + // We can't use the version numbers meaningfully, so just put this plugin + // at the top of the list. + arrayPos = 0; + } + } + } + } + + return arrayPos; + } + +TBool CMMFControllerPluginSelectionParameters::CheckFormatSupportL(CMMFFormatSelectionParameters* aSelectParams, const RMMFFormatImplInfoArray& aFormats) const + { + // If aSelectParams are NULL (ie none were set) then the plugin must be suitable! + if (aSelectParams == NULL) + return ETrue; + + TBool suitable = EFalse; + + // Check all the formats in aFormats. If any support the required data type, return ETrue. + TInt index; + switch (aSelectParams->MatchDataType()) + { + case CMMFFormatSelectionParameters::EMatchAny: + // All plugins intrinsically match this! + suitable = ETrue; + break; + case CMMFFormatSelectionParameters::EMatchFileExtension: + for (index=0;indexSupportsFileExtension(aSelectParams->MatchData())) + { + suitable = ETrue; + break; + } + } + break; + case CMMFFormatSelectionParameters::EMatchMimeType: + for (index=0;indexSupportsMimeType(aSelectParams->MatchData())) + { + suitable = ETrue; + break; + } + } + break; + case CMMFFormatSelectionParameters::EMatchHeaderData: + for (index=0;indexSupportsHeaderDataL(aSelectParams->MatchData())) + { + suitable = ETrue; + break; + } + } + break; + + case CMMFFormatSelectionParameters::EMatchUri: + { + suitable = ETrue; //if uri match specifically looked , then that has been already matched in a CheckUriSupport() + break; + } + + + default: + User::Leave(KErrNotSupported); + }; + + return suitable; + } + + + +EXPORT_C CMMFControllerSecureDrmPluginSelectionParameters* CMMFControllerSecureDrmPluginSelectionParameters::NewL() + { + CMMFControllerSecureDrmPluginSelectionParameters* s = CMMFControllerSecureDrmPluginSelectionParameters::NewLC(); + CleanupStack::Pop(s); + return s; + } + +EXPORT_C CMMFControllerSecureDrmPluginSelectionParameters* CMMFControllerSecureDrmPluginSelectionParameters::NewLC() + { + CMMFControllerSecureDrmPluginSelectionParameters* s = new(ELeave) CMMFControllerSecureDrmPluginSelectionParameters; + CleanupStack::PushL(s); + return s; + } + +CMMFControllerSecureDrmPluginSelectionParameters::CMMFControllerSecureDrmPluginSelectionParameters() : + CMMFControllerPluginSelectionParameters() + { + } + +EXPORT_C void CMMFControllerSecureDrmPluginSelectionParameters::ListImplementationsL(RMMFControllerImplInfoArray& aImplementations) const + { + CMMFControllerPluginSelectionParameters::ListImplementationsL(aImplementations); + TInt pluginsCount = aImplementations.Count(); + for (TInt i = pluginsCount - 1; i >= 0; i--) + { + CMMFControllerImplementationInformation* c = aImplementations[i]; + if (!c->SupportsSecureDRMProcessMode()) + { + aImplementations.Remove(i); + delete c; + } + } + aImplementations.Compress(); + } + + + +CMMFFormatPluginSelectionParameters::CMMFFormatPluginSelectionParameters(TUid aInterfaceUid) : + CMMFPluginSelectionParameters(aInterfaceUid) + { + } + +CMMFFormatPluginSelectionParameters::~CMMFFormatPluginSelectionParameters() + { + delete iRequiredFormatSupport; + } + +EXPORT_C void CMMFFormatPluginSelectionParameters::SetRequiredFormatSupportL(const CMMFFormatSelectionParameters& aRequiredSupport) + { + delete iRequiredFormatSupport; + iRequiredFormatSupport = NULL; + iRequiredFormatSupport = CMMFFormatSelectionParameters::NewL(aRequiredSupport); + } + +EXPORT_C void CMMFFormatPluginSelectionParameters::ListImplementationsL(RMMFFormatImplInfoArray& aImplementations) const + { + aImplementations.ResetAndDestroy(); + + RImplInfoPtrArray ecomArray; + CleanupResetAndDestroyPushL(ecomArray); + + MmPluginUtils::FindImplementationsL(InterfaceUid(), ecomArray); + + + TInt index; + // Create Format Implementation Information for each entry + for (index=0; index=0) + { + // This plugin is suitable - insert it into the array at the suggested position + User::LeaveIfError(aImplementations.Insert(c, arrayPos)); + CleanupStack::Pop(c); + } + else + { + // This plugin isn't suitable so just destroy it + CleanupStack::PopAndDestroy(c); + } + } + else if (error != KErrCorrupt) + { + // Ignore the plugin if it is corrupt. Otherwise, leave. + // if error !=KErrNone, c hasn't been constructed so it is safe to leave + User::Leave(error); + } + } + + CleanupStack::PopAndDestroy();//ecomArray + } + +void CMMFFormatPluginSelectionParameters::MatchImplementationToSelectParamsL(RMMFFormatImplInfoArray& aImplementations, const CMMFFormatImplementationInformation& aPlugin, TInt& aArrayPos) const + { + TBool suitable = EFalse; + + // First, check whether the plugin supports the required play formats + suitable = CheckFormatSupportL(aPlugin); + + // Next, check for correct media id support + if (suitable) + suitable = CheckMediaIdSupportL(aPlugin); + + // Finally, calculate the position the plugin should take in aImplementations depending on the preferred supplier and version number. + if (suitable) + aArrayPos = CheckPreferredSupplierL(aImplementations, aPlugin); + else + aArrayPos = -1; + } + +TInt CMMFFormatPluginSelectionParameters::CheckPreferredSupplierL(RMMFFormatImplInfoArray& aImplementations, const CMMFFormatImplementationInformation& aPlugin) const + { + // Set the return value to indicated the plugin is not suitable. + TBool pluginSuitable = EFalse; + TBool needToPlaceInVersionOrder = EFalse; + + switch (PreferredSupplierMatchType()) + { + case ENoPreferredSupplierMatch: + // No match, so suitable. + pluginSuitable = ETrue; + break; + case EPreferredSupplierPluginsFirstInList: + pluginSuitable = ETrue; + if (aPlugin.SupportsSupplier(PreferredSupplier())) + needToPlaceInVersionOrder = ETrue; + break; + case EOnlyPreferredSupplierPluginsReturned: + if (aPlugin.SupportsSupplier(PreferredSupplier())) + { + pluginSuitable = ETrue; + needToPlaceInVersionOrder = ETrue; + } + break; + default: + User::Leave(KErrNotSupported); + } + + + TInt arrayPos; + + if (!pluginSuitable) + { + arrayPos = -1; + } + else + { + if (!needToPlaceInVersionOrder) + { + arrayPos = aImplementations.Count(); + } + else + { + // Insert the plugin at the beginning of the array, in version order if possible. + // Make an assumption: if we've been asked for format support, then only plugins + // that support the same format will be in the array - so ordering them by version + // will be meaningful. Otherwise, there's no point. + if (iRequiredFormatSupport && (iRequiredFormatSupport->MatchDataType() != CMMFFormatSelectionParameters::EMatchAny)) + { + // Put the plugin in version order at the beginning of the list + + // Set aArrayPos to the end of the array in case this plugin has the lowest version number + arrayPos = aImplementations.Count(); + // Cycle through aImplementations to find the first plugin with a version number LOWER than aPlugin + for (TInt i=0; iSupplier() == aPlugin.Supplier()) + && (c->Version() <= aPlugin.Version())) + { + arrayPos = i;//plugin will be inserted before c in the array + break; + } + } + } + else + { + // We can't use the version numbers meaningfully, so just put this plugin + // at the top of the list. + arrayPos = 0; + } + } + } + return arrayPos; + } + +TBool CMMFFormatPluginSelectionParameters::CheckFormatSupportL(const CMMFFormatImplementationInformation& aPlugin) const + { + // If iRequiredFormatSupport is NULL (ie no requirements set) then the plugin must be suitable! + if (iRequiredFormatSupport == NULL) + return ETrue; + + TBool suitable = EFalse; + + switch (iRequiredFormatSupport->MatchDataType()) + { + case CMMFFormatSelectionParameters::EMatchAny: + suitable = ETrue; + break; + case CMMFFormatSelectionParameters::EMatchFileExtension: + if (aPlugin.SupportsFileExtension(iRequiredFormatSupport->MatchData())) + suitable = ETrue; + break; + case CMMFFormatSelectionParameters::EMatchMimeType: + if (aPlugin.SupportsMimeType(iRequiredFormatSupport->MatchData())) + suitable = ETrue; + break; + case CMMFFormatSelectionParameters::EMatchHeaderData: + if (aPlugin.SupportsHeaderDataL(iRequiredFormatSupport->MatchData())) + suitable = ETrue; + break; + default: + User::Leave(KErrNotSupported); + }; + + return suitable; + } + + +EXPORT_C CMMFFormatEncodePluginSelectionParameters* CMMFFormatEncodePluginSelectionParameters::NewL() + { + CMMFFormatEncodePluginSelectionParameters* s = CMMFFormatEncodePluginSelectionParameters::NewLC(); + CleanupStack::Pop(s); + return s; + } + +EXPORT_C CMMFFormatEncodePluginSelectionParameters* CMMFFormatEncodePluginSelectionParameters::NewLC() + { + CMMFFormatEncodePluginSelectionParameters* s = new(ELeave) CMMFFormatEncodePluginSelectionParameters; + CleanupStack::PushL(s); + return s; + } + +CMMFFormatEncodePluginSelectionParameters::CMMFFormatEncodePluginSelectionParameters() : + CMMFFormatPluginSelectionParameters(KUidInterfaceFormatEncode) + { + } + + +EXPORT_C CMMFFormatDecodePluginSelectionParameters* CMMFFormatDecodePluginSelectionParameters::NewL() + { + CMMFFormatDecodePluginSelectionParameters* s = CMMFFormatDecodePluginSelectionParameters::NewLC(); + CleanupStack::Pop(s); + return s; + } + +EXPORT_C CMMFFormatDecodePluginSelectionParameters* CMMFFormatDecodePluginSelectionParameters::NewLC() + { + CMMFFormatDecodePluginSelectionParameters* s = new(ELeave) CMMFFormatDecodePluginSelectionParameters; + CleanupStack::PushL(s); + return s; + } + +CMMFFormatDecodePluginSelectionParameters::CMMFFormatDecodePluginSelectionParameters() : + CMMFFormatPluginSelectionParameters(KUidInterfaceFormatDecode) + { + } + + + + + +void TaggedDataParser::ParseTaggedDataL(const TDesC8& aData, MTaggedDataParserClient& aClient) + { + TPtrC8 data(aData); + TInt readPosition = 0; + TBool moreData = data.Length() ? ETrue : EFalse; + while (moreData) + { + // Assumes that this segment will begin with a tag + TPtrC8 restOfData = data.Mid(readPosition); + + TInt endPos = restOfData.MatchF(KTagMatch); + if (endPos == KErrNotFound) + User::Leave(KErrCorrupt); + + // extract the tag + TPtrC8 tag = restOfData.Left(KTagLength); + + + readPosition += KTagLength; + + // Find the next tag + restOfData.Set(data.Mid(readPosition)); + endPos = restOfData.MatchF(KTagMatch); + + TPtrC8 tagData; + if (endPos == KErrNotFound) + { + // If we didn't find a tag, we must be at the end of the data + tagData.Set(restOfData); + readPosition = restOfData.Length(); + moreData = EFalse; + } + else + { + tagData.Set(restOfData.Left(endPos)); + readPosition += endPos; + } + + aClient.ProcessTaggedDataL(tag, tagData); + } + } + +void TaggedDataParser::ConvertTextToUidL(const TDesC8& aData, TUid& aUid) + { + // Make sure aData is in the correct format - "0x12345678" + _LIT8(K0x, "0x"); + _LIT8(K0X, "0X"); + if ((aData.Length() == 10) && ((aData.FindF(K0x) == 0) || (aData.FindF(K0X) == 0))) + { + // only take the right 8 characters (ie discard the "0x") + TLex8 lex(aData.Right(8)); + TUint32 value = 0; + User::LeaveIfError(lex.Val(value, EHex)); + aUid.iUid = value; + } + else + User::Leave(KErrCorrupt); + } + + +void TaggedDataParser::ConvertTextToTUintL(const TDesC8& aData, TUint& aUint) + { + // Determine whether hex or decimal then parse as such + _LIT8(K0x, "0x"); + _LIT8(K0X, "0X"); + if (((aData.FindF(K0x) == 0) || (aData.FindF(K0X) == 0)) && (aData.Length() >= 3)) + { + // only take the characters after "0x" + TLex8 lex(aData.Right(aData.Length()-2)); + TUint32 value = 0; + User::LeaveIfError(lex.Val(value, EHex)); + aUint = value; + } + else if (aData.Length() > 0) + { + TLex8 lex(aData.Right(aData.Length())); + TUint32 value = 0; + User::LeaveIfError(lex.Val(value, EDecimal)); + aUint = value; + } + else + User::Leave(KErrCorrupt); + } + + +EXPORT_C TBool CMMFPluginImplementationInformation::SupportsSupplier(const TDesC& aSupplier) const + { + if (iSupplier) + { + if (aSupplier.CompareF(*iSupplier) == KErrNone) + return ETrue; + } + return EFalse; + } + +EXPORT_C TBool CMMFPluginImplementationInformation::SupportsMediaId(TUid aMediaId) const + { + TInt location = iMediaIds.Find(aMediaId); + return (location != KErrNotFound); + } + +EXPORT_C TUid CMMFPluginImplementationInformation::Uid() const + { + return iUid; + } + +EXPORT_C const TDesC& CMMFPluginImplementationInformation::DisplayName() const + { + if (iDisplayName) + return *iDisplayName; + else + return KNullDesC; + } + +EXPORT_C const TDesC& CMMFPluginImplementationInformation::Supplier() const + { + if (iSupplier) + return *iSupplier; + else + return KNullDesC; + } + +EXPORT_C TInt CMMFPluginImplementationInformation::Version() const + { + return iVersion; + } + +EXPORT_C const RArray& CMMFPluginImplementationInformation::SupportedMediaIds() const + { + return iMediaIds; + } + +CMMFPluginImplementationInformation::~CMMFPluginImplementationInformation() + { + delete iDisplayName; + delete iSupplier; + iMediaIds.Close(); + } + + +CMMFPluginImplementationInformation::CMMFPluginImplementationInformation() + { + } + +void CMMFPluginImplementationInformation::SetSupplierL(const TDesC8& aData) + { + delete iSupplier; + iSupplier = NULL; + // Convert aData to unicode... + iSupplier = HBufC::NewL(aData.Length()); + TPtr ptr = iSupplier->Des(); + User::LeaveIfError(CnvUtfConverter::ConvertToUnicodeFromUtf8(ptr, aData)); + } + +void CMMFPluginImplementationInformation::AddMediaIdL(const TDesC8& aData) + { + TUid mediaId; + TaggedDataParser::ConvertTextToUidL(aData, mediaId); + User::LeaveIfError(iMediaIds.Append(mediaId)); + } + +CMMFControllerImplementationInformation* CMMFControllerImplementationInformation::NewL(const CImplementationInformation& aImplInfo) + { + CMMFControllerImplementationInformation* s = CMMFControllerImplementationInformation::NewLC(aImplInfo); + CleanupStack::Pop(s); + return s; + } + +CMMFControllerImplementationInformation* CMMFControllerImplementationInformation::NewLC(const CImplementationInformation& aImplInfo) + { + CMMFControllerImplementationInformation* s = new(ELeave) CMMFControllerImplementationInformation; + CleanupStack::PushL(s); + s->ConstructL(aImplInfo); + return s; + } + +EXPORT_C CMMFControllerImplementationInformation* CMMFControllerImplementationInformation::NewL(TUid aUid) + { + RImplInfoPtrArray ecomArray; + CleanupResetAndDestroyPushL(ecomArray); + + MmPluginUtils::FindImplementationsL(KUidInterfaceMMFController, ecomArray); + + TInt index; + CMMFControllerImplementationInformation* controller = NULL; + // Create Controller Implementation Information for the entry with the requested UID + for (index=0; indexImplementationUid()==aUid) + { + // Create the impl info object, and get the play and record formats supported by the plugin + controller = CMMFControllerImplementationInformation::NewL(*(ecomArray[index])); + + CleanupStack::PushL(controller); // INC023207 - Placed controller on CleanupStack + controller->GetPlayFormatsL(); + controller->GetRecordFormatsL(); // INC023207 + CleanupStack::Pop(); + } + } + + if (controller == NULL) + { + User::Leave(KErrNotFound); + } + + CleanupStack::PopAndDestroy(); // ecomArray + return controller; + } + +EXPORT_C const RMMFFormatImplInfoArray& CMMFControllerImplementationInformation::PlayFormats() const + { + return iPlayFormats; + } + +EXPORT_C const RMMFFormatImplInfoArray& CMMFControllerImplementationInformation::RecordFormats() const + { + return iRecordFormats; + } + + +EXPORT_C TUint CMMFControllerImplementationInformation::HeapSpaceRequired() const + { + return iHeapSpaceRequired; + } + +EXPORT_C TUint CMMFControllerImplementationInformation::StackSize() const + { + return iStackSize; + } +/** + @publishedPartner + @prototype + + Returns the uri schemes of this plugin. + + @return The array of uri schemes. +*/ +EXPORT_C const CDesC8Array& CMMFControllerImplementationInformation::SupportedUriSchemes() const + { + return *iUriSchemes; + } + +/** + @publishedPartner + @prototype + + Tests whether the plugin supports aUriScheme. + + @param aUriScheme + The required Uri Scheme. + + @return A boolean indicating if the plugin supports aUriScheme. ETrue if this plugin supports aUriScheme, EFalse if not. +*/ +EXPORT_C TBool CMMFControllerImplementationInformation::SupportsUriScheme(const TDesC8& aUriScheme) const + { + TInt position; + TInt error = iUriSchemes->FindIsq(aUriScheme, position, ECmpFolded); + return (error==KErrNone); + } + +/** + @publishedPartner + @prototype + + Sets the uri priority of this controller + + @param aUriPriority + The Uri priority to be assigned. +*/ +EXPORT_C void CMMFControllerImplementationInformation::SetUriPriority(TInt aUriPriority) + { + iUriPriority = aUriPriority; + } + +/** + @publishedPartner + @prototype + + Retrieves the uri priority of this controller + + @return The assigned Uri priority. +*/ +EXPORT_C TInt CMMFControllerImplementationInformation::UriPriority() const + { + return iUriPriority; + } + +/** + @publishedPartner + @prototype + + Tests whether the controller plugin supports url + + @return A boolean indicating if the plugin supports url. ETrue for uri supporting controller, EFalse if not. +*/ +EXPORT_C TBool CMMFControllerImplementationInformation::SupportsNetworkCapability() const + { + return iIsNetworkCtrl; + } + +/** + @publishedPartner + @prototype + + Check whether the controller plugin supports secure DRM process mode + + @return A boolean indicating if the plugin supports secure DRM process mode. +*/ +EXPORT_C TBool CMMFControllerImplementationInformation::SupportsSecureDRMProcessMode() const + { + return iSupportsSecureDRMProcessMode; + } + +CMMFControllerImplementationInformation::CMMFControllerImplementationInformation() + { + iUriPriority = KUriPriorityNone; + iIsNetworkCtrl = ETrue; + iPlayFormatCollectionUid = KNullUid; + iRecordFormatCollectionUid = KNullUid; + iHeapSpaceRequired = KMMFDefaultControllerThreadHeapSize; + iSupportsSecureDRMProcessMode = EFalse; + iStackSize = KDefaultStackSize; + } + +void CMMFControllerImplementationInformation::ConstructL(const CImplementationInformation& aImplInfo) + { + iUriSchemes = new(ELeave) CDesC8ArrayFlat(KDesCArrayGranularity); + iUid = aImplInfo.ImplementationUid(); + iDisplayName = aImplInfo.DisplayName().AllocL(); + iVersion = aImplInfo.Version(); + + // Parse the opaque data... + TaggedDataParser::ParseTaggedDataL(aImplInfo.OpaqueData(), *this); + } + +void CMMFControllerImplementationInformation::ProcessTaggedDataL(const TDesC8& aTag, const TDesC8& aData) + { + if (aTag==KSupplier) + { + SetSupplierL(aData); + } + else if (aTag==KMediaId) + { + AddMediaIdL(aData); + } + else if (aTag==KUriScheme) + { + SetUriSchemeL(aData); + } + else if (aTag==KNonNetwork) + { + SetNetworkCapabilityL(aData); + } + else if (aTag==KPlayFormatCollectionUid) + { + SetPlayFormatCollectionUidL(aData); + } + else if (aTag==KRecordFormatCollectionUid) + { + SetRecordFormatCollectionUidL(aData); + } + else if(aTag==KHeapSize) + { + SetHeapSizeL(aData); + } + else if (aTag==KSecureDRMProcessMode) + { + iSupportsSecureDRMProcessMode = ETrue; + } + else if (aTag==KStackSize) + { + SetStackSizeL(aData); + } + else + { + User::Leave(KErrCorrupt); + } + } + + +CMMFControllerImplementationInformation::~CMMFControllerImplementationInformation() + { + iPlayFormats.ResetAndDestroy(); + iRecordFormats.ResetAndDestroy(); + delete iUriSchemes; + } + + +void CMMFControllerImplementationInformation::SetPlayFormatCollectionUidL(const TDesC8& aData) + { + TaggedDataParser::ConvertTextToUidL(aData, iPlayFormatCollectionUid); + } + +void CMMFControllerImplementationInformation::SetRecordFormatCollectionUidL(const TDesC8& aData) + { + TaggedDataParser::ConvertTextToUidL(aData, iRecordFormatCollectionUid); + } + +void CMMFControllerImplementationInformation::SetHeapSizeL(const TDesC8& aData) + { + TaggedDataParser::ConvertTextToTUintL(aData, iHeapSpaceRequired); + } + +void CMMFControllerImplementationInformation::SetStackSizeL(const TDesC8& aData) + { + TaggedDataParser::ConvertTextToTUintL(aData, iStackSize); + } + + +void CMMFControllerImplementationInformation::AddFormatsSwallowCorruptL(RImplInfoPtrArray& aEcomArray, RMMFFormatImplInfoArray& aFormatArray) + { + for (TInt index=0; index controllerUid; + _LIT8(K0x, "0x"); + controllerUid.Append(K0x); + controllerUid.AppendNumFixedWidth(iUid.iUid, EHex, 8); + + MmPluginUtils::FindImplementationsL(aFormatPluginCollectionUid, ecomArray, controllerUid); + // Create format implementation information for each entry + AddFormatsSwallowCorruptL(ecomArray, aFormatArray); + + CleanupStack::PopAndDestroy();//ecomArray + } + +void CMMFControllerImplementationInformation::GetPlayFormatsL() + { + GetFormatsL(iPlayFormatCollectionUid, KUidInterfaceFormatDecode, iPlayFormats); + } + +void CMMFControllerImplementationInformation::GetRecordFormatsL() + { + GetFormatsL(iRecordFormatCollectionUid, KUidInterfaceFormatEncode, iRecordFormats); + } + +/** + Sets the Uri Scheme found in opaque data + + @param aUriScheme + Gives the uri scheme supported by the controller +*/ +void CMMFControllerImplementationInformation::SetUriSchemeL(const TDesC8& aUriScheme) + { + //If No uri support already declared in the resource file, + //then mentioning a particular schema support is illegal + if(!iIsNetworkCtrl) + { + User::Leave(KErrArgument); + } + + // Insert the new uri scheme into the array + iUriSchemes->InsertIsqL(aUriScheme, ECmpFolded);//ensures there are no repeated entries + } + +/** + Sets the Network capability found in opaque data + + @param aNetworkCapable + Declares the incapability to support uri if matches to 'yes'. + If this is the case, iIsNetworkCtrl is set to EFalse +*/ +void CMMFControllerImplementationInformation::SetNetworkCapabilityL(const TDesC8& aNetworkCapable) + { + //If a uri scheme is already declared in the resource file, + //then mentioning no url support is illegal + if(iUriSchemes->Count() > 0) + { + User::Leave(KErrArgument); + } + + if (aNetworkCapable.CompareF(KTagYes) == KErrNone) + { + iIsNetworkCtrl = EFalse; + } + else + { + User::Leave(KErrBadName); // will leave if aNetworkCapable is anything other than 'yes'. + } + } + + + + +CMMFFormatImplementationInformation* CMMFFormatImplementationInformation::NewL(const CImplementationInformation& aImplInfo) + { + CMMFFormatImplementationInformation* s = CMMFFormatImplementationInformation::NewLC(aImplInfo); + CleanupStack::Pop(s); + return s; + } + +CMMFFormatImplementationInformation* CMMFFormatImplementationInformation::NewLC(const CImplementationInformation& aImplInfo) + { + CMMFFormatImplementationInformation* s = new(ELeave) CMMFFormatImplementationInformation(); + CleanupStack::PushL(s); + s->ConstructL(aImplInfo); + return s; + } + +CMMFFormatImplementationInformation::CMMFFormatImplementationInformation() + { + } + +void CMMFFormatImplementationInformation::ConstructL(const CImplementationInformation& aImplInfo) + { + iUid = aImplInfo.ImplementationUid(); + iDisplayName = aImplInfo.DisplayName().AllocL(); + + iBody = CMMFFormatImplementationInformation::CBody::NewL(); + + // Extract the rest of the data from the opaque data field of aImplInfo... + // Parse the opaque data... + TaggedDataParser::ParseTaggedDataL(aImplInfo.OpaqueData(), *this); + } + +void CMMFFormatImplementationInformation::ProcessTaggedDataL(const TDesC8& aTag, const TDesC8& aTagData) + { + if (aTag == KSupplier) + SetSupplierL(aTagData); + else if (aTag == KMediaId) + AddMediaIdL(aTagData); + else if (aTag == KFormatFileExtension) + AddFileExtensionL(aTagData); + else if (aTag == KFormatMimeType) + AddMimeTypeL(aTagData); + else if (aTag == KFormatHeaderData) + AddHeaderDataL(aTagData); + else if ((aTag == KCustomInterfaceSupport) && (aTagData.CompareF(KTagYes) == 0)) + iBody->SetSupportsCustomInterfaces(ETrue); + else + User::Leave(KErrCorrupt); + } + +void CMMFFormatImplementationInformation::AddFileExtensionL(const TDesC8& aData) + { + iBody->AddFileExtensionL(aData); + } + +void CMMFFormatImplementationInformation::AddMimeTypeL(const TDesC8& aData) + { + iBody->AddMimeTypeL(aData); + } + +void CMMFFormatImplementationInformation::AddHeaderDataL(const TDesC8& aData) + { + iBody->AddHeaderDataL(aData); + } + +CMMFFormatImplementationInformation::~CMMFFormatImplementationInformation() + { + delete iBody; + } + +EXPORT_C const CDesC8Array& CMMFFormatImplementationInformation::SupportedFileExtensions() const + { + return iBody->SupportedFileExtensions(); + } + +EXPORT_C const CDesC8Array& CMMFFormatImplementationInformation::SupportedMimeTypes() const + { + return iBody->SupportedMimeTypes(); + } + +EXPORT_C const CDesC8Array& CMMFFormatImplementationInformation::SupportedHeaderData() const + { + return iBody->SupportedHeaderData(); + } + + +EXPORT_C TBool CMMFFormatImplementationInformation::SupportsFileExtension(const TDesC8& aFileExtension) const + { + return iBody->SupportsFileExtension(aFileExtension); + } + +EXPORT_C TBool CMMFFormatImplementationInformation::SupportsMimeType(const TDesC8& aMimeType) const + { + return iBody->SupportsMimeType(aMimeType); + } + +EXPORT_C TBool CMMFFormatImplementationInformation::SupportsHeaderDataL(const TDesC8& aHeaderData) const + { + return iBody->SupportsHeaderDataL(aHeaderData); + } + +EXPORT_C TBool CMMFFormatImplementationInformation::SupportsCustomInterfaces() const + { + return iBody->SupportsCustomInterfaces(); + } + +CMatchData* CMatchData::CreateL() + { + return new (ELeave) CMatchData(); + } + +void CMatchData::SetMatchDataL(const TDesC8& aMatchData) + { + delete iMatchData; + iMatchData = NULL; + + iMatchData = aMatchData.AllocL(); + } + +void CMatchData::SetMatchUriSchemeL(const TDesC8& aMatchUriScheme) + { + delete iMatchUriScheme; + iMatchUriScheme = NULL; + + iMatchUriScheme = aMatchUriScheme.AllocL(); + } + +const TDesC8& CMatchData::MatchData() const + { + if (iMatchData ) + { + return *iMatchData; + } + else + { + return KNullDesC8; + } + } + +const TDesC8& CMatchData::MatchUriScheme() const + { + if (iMatchUriScheme ) + { + return *iMatchUriScheme; + } + else + { + return KNullDesC8; + } + } + +CMatchData::~CMatchData() + { + delete iMatchData; + delete iMatchUriScheme; + } +