--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xml/xmlfw/src/xmlframework/matchdata.cpp Thu Dec 17 09:29:21 2009 +0200
@@ -0,0 +1,884 @@
+// Copyright (c) 2005-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:
+// Implementation of CMatchData class
+//
+//
+
+/**
+ @file
+ @publishedAll
+ @released
+*/
+
+#include <xml/matchdata.h>
+#include <xml/xmlframeworkerrors.h>
+
+using namespace Xml;
+
+/**
+The maximum length of variant field
+
+@internalComponent
+*/
+const TInt KXmlMaxVariantLength = 32;
+
+/**
+The maximum length of mime type field
+
+@internalComponent
+*/
+const TInt KXmlMaxMimeTypeLength = 255;
+
+/**
+Fields separator for data and opaque data in resource information file
+
+@internalComponent
+*/
+_LIT8(KXmlDataSeparator, "||");
+
+/**
+Set flag macro to simplify bitmap management
+
+@internalComponent
+*/
+#define SYMBIAN_XML_FLAG_SET(bitmap, flag, setting) \
+ bitmap = setting?(bitmap|flag):(bitmap&(~flag))
+
+/**
+Rom only flag
+To request for rom based parsers only
+Default value is FALSE
+
+@internalComponent
+*/
+const TInt32 KXmlRomOnlyFlag = 0x00000001;
+
+/**
+Case Sensitivity flag
+To specify how case sensitivity should be applied, while performing strings matching
+Default value is TRUE
+
+@internalComponent
+*/
+const TInt32 KXmlCaseSensitivityFlag = 0x00000002;
+
+/**
+Leave on many flag
+To leave when the query is narrowed down to more than one parser.
+If not set, the XML framework will choose a parser.
+Default value is FALSE
+
+@internalComponent
+*/
+const TInt32 KXmlLeaveOnManyFlag = 0x00000004;
+
+/**
+Reserved, unused flags in iAddInfo attribute
+
+@internalComponent
+*/
+const TInt32 KXmlAddInfoReservedFlags = 0xFFFFFFF8;
+
+/**
+Object constructor. Initializes internal state to default values
+
+@internalComponent
+*/
+CMatchData::CMatchData():
+ iMimeType(NULL),
+ iVariant(NULL),
+ iAddInfo(KXmlCaseSensitivityFlag)
+ {
+
+ }
+
+/**
+Object destructor. Deletes allocated heap based memory.
+
+@internalComponent
+*/
+CMatchData::~CMatchData()
+ {
+ if (iMimeType != NULL)
+ {
+ delete iMimeType;
+ iMimeType = NULL;
+ }
+
+ if (iVariant != NULL)
+ {
+ delete iVariant;
+ iVariant = NULL;
+ }
+ }
+
+/**
+Creates CMatchData object with its default values.
+
+@leave KErrNoMemory If there is not enough memory to create an object.
+
+@return A pointer to the newly created CMatchData object.
+
+*/
+EXPORT_C CMatchData* CMatchData::NewL()
+ {
+ CMatchData* me = CMatchData::NewLC();
+ CleanupStack::Pop(me);
+ return me;
+ }
+
+/**
+Creates CMatchData object using heap based stream of externalized object's data.
+
+@param aPackage Descriptor to the heap based stream of externalized object
+
+@leave KErrNoMemory If there is not enough memory to create an object.
+@leave KErrArgument If the argument passed to an object is incorrect.
+
+@return A pointer to the newly created CMatchData object.
+
+@internalComponent
+*/
+EXPORT_C CMatchData* CMatchData::NewL(const TDesC8& aPackage)
+ {
+ CMatchData* me = CMatchData::NewLC(aPackage);
+ CleanupStack::Pop(me);
+ return me;
+ }
+
+
+/**
+Creates CMatchData object with its default values.
+Leaves an obeject pointer on a cleanup stack.
+
+@leave KErrNoMemory If there is not enough memory
+
+@return A pointer to the newly created CMatchData object.
+
+*/
+EXPORT_C CMatchData* CMatchData::NewLC()
+ {
+ CMatchData* me = new (ELeave) CMatchData();
+ CleanupStack::PushL(me);
+ return me;
+ }
+
+
+/**
+Creates CMatchData object using heap based stream of externalized object's data.
+Leaves an obeject pointer on a cleanup stack.
+
+@param aPackage Descriptor to the heap based stream of externalized object
+
+@leave KErrNoMemory If there is not enough memory to create an object.
+@leave KErrArgument If the argument passed to an object is incorrect.
+
+@return A pointer to the newly created CMatchData object.
+
+@internalComponent
+*/
+EXPORT_C CMatchData* CMatchData::NewLC(const TDesC8& aPackage)
+ {
+ CMatchData* me = new (ELeave) CMatchData();
+ CleanupStack::PushL(me);
+ me->ConstructL(aPackage);
+ return me;
+ }
+
+/**
+Standard symbian 2-phase construction method.
+It reads a stream stored on a heap and internalize the object.
+
+@param aPackage Descriptor to the heap based stream of externalized object
+
+@leave KErrNoMemory If there is not enough memory to create an object.
+@leave KErrArgument If the argument passed to an object is incorrect.
+
+@return A pointer to the newly created CMatchData object.
+
+@internalComponent
+*/
+void CMatchData::ConstructL(const TDesC8& aPackage)
+ {
+ RDesReadStream stream(aPackage);
+ InternalizeL(stream);
+ stream.Close();
+ }
+
+/**
+Externalizes the object into RWriteStrem.
+
+@param aStream Stream to write to
+
+@internalComponent
+*/
+void CMatchData::ExternalizeL(RWriteStream& aStream) const
+ {
+ aStream.WriteInt16L(iMimeType? iMimeType->Length():0);
+ if(iMimeType && iMimeType->Length() > 0)
+ {
+ aStream.WriteL(*iMimeType, iMimeType->Length());
+ }
+
+ aStream.WriteInt16L(iVariant?iVariant->Length():0);
+ if (iVariant && iVariant->Length() > 0 )
+ {
+ aStream.WriteL(*iVariant, iVariant->Length());
+ }
+
+ aStream.WriteUint32L(iAddInfo);
+ }
+
+/**
+Internalizes the object out of RReadStream.
+
+@param aStream Stream to read from
+
+@leave KErrNoMemory If there is not enough memory for new string allocation.
+@leave KErrArgument If passed descriptor doesn't comply with length constraints.
+
+@internalComponent
+*/
+void CMatchData::InternalizeL(RReadStream& aStream)
+ {
+ TInt16 temp;
+
+ // read mime type and create the heap buffer for it.
+ // verify constraints
+ temp = aStream.ReadInt16L();
+ if (temp <=0 || temp > KXmlMaxMimeTypeLength)
+ {
+ // must not be greater then max
+ User::LeaveIfError(KErrArgument);
+ }
+
+ // delete current value as it is no longer valid
+ if (iMimeType != NULL)
+ {
+ delete iMimeType;
+ iMimeType = NULL;
+ }
+
+ // create buffer and read new data if available
+ if (temp > 0)
+ {
+ iMimeType = HBufC8::NewL(temp);
+ TPtr8 ptr = iMimeType->Des();
+ aStream.ReadL(ptr, temp);
+ }
+
+ // read variant and create the heap buffer for it.
+ // verify constarints
+ temp = aStream.ReadInt16L();
+ if (temp <0 || temp > KXmlMaxVariantLength)
+ {
+ // must not be greater then max, zero possible.
+ User::LeaveIfError(KErrArgument);
+ }
+
+ // delete current value as it is no longer valid
+ if (iVariant != NULL)
+ {
+ delete iVariant;
+ iVariant = NULL;
+ }
+
+ // create buffer and read new data if available
+ if (temp > 0)
+ {
+ iVariant = HBufC8::NewL(temp);
+ TPtr8 ptr = iVariant->Des();
+ aStream.ReadL(ptr, temp);
+ }
+
+ // read additional info
+ iAddInfo = aStream.ReadUint32L();
+ // check for correctness of the iAddInfo bitmap
+ if (iAddInfo & KXmlAddInfoReservedFlags > 0 )
+ {
+ // Leave as unexpected flags are set.
+ User::LeaveIfError(KErrArgument);
+ }
+}
+
+/**
+Sets up a mime type attribute to a string given as an aData descriptor.
+
+@param aData String descriptor
+
+@leave KErrNoMemory If there is not enough memory for new string allocation.
+@leave KErrArgument If passed descriptor doesn't comply with length constraints.
+
+*/
+EXPORT_C void CMatchData::SetMimeTypeL(const TDesC8& aData)
+ {
+ // verify constraints
+ if (aData.Length() == 0 || aData.Length() > KXmlMaxMimeTypeLength)
+ {
+ // must not be greater than max
+ User::Leave(KErrArgument);
+ }
+
+ // delete current value as it is no longer valid
+ if (iMimeType != NULL)
+ {
+ delete iMimeType;
+ iMimeType = NULL;
+ }
+
+ // allocate required buffer and copy new data
+ iMimeType = aData.AllocL();
+
+ }
+
+/**
+Sets up a variant attribute to a string given as an aVariant descriptor.
+If this is not set OR is set to a string of length 0 the Variant ID is
+not used during parser resolution and hence the variant IDs of plug-in
+parsers are ignored.
+
+@param aData String descriptor
+
+@leave KErrNoMemory If there is not enough memory for new string allocation.
+@leave KErrArgument If passed descriptor doesn't comply with length constraints.
+
+*/
+EXPORT_C void CMatchData::SetVariantL(const TDesC8& aVariant)
+ {
+
+ // verify constraints
+ if (aVariant.Length() > KXmlMaxVariantLength)
+ {
+ // must not be greater than max
+ User::Leave(KErrArgument);
+ }
+
+ // delete current value as it is no longer valid
+ if (iVariant != NULL)
+ {
+ delete iVariant;
+ iVariant = NULL;
+ }
+
+ // allocate required buffer and copy new data
+ iVariant = aVariant.AllocL();
+ }
+
+/**
+Returns a pointer to the mime type string.
+
+@return A pointer to the mime type string.
+ Pointer to KNullDesC8 is returned if not set up yet.
+
+*/
+EXPORT_C const TPtrC8 CMatchData::MimeType() const
+ {
+ TPtrC8 result;
+
+ if(iMimeType)
+ result.Set(*iMimeType);
+ else
+ result.Set(KNullDesC8);
+
+ return result;
+ }
+
+/**
+Returns a pointer to the variant string.
+
+@return A pointer to the variant string.
+ Pointer to KNullDesC8 is returned if not set up yet.
+
+*/
+EXPORT_C const TPtrC8 CMatchData::Variant() const
+ {
+ TPtrC8 result;
+
+ if(iVariant)
+ result.Set(*iVariant);
+ else
+ result.Set(KNullDesC8);
+
+ return result;
+ }
+
+/**
+Returns a heap based buffer descriptor of an externalized CMatchData object stream.
+The newly created object's ownership is shifted to the caller.
+
+@leave KErrNoMemory If there is not enough memory to create an heap based buffer.
+
+@return Heap based buffer descriptor of an externalized object stream.
+
+@internalComponent
+*/
+HBufC8* CMatchData::PackToBufferL() const
+ {
+ //Create new Heap Descriptor with the size of externalized CMatchData
+ HBufC8* data = HBufC8::NewLC( (iMimeType?iMimeType->Size():0)
+ + (iVariant?iVariant->Size():0)
+ + 2*sizeof(TInt16) // length of mime type and variant strings
+ + sizeof(TUint32)); // size of addinfo variable
+
+ // create the stream using allocated buffer
+ TPtr8 dataDes = data->Des();
+ RDesWriteStream stream(dataDes);
+
+ // pack object into the allocated buffer
+ ExternalizeL(stream);
+
+ //cleanup
+ stream.Close();
+ CleanupStack::Pop(data);
+ return data;
+ }
+
+
+/**
+Sets the LeaveOnManyFlag flag.
+If set, it notifies customized resolver it should leave when the query is resolved to more than one parser.
+By default this flag is not set, so the framework chooses a parser in this case.
+
+@param aSetting The setting value.
+
+*/
+EXPORT_C void CMatchData::SetLeaveOnMany(TBool aSetting)
+ {
+ SYMBIAN_XML_FLAG_SET(iAddInfo, KXmlLeaveOnManyFlag, aSetting);
+ }
+
+/**
+Sets the Rom Only flag.
+If set, it notifies customized resolver the request is for ROM-based parsers only.
+By default this flag is not set, so the framework searches for rom and non-rom based parsers.
+
+@param aSetting The setting value.
+
+*/
+EXPORT_C void CMatchData::SetRomOnly(TBool aSetting)
+ {
+ SYMBIAN_XML_FLAG_SET(iAddInfo, KXmlRomOnlyFlag, aSetting);
+ }
+
+/**
+Sets the Case Sensitivity flag.
+Customized resolver uses this setting to turn on or off case sensitivity for strings matching.
+
+@param aSetting The setting value.
+
+*/
+EXPORT_C void CMatchData::SetCaseSensitivity(TBool aSetting)
+ {
+ SYMBIAN_XML_FLAG_SET(iAddInfo, KXmlCaseSensitivityFlag, aSetting);
+ }
+
+/**
+Static function to sort an array of CImplementationInformation objects,
+in ascending order of their Uid values.
+The function is used in CMatchData::ResolveL().
+
+@param aImpInfo1 pointer of first CImplementationInformation object
+@param aImpInfo2 pointer of second CImplementationInformation object
+
+@return zero, if the two objects have equal Uids
+@return a negative value, if the first object's Uid is less than the second object's Uid.
+@return a positive value, if the first object's Uid is greater than the second object's Uid.
+
+@internalComponent
+
+*/
+TInt CMatchData::SortOrder(const CImplementationInformation &aImpInfo1,
+ const CImplementationInformation &aImpInfo2)
+ {
+ if (aImpInfo1.ImplementationUid().iUid > aImpInfo2.ImplementationUid().iUid)
+ {
+ return 1;
+ }
+ if (aImpInfo1.ImplementationUid().iUid < aImpInfo2.ImplementationUid().iUid)
+ {
+ return -1;
+ }
+ return 0;
+ }
+
+/**
+Performs a parser resolution.
+Following criteria are considered:
+ - Case sensitivity for string matching is applied according to the Case Sensitivity flag.
+ - Only ROM-based parsers are considered when ROM only flag is set.
+ - Mime type is mandatory as it must match the data field in resource information file.
+ - Variant is optional. If present it must match first entry in the opaque data field.
+ - If the query is narrowed down to more than one parser the behaviour is determined in
+ SelectSingleParserL function.
+
+@param aImplList The list of available parsers to choose from.
+
+@leave KErrNoMemory
+@leave KErrXmlMoreThanOneParserMatched
+
+@return Parser's Uid or KNullUid if parser isn't found.
+
+@see SelectSingleParserL
+
+@internalComponent
+
+*/
+EXPORT_C TUid CMatchData::ResolveL(RImplInfoArray& aImplList) const
+ {
+ TUid matchUid;
+
+ // Create an array to hold multiple matching parser uids
+ // RImplInfoPtrArray is used here for the usage of TLinearOrder<> pattern
+ RImplInfoPtrArray parserArray;
+
+ CleanupClosePushL(parserArray);
+
+ // go through the list of implementations for the
+ for (TInt i = 0 ; i < aImplList.Count(); i++)
+ {
+ ::CImplementationInformation* impData = aImplList[i];
+
+ if (RomOnly() && !(impData->RomBased()))
+ {
+ // Request for rom based parser only.
+ // This one isn't rom based, so continue with the next one
+ continue;
+ }
+
+ if ((MimeTypeMatch(impData->DataType()) == TRUE)
+ && (VariantMatch(impData->OpaqueData()) == TRUE) )
+ {
+ // store the matching implementation occurance
+ // if there is only one occurance, this Uid will be returned
+ // otherwise, the list will contain items sorted by Uid
+ // (see CMatchData::SortOrder())
+ parserArray.InsertInOrderL(impData,
+ TLinearOrder<CImplementationInformation>(CMatchData::SortOrder));
+ }
+ }
+
+ // check if multiple match found
+ if (parserArray.Count()==1)
+ {
+ // list filtered down to one parser.
+ matchUid = parserArray[0]->ImplementationUid();
+ }
+ else if (parserArray.Count()>1)
+ {
+ // multiple matches found. we need to make a decision
+ matchUid = SelectSingleParserL(parserArray);
+ }
+ else
+ {
+ // no match
+ matchUid = KNullUid;
+ }
+
+ CleanupStack::PopAndDestroy(&parserArray);
+ return matchUid;
+ }
+
+/**
+Helps parser resolution when multiple matches are found
+Following criteria are considered on the list filtered by ResolveL:
+- The code might either leave with an error if LeaveOnMany flag is set, or
+ select a parser from the multiple-item list. The default behaviour is to select
+ the parser with lowest uid. To preserve backwards compatibility, in the case of
+ no variant a Symbian supplied parser will be returned if present. If there are
+ multiple matching Symbian parsers, the one with the lowest Uid will be returned.
+
+@param aImplList The filtered list of parsers to choose from.
+
+@leave KErrNoMemory
+@leave KErrXmlMoreThanOneParserMatched
+
+@return Parser's Uid
+
+@internalComponent
+*/
+TUid CMatchData::SelectSingleParserL(RImplInfoPtrArray& aImplList) const
+ {
+ TInt arrayLen = aImplList.Count();
+
+ // check if multiple match found
+ if ( LeaveOnMany() )
+ {
+ // At this point more than one parser was found matching resolution criteria,
+ // the user is requesting to leave in such a case
+ User::Leave(KErrXmlMoreThanOneParserMatched);
+ }
+
+ if (IsInvalidVariant())
+ {
+ // multiple matches in list and variant is invalid means we should look for Symbian plugin
+ // we go through the (ascending) sorted list of implementations
+ for (TInt j = 0 ; j <= arrayLen-1; j++)
+ {
+ ::CImplementationInformation* impData = aImplList[j];
+
+ // we check every matching parser variant for Symbian string
+ if ((CaseSensitivity() && (impData->OpaqueData().Compare(KXmlSymbianPluginVariant) == 0))
+ ||(!CaseSensitivity() && (impData->OpaqueData().CompareF(KXmlSymbianPluginVariant) == 0)) )
+ {
+ // this match is the lowest Uid Symbian parser, return it
+ return impData->ImplementationUid();
+ }
+ }
+ // if this for loop finishes without returning, this means there are multiple
+ // matching parsers none of which are Symbian. We defer their processing to the
+ // common 'return lowest uid' part of the algorithm
+ }
+
+ // return the lowest uid, which should be the first item in the list
+ return aImplList[0]->ImplementationUid();
+ }
+
+/**
+Performs string matching for all the entries in an aField string separated by aSeparator.
+
+@param aField string with several entries separated by aSeparator.
+@param aMatchString string to match against entries in aField
+@param aSeparator string which separates entries in aField
+
+@return Match result
+
+@internalComponent
+*/
+TBool CMatchData::MatchField(const TDesC8& aField, const TDesC8& aMatchString, const TDesC8& aSeparator) const
+ {
+ // verify input data
+ if (aField.Length() == 0 || aMatchString.Length() == 0)
+ {
+ return EFalse;
+ }
+
+ // Check if aField and aMatchString are not the same.
+ // For most cases aField is a one-entry string, so for better performance it is worth to check it up front.
+ if ( (CaseSensitivity() && (aField.Compare(aMatchString) == 0))
+ || (!CaseSensitivity() && (aField.CompareF(aMatchString) == 0) ) )
+ {
+ return ETrue;
+ }
+
+ // Find the first separator position
+ TInt separatorPos = aField.Find(aSeparator);
+ if (separatorPos == KErrNotFound)
+ {
+ // No separators in the string.
+ // Only one entry in the aField string, which was already verified as non-matching.
+ // No matches found then.
+ return EFalse;
+ }
+
+ TInt separatorLength = aSeparator.Length();
+
+ // call again the method with the "first field" of the string
+ if (MatchField(aField.Left(separatorPos), aMatchString, aSeparator) == TRUE)
+ {
+ return ETrue;
+ }
+
+ // call the method with the remaining sections of the string
+ if (MatchField(aField.Mid(separatorPos + separatorLength), aMatchString, aSeparator) == TRUE)
+ {
+ return ETrue;
+ }
+
+ //All recursive calls returned false, so the match wasn't found
+ return EFalse;
+ }
+
+/**
+Checks for mime type entry in aDataField string.
+
+@param aDataFiled string with several mime type entries separated by "||" string.
+
+@return Match result
+
+@internalComponent
+*/
+TBool CMatchData::MimeTypeMatch(const TDesC8& aDataField) const
+ {
+ return MatchField(aDataField, *iMimeType, KXmlDataSeparator);
+ }
+
+/**
+Checks for variant string entry in first field of aOpaqueField string.
+
+@param aOpaqueField string with several entries separated by "||" string.
+
+@return Match result
+
+@internalComponent
+*/
+TBool CMatchData::VariantMatch(const TDesC8& aOpaqueField) const
+ {
+ TPtrC8 matchString;
+
+ if (IsInvalidVariant())
+ {
+ // optional variant is not set
+ // return true in all cases
+ return ETrue;
+ }
+
+ TInt separatorPos = aOpaqueField.Find(KXmlDataSeparator);
+
+ // set the first entry in the opague data to match against
+ if (separatorPos == KErrNotFound)
+ {
+ matchString.Set(aOpaqueField);
+ }
+ else
+ {
+ matchString.Set(aOpaqueField.Left(separatorPos));
+ }
+
+ // perform string matching
+ if ( (CaseSensitivity() && (iVariant->Compare(matchString) == 0))
+ ||(!CaseSensitivity() && (iVariant->CompareF(matchString) == 0)) )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+/**
+Returns Case Sensitivity flag value
+
+@return Flag state
+
+@internalComponent
+*/
+TBool CMatchData::CaseSensitivity() const
+ {
+ return (iAddInfo & KXmlCaseSensitivityFlag)?ETrue:EFalse;
+ }
+
+/**
+Returns LeaveOnMany flag value
+
+@return Flag state
+
+@internalComponent
+*/
+TBool CMatchData::LeaveOnMany() const
+ {
+ return (iAddInfo & KXmlLeaveOnManyFlag)?ETrue:EFalse;
+ }
+
+/**
+Returns Rom-Only flag value
+
+@return Flag state
+
+@internalComponent
+*/
+TBool CMatchData::RomOnly() const
+ {
+ return (iAddInfo & KXmlRomOnlyFlag)?ETrue:EFalse;
+ }
+
+/**
+Assignement operator
+
+@param aMatchData CMatchData object to assign from
+
+@internalComponent
+*/
+CMatchData& CMatchData::operator=(const CMatchData & aMatchData)
+ {
+
+ /*
+ * SYMBIAN DEF132492 FIX : Added TRAP statements to handle the case wherein the functions
+ * called here leave.
+ */
+ TRAPD( err, SetMimeTypeL(aMatchData.MimeType()) ) ;
+ if( err != KErrNone )
+ {
+ return *this;
+ }
+
+ /*
+ * SYMBIAN DEF132492 FIX : Added TRAP statements to handle the case wherein the functions
+ * called here leave.
+ */
+ TRAP( err, SetVariantL(aMatchData.Variant()));
+ if( err != KErrNone )
+ {
+ return *this;
+ }
+
+
+ iAddInfo = aMatchData.iAddInfo;
+ return *this;
+ }
+/**
+Comparison operator.
+
+@param aMatchData CMatchData object to compare with
+
+@internalComponent
+*/
+TBool CMatchData::operator==(const CMatchData & aMatchData) const
+ {
+
+ // verify iAddInfo first as the fastest comparision
+ if (aMatchData.iAddInfo != iAddInfo)
+ {
+ return EFalse;
+ }
+
+ // verfiy mime type
+ if (iMimeType == NULL
+ || (CaseSensitivity() && iMimeType->Compare(aMatchData.MimeType()) != 0)
+ || (!CaseSensitivity() && iMimeType->CompareF(aMatchData.MimeType()) != 0) )
+ {
+ // iMimeType is NULL or strings doesn't match
+ // verify the case where both might be NULL.
+ if ( (iMimeType != NULL) || (aMatchData.iMimeType != NULL ) )
+ {
+ // mime type doesn't match
+ return EFalse;
+ }
+ }
+
+ // verfiy variant
+ if (iVariant == NULL
+ || (CaseSensitivity() && iVariant->Compare(aMatchData.Variant()) != 0)
+ || (!CaseSensitivity() && iVariant->CompareF(aMatchData.Variant()) != 0) )
+ {
+ // iVariant is NULL or strings doesn't match
+ // verify the case where both might be NULL.
+ if ( (iVariant != NULL) || (aMatchData.iVariant != NULL) )
+ {
+ // variant doesn't match
+ return EFalse;
+ }
+ }
+ return ETrue;
+ }
+
+/**
+Checks if iVariant is not set or empty
+
+@return Variant string validness
+
+@internalComponent
+*/
+TBool CMatchData::IsInvalidVariant() const
+ {
+ return (iVariant == NULL || (iVariant && iVariant->Length() == 0));
+ }
+