metadataengine/server/src/mdsnotifycomparator.cpp
changeset 0 c53acadfccc6
child 3 b73a2e62868f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/metadataengine/server/src/mdsnotifycomparator.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,1277 @@
+/*
+* 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:  Comparator algorithms for notifier*
+*/
+
+#include "mdsnotifycomparator.h"
+
+#include "mdcresult.h"
+#include "mdcitem.h"
+#include "mdccommon.pan"
+#include "mdcserializationbuffer.h"
+#include "mderange.h"
+#include "mdscommoninternal.h"
+#include "mdcquery.h"
+#include "mdccommon.h"
+#include "mdeinternalerror.h"
+
+CMdSNotifyComparator* CMdSNotifyComparator::NewL()
+    {
+    CMdSNotifyComparator* that = CMdSNotifyComparator::NewLC();
+    CleanupStack::Pop( that );
+    return that;
+    }
+
+CMdSNotifyComparator* CMdSNotifyComparator::NewLC()
+	{
+	CMdSNotifyComparator* that = new(ELeave) CMdSNotifyComparator();
+	CleanupStack::PushL( that );
+	that->ConstructL();
+	return that;
+	}
+
+
+CMdSNotifyComparator::~CMdSNotifyComparator()
+    {
+    
+    }
+
+CMdSNotifyComparator::CMdSNotifyComparator()
+    {
+    
+    }
+
+void CMdSNotifyComparator::ConstructL()
+    {
+    }
+
+TBool CMdSNotifyComparator::MatchL(
+	TDefId aNamespaceDefId, TUint32 aType,
+    CMdCSerializationBuffer& aSerializedCondition,
+    CMdCSerializationBuffer& aSerializedItems,
+    CMdCSerializationBuffer& aSerializedItemIds,
+    RArray<TItemId>& aMatchingItemIdArray,
+    TBool aAllowConfidential)
+    {
+    const TMdCItems& items = TMdCItems::GetFromBufferL( aSerializedItems );
+
+    const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( aSerializedItemIds );
+
+	// check if some namespace definitions are not the same
+    if( itemIds.iNamespaceDefId != aNamespaceDefId )
+    	{
+    	return EFalse;
+    	}
+
+    if( ( items.iObjects.iPtr.iCount > 0 ) && 
+    	( itemIds.iObjectIds.iPtr.iCount > 0 ) && 
+    	( aType & ( EObjectNotifyAdd | EObjectNotifyModify ) ) )
+    	{
+    	// object ID count and object item count should match
+		__ASSERT_DEBUG( items.iObjects.iPtr.iCount == itemIds.iObjectIds.iPtr.iCount, MMdCCommon::Panic( KErrCorrupt ) );
+
+    	aSerializedItemIds.PositionL( itemIds.iObjectIds.iPtr.iOffset );
+    	for( TUint32 i = 0; i < itemIds.iObjectIds.iPtr.iCount; i++ )
+    		{
+    		TItemId objectId;
+    		aSerializedItemIds.ReceiveL( objectId );
+
+    		if( aSerializedCondition.Size() > 0 )
+    			{
+	            TBool results( EFalse );
+	            TBool succeed( EFalse );
+    			
+	            // move condition buffer's position beginnig of the buffer
+	            aSerializedCondition.PositionL( KNoOffset  );
+	            
+	            const TMdCLogicCondition& logicCondition = 
+	            		TMdCLogicCondition::GetFromBufferL( aSerializedCondition );
+
+	            for ( TUint32 j = 0; j < logicCondition.iChildConditions.iPtr.iCount; j++ )
+	                {
+		    		// set correct position to item buffer
+	    	    	aSerializedItems.PositionL( items.iObjects.iPtr.iOffset + 
+	    	    			i * sizeof(TMdCObject) );
+
+	    	    	// set correct positin to condition buffer
+	    	    	aSerializedCondition.PositionL( 
+	    	    			logicCondition.iChildConditions.iPtr.iOffset + 
+	    	    			j * CMdCSerializationBuffer::KRequiredSizeForTUint32 );
+	    	    	TUint32 conditionOffset;
+	    	    	aSerializedCondition.ReceiveL( conditionOffset );
+	    	    	aSerializedCondition.PositionL( conditionOffset );
+
+	                results = MatchObjectL( aSerializedCondition, 
+	                		aSerializedItems, objectId, aAllowConfidential );
+
+	                succeed = results;
+	                if ( logicCondition.iOperator == ELogicConditionOperatorAnd )
+	                    {
+	                    if( !results )
+	                        {
+	                        break;
+	                        }
+	                    }
+
+	                if ( logicCondition.iOperator == ELogicConditionOperatorOr )
+	                    {
+	                    if( results )
+	                        {
+	                        break;
+	                        }
+	                    }
+	                }
+    		
+	            if ( logicCondition.iNegated )    
+	                {
+	                succeed = !( succeed );
+	                }
+
+	    	    if ( succeed )    
+	                {
+	                aMatchingItemIdArray.AppendL( objectId );
+	                }
+    			}
+    		else
+    			{
+    			aMatchingItemIdArray.AppendL( objectId );
+    			}
+    		}
+    	}
+    else if( ( items.iEvents.iPtr.iCount > 0 ) && 
+    		 ( itemIds.iEventIds.iPtr.iCount > 0 ) && 
+    		 ( aType & ( EEventNotifyAdd /*| EEventNotifyRemove*/ ) ) )
+    	{
+    	// event ID count and event item count should match
+		__ASSERT_DEBUG( items.iEvents.iPtr.iCount == itemIds.iEventIds.iPtr.iCount, MMdCCommon::Panic( KErrCorrupt ) );
+
+		aSerializedItemIds.PositionL( itemIds.iEventIds.iPtr.iOffset );
+    	for( TUint32 i = 0; i < itemIds.iEventIds.iPtr.iCount; i++ )
+    		{
+    		TItemId eventId;
+    		aSerializedItemIds.ReceiveL( eventId );
+    		
+    		if( aSerializedCondition.Size() > 0 )
+    			{
+	    		// set correct position to item buffer
+	    		aSerializedItems.PositionL( items.iEvents.iPtr.iOffset + i * sizeof(TMdCEvent) );
+
+	    		// move condition buffer's position to the begin of the buffer
+	    		aSerializedCondition.PositionL( KNoOffset );
+
+	    		if( MatchEventL( aSerializedCondition, aSerializedItems, eventId ) )
+	    			{
+	    			aMatchingItemIdArray.AppendL( eventId );
+	    			}
+    			}
+    		else
+    			{
+    			aMatchingItemIdArray.AppendL( eventId );
+    			}
+    		}
+    	}
+    else if( ( items.iRelations.iPtr.iCount > 0 ) && 
+    		 ( itemIds.iRelationIds.iPtr.iCount > 0 ) && 
+    		 ( aType & ( ERelationNotifyAdd | ERelationNotifyModify /*| ERelationNotifyRemove*/ ) ) )
+    	{
+    	// relation ID count and relation item count should match
+		__ASSERT_DEBUG( items.iRelations.iPtr.iCount == itemIds.iRelationIds.iPtr.iCount, MMdCCommon::Panic( KErrCorrupt ) );
+
+    	aSerializedItemIds.PositionL( itemIds.iRelationIds.iPtr.iOffset );
+    	for( TUint32 i = 0; i < itemIds.iRelationIds.iPtr.iCount; i++ )
+    		{
+    		TItemId relationId;
+    		aSerializedItemIds.ReceiveL( relationId );
+
+			if( aSerializedCondition.Size() > 0 )
+				{
+	    		// set correct position to item buffer
+	    		aSerializedItems.PositionL( items.iRelations.iPtr.iOffset
+	    				+ i * sizeof(TMdCRelation) );
+
+	    		// move condition buffer's position to the begin of the buffer
+	    		aSerializedCondition.PositionL( KNoOffset );
+
+	    		if( MatchRelationL( aSerializedCondition, aSerializedItems, relationId ) )
+	    			{
+	    			aMatchingItemIdArray.AppendL( relationId );
+	    			}
+				}
+			else
+				{
+				aMatchingItemIdArray.AppendL( relationId );
+				}
+    		}
+    	}
+
+    if( aMatchingItemIdArray.Count() > 0 )
+    	{
+    	return ETrue;
+    	}
+    else
+    	{
+    	return EFalse;
+    	}
+    }
+
+TBool CMdSNotifyComparator::MatchObjectL(
+		CMdCSerializationBuffer& aSerializedCondition,
+		CMdCSerializationBuffer& aSerializedItem, TItemId aObjectId, 
+		TBool aAllowConfidential )
+	{
+ 	// check if object is failed
+	if( aObjectId == KNoId )
+		{
+		return EFalse;
+		}
+
+	// Check type
+	const TMdCCondition& condition = 
+			TMdCCondition::GetFromBufferL( aSerializedCondition );
+
+	switch( condition.iConditionType )
+		{
+	    case EConditionTypeObject:
+	        {
+	    	return ( CheckObjectL( aSerializedCondition, aSerializedItem, 
+	    			aAllowConfidential ) );
+	    	}
+		case EConditionTypeProperty:
+		case EConditionTypePropertyIntRange:
+		case EConditionTypePropertyInt64Range:
+		case EConditionTypePropertyUintRange:
+		case EConditionTypePropertyRealRange:
+		case EConditionTypePropertyTimeRange:
+	    case EConditionTypePropertyText:
+    	case EConditionTypePropertyBool:
+	        {
+   			return ( CheckPropertyL( aSerializedCondition, aSerializedItem ) );
+	    	}
+    	default:
+#ifdef _DEBUG
+    		User::Panic( _L("MdSNCMaO") , KErrMdEUnknownConditionType );
+#endif    		
+    	    break;
+		}
+
+	return EFalse;
+	}
+
+TBool CMdSNotifyComparator::CheckPropertyL( 
+		CMdCSerializationBuffer& aSerializedCondition,
+    	CMdCSerializationBuffer& aSerializedItem )
+    {
+    const TMdCObject& object = TMdCObject::GetFromBufferL( aSerializedItem );
+    
+    const TMdCPropertyCondition& propertyCondition = 
+    		TMdCPropertyCondition::GetFromBufferL( aSerializedCondition );
+
+    for( TUint32 i=0; i < object.iProperties.iPtr.iCount; i++ )
+        {
+        aSerializedItem.PositionL( object.iProperties.iPtr.iOffset
+        		+ i * sizeof(TMdCProperty) );
+        const TMdCProperty& property = TMdCProperty::GetFromBufferL( aSerializedItem );
+
+        // check propertyDefId doesn't match -> skip it
+        if( property.iPropertyDefId == propertyCondition.iPropertyDefId )
+            {
+            // move condition buffer to begin of the condition
+            aSerializedCondition.PositionL( propertyCondition.iCondition );
+
+            switch( propertyCondition.iConditionType )
+	            {
+	            case EConditionTypeProperty:
+	            	{
+		            // check only if existing condition is negated
+	            	if( propertyCondition.iNegated )
+	            		{
+	            		return EFalse;
+	            		}
+	            	else
+	            		{
+	            		return ETrue;
+	            		}
+	            	}
+	            
+   	            case EConditionTypePropertyIntRange:
+	                {
+		            TInt32 rangeType32( 0 );
+		            aSerializedCondition.ReceiveL( rangeType32 );
+		            const TMdERangeType rangeType = ( TMdERangeType )rangeType32;
+
+		            TMdCValueUnion minValue;
+                    aSerializedCondition.ReceiveL( minValue );
+                    TMdCValueUnion maxValue;
+                    aSerializedCondition.ReceiveL( maxValue );
+
+		            // init range for next test
+                    TMdEIntRange range( minValue.iInt32, maxValue.iInt32, 
+                    		rangeType );
+		            
+   	                if( range.InRange( property.iValue.iInt32 ) == propertyCondition.iNegated )
+                        {
+                        return EFalse;
+                        }   
+	                break;
+	                }
+	            case EConditionTypePropertyInt64Range:
+	                {
+		            TInt32 rangeType32( 0 );
+		            aSerializedCondition.ReceiveL( rangeType32 );
+		            const TMdERangeType rangeType = ( TMdERangeType )rangeType32;
+
+		            TMdCValueUnion minValue;
+                    aSerializedCondition.ReceiveL( minValue );
+                    TMdCValueUnion maxValue;
+                    aSerializedCondition.ReceiveL( maxValue );
+
+                    // init range for next test
+                    TMdEInt64Range range( minValue.iInt64, maxValue.iInt64, 
+                    		rangeType );
+                    
+                    // test if valueType is in the range
+                    if( range.InRange( property.iValue.iInt64 ) == propertyCondition.iNegated )
+                        {
+                        return EFalse;
+                        }	                
+	                break;
+	                }
+	            case EConditionTypePropertyUintRange:
+	                {
+		            TInt32 rangeType32( 0 );
+		            aSerializedCondition.ReceiveL( rangeType32 );
+		            const TMdERangeType rangeType = ( TMdERangeType )rangeType32;
+
+		            TMdCValueUnion minValue;
+                    aSerializedCondition.ReceiveL( minValue );
+                    TMdCValueUnion maxValue;
+                    aSerializedCondition.ReceiveL( maxValue );
+
+                    // init range for next test
+                    TMdEUintRange range( minValue.iUint32, maxValue.iUint32, 
+                    		rangeType );
+	               
+   	                if( range.InRange( property.iValue.iUint32 ) == propertyCondition.iNegated )
+                        {
+                        return EFalse;
+                        }   
+	                break;
+	                }
+	            case EConditionTypePropertyRealRange:
+	                {
+		            TInt32 rangeType32( 0 );
+		            aSerializedCondition.ReceiveL( rangeType32 );
+		            const TMdERangeType rangeType = ( TMdERangeType )rangeType32;
+
+		            TMdCValueUnion minValue;
+                    aSerializedCondition.ReceiveL( minValue );
+                    TMdCValueUnion maxValue;
+                    aSerializedCondition.ReceiveL( maxValue );
+                    
+                    // init range for next test
+                    TMdERealRange range( minValue.iReal, maxValue.iReal, rangeType );
+
+                    // test if valueType is in the range
+                    if( range.InRange( property.iValue.iReal ) == propertyCondition.iNegated )
+                        {
+                        return EFalse;
+                        }	                
+	                break;
+	                }
+	            case EConditionTypePropertyTimeRange:
+                    {
+		            TInt32 rangeType32( 0 );
+		            aSerializedCondition.ReceiveL( rangeType32 );
+		            TMdERangeType rangeType = ( TMdERangeType )rangeType32;
+
+		            TMdCValueUnion minValue;
+                    aSerializedCondition.ReceiveL( minValue );
+                    TMdCValueUnion maxValue;
+                    aSerializedCondition.ReceiveL( maxValue );
+
+                    // init range for next test
+                    TMdETimeRange range( minValue.iInt64, maxValue.iInt64, 
+                    		rangeType );
+
+	                TTime value( property.iValue.iInt64 );
+                    // test if valueType is in the range
+                    if( range.InRange( property.iValue.iInt64 ) == propertyCondition.iNegated )
+                        {
+                        return EFalse;
+                        }	                
+                    break;
+                    }
+                case EConditionTypePropertyText:
+	                {
+	                // SerializedItem
+	                aSerializedItem.PositionL( property.iValue.iPtr.iOffset );
+	                TPtrC16 value = aSerializedItem.ReceivePtr16L();
+
+	                // ConditionItem
+	                TUint32 condCompareMethod( 0 );
+	                aSerializedCondition.ReceiveL( condCompareMethod );
+	                TPtrC16 condValue = aSerializedCondition.ReceivePtr16L();
+
+                    //Check, that compare method is in range
+#ifdef _DEBUG
+	                if( condCompareMethod <= ETextPropertyConditionCompareFirst || condCompareMethod >= ETextPropertyConditionCompareLast )
+	                	{
+						User::Panic( _L("MdSNCCP1") , KErrMdEUnknownConditionCompareMethod );
+	                	}
+#endif
+	                TBool compareResult( EFalse );
+
+	                switch( condCompareMethod )
+		                {
+	                    case ETextPropertyConditionCompareEquals:
+	   		                {
+	   		                if( (value == condValue ) )
+	   		                    {
+	   		                    compareResult = EFalse;
+	   		                    }
+	   		                break;
+	   		                }
+	                    case ETextPropertyConditionCompareContains:
+	   		                {
+	   		                compareResult = FindDes( value, condValue ); 
+	   		                break;
+	   		                }
+	                    case ETextPropertyConditionCompareBeginsWith:
+	   		                {
+	   		                compareResult = CompareDesBeginsWith( value, condValue ); 
+                            break;	   		               
+	   		                }
+	                    case ETextPropertyConditionCompareEndsWith:
+	                        {
+	   		                compareResult = CompareDesEndsWith( value, condValue );
+                            break;	   		               
+	   		                }
+                        default: 
+                            {
+#ifdef _DEBUG
+                            User::Panic( _L("MdSNCCP2") , KErrMdEUnknownConditionCompareMethod );
+#endif
+   		                    }
+		                }          
+	                
+	                if( compareResult == propertyCondition.iNegated )
+	                    {
+	                    return EFalse;
+	                    }
+	                break;
+	                }
+	            case EConditionTypePropertyBool:
+    		        {
+			        const TBool value( property.iValue.iInt32 );
+
+			        TBool condValue( EFalse );
+			        aSerializedCondition.ReceiveL( condValue );
+
+			        if( ( value == condValue ) == propertyCondition.iNegated )
+				        {
+				        return EFalse;
+				        }
+			        break;
+    		        }
+	            default:
+	            	{
+#ifdef _DEBUG
+                    User::Panic( _L("MdSNCCP3") , KErrMdEUnknownConditionType );
+#endif
+	            	User::Leave( KErrMdEUnknownConditionType );
+	            	}
+	            } // switch
+
+            return ETrue;
+
+            } // if
+
+        } // for
+
+    return EFalse;
+    }
+
+TBool CMdSNotifyComparator::CheckObjectL( CMdCSerializationBuffer& aSerializedCondition,
+    			   						  CMdCSerializationBuffer& aSerializedItem,
+    			   						  TBool aAllowConfidential )
+    {
+    const TMdCObject& object = TMdCObject::GetFromBufferL( aSerializedItem );
+
+	const TBool confidential = object.iFlags & EMdEObjectFlagConfidential;
+
+	// check if object is confidential and confidentials are not allowed
+	if( confidential && ( aAllowConfidential == EFalse ) )
+		{
+		return EFalse;
+		}
+
+	// check if no condition defined
+	if( aSerializedCondition.Size() <= 0 )
+		{
+		// pass all successful objects
+		return ETrue;
+		}
+
+	const TMdCObjectCondition& condition = 
+			TMdCObjectCondition::GetFromBufferL( aSerializedCondition );
+
+	switch( condition.iConfidentialityLevel )
+		{
+	    case EObjectConditionLevelNormal:
+	    	if( confidential )
+	    		{
+	    		return EFalse;
+	    		}
+			break;
+		case EObjectConditionLevelConfidential:
+	    	if( confidential == EFalse )
+	    		{
+	    		return EFalse;
+	    		}
+			break;
+
+	    default:
+	    	{
+#ifdef _DEBUG
+            User::Panic( _L("MdSNCCO1") , KErrMdEUnknownConfidentialityLevel );
+#endif	    	
+	    	User::Leave( KErrMdEUnknownConfidentialityLevel );
+	    	}
+		}
+
+	if( ( condition.iFlags & EMdEObjectFlagPlaceholder ) && 
+			( object.iFlags & EMdEObjectFlagPlaceholder ) )
+		{
+		return EFalse;
+		}
+
+	// move position to begin of sub condition
+	aSerializedCondition.PositionL( condition.iCondition );
+	
+	switch( condition.iCompareMethod )
+		{
+		case EObjectConditionCompareNone:
+			break;
+
+		case EObjectConditionCompareId:
+			{
+			TItemId conditionObjectId;
+			aSerializedCondition.ReceiveL( conditionObjectId );
+
+			if( ( conditionObjectId == object.iId ) == condition.iNegated )
+				{
+				return EFalse;
+				}
+			}
+			break;
+
+        case EObjectConditionCompareUsageCount:
+			{
+			TInt32 rangeType32;
+			aSerializedCondition.ReceiveL( rangeType32 );
+			const TMdERangeType rangeType = (TMdERangeType)rangeType32;
+
+			TMdCValueUnion minValue;
+			aSerializedCondition.ReceiveL( minValue );
+			TMdCValueUnion maxValue;
+			aSerializedCondition.ReceiveL( maxValue );
+
+			// init range for next test
+			TMdEUintRange range( minValue.iUint32, maxValue.iUint32, 
+					rangeType );
+
+			// test if event's creation time is in the range
+			if( BoolEqual( range.InRange( object.iUsageCount ), condition.iNegated ) )
+				{
+				return EFalse;
+				}
+			}
+			break;
+
+		case EObjectConditionCompareGuid:
+			{
+			TInt64 conditionGuidHigh;
+			aSerializedCondition.ReceiveL( conditionGuidHigh );
+			TInt64 conditionGuidLow;
+			aSerializedCondition.ReceiveL( conditionGuidLow );
+
+			if( ( ( conditionGuidHigh == object.iGuidHigh ) && 
+				( conditionGuidLow == object.iGuidLow ) ) == 
+				condition.iNegated )
+				{
+				return EFalse;
+				}
+			}
+			break;
+
+        case EObjectConditionCompareObjectDef:
+			{
+			TDefId conditionObjectDefId;
+			aSerializedCondition.ReceiveL( conditionObjectDefId );
+
+			if( ( conditionObjectDefId == object.iDefId ) == condition.iNegated )
+				{
+				return EFalse;
+				}
+			}
+			break;
+
+        case EObjectConditionCompareUri:
+			{
+			aSerializedItem.PositionL( object.iUri.iPtr.iOffset );
+			TPtrC16 uri = aSerializedItem.ReceivePtr16L();
+
+			TPtrC16 conditionUri = aSerializedCondition.ReceivePtr16L();
+
+			if( ( conditionUri.Compare( uri ) == 0 ) == condition.iNegated )
+				{
+				return EFalse;
+				}
+			}
+			break;
+
+        case EObjectConditionCompareUriBeginsWith:
+			{
+			aSerializedItem.PositionL( object.iUri.iPtr.iOffset );
+			TPtrC16 uri = aSerializedItem.ReceivePtr16L();
+
+			TPtrC16 conditionUri = aSerializedCondition.ReceivePtr16L();
+
+			if( CompareDesBeginsWith( uri, conditionUri ) == condition.iNegated )
+				{
+				return EFalse;
+				}
+			}
+			break;
+
+	    default:
+	    	{
+#ifdef _DEBUG
+            User::Panic( _L("MdSNCCO2") , KErrMdEUnknownConditionCompareMethod );
+#endif	    	
+	    	User::Leave( KErrMdEUnknownConditionCompareMethod );
+	    	}
+		}
+
+	return ETrue;
+    }
+
+
+TBool CMdSNotifyComparator::MatchEventL(CMdCSerializationBuffer& aSerializedCondition,
+					    			    CMdCSerializationBuffer& aSerializedItem,
+					    			    TItemId aEventId)
+	{
+	const TMdCEvent& event = TMdCEvent::GetFromBufferL( aSerializedItem );
+
+	// check if event is failed
+	if( aEventId == 0 )
+		{
+		return EFalse;
+		}
+
+	// check if no condition defined
+	if( aSerializedCondition.Size() <= 0 )
+		{
+		// pass all successful events
+		return ETrue;
+		}
+
+	const TMdCEventCondition& eventCondition = 
+			TMdCEventCondition::GetFromBufferL( aSerializedCondition );
+
+	// check if event condition contains event ID comparsion
+	if( eventCondition.iEventId != KNoId )
+		{
+		if( ( eventCondition.iEventId == event.iId ) == eventCondition.iNegated )
+			{
+			return EFalse;
+			}
+		}
+
+	// check if event condition contains event def ID comparsion
+	if( eventCondition.iEventDefId != KNoDefId )
+		{
+		if( ( eventCondition.iEventDefId == event.iDefId ) == eventCondition.iNegated )
+			{
+			return EFalse;
+			}
+		}
+
+	// check event condition contains event creation time range comparision
+	if( eventCondition.iCreationTimeRange != KNoOffset )
+		{
+		aSerializedCondition.PositionL( eventCondition.iCreationTimeRange );
+
+		TInt32 rangeType32;
+		aSerializedCondition.ReceiveL( rangeType32 );
+		const TMdERangeType rangeType = (TMdERangeType)rangeType32;
+
+		TMdCValueUnion minValue;
+		aSerializedCondition.ReceiveL( minValue );
+		TMdCValueUnion maxValue;
+		aSerializedCondition.ReceiveL( maxValue );
+
+		// init range for next test
+		TMdEInt64Range range( minValue.iInt64, maxValue.iInt64, rangeType );
+
+		// test if event's creation time is in the range
+		if( range.InRange( event.iTime.Int64() ) == eventCondition.iNegated )
+			{
+			return EFalse;
+			}
+		}
+
+	// check object condition 
+	// (only accept OR-logic condition which contains object ID condition(s))
+	if( eventCondition.iObjectCondition != KNoOffset )
+		{
+		aSerializedCondition.PositionL( eventCondition.iObjectCondition );
+
+		if( MatchObjectIdToObjectIdConditionsL( aSerializedCondition, 
+				event.iObjectId ) == eventCondition.iNegated )
+			{
+			return EFalse;
+			}
+		}
+
+	// check event condition contains source or participant comparsion
+	if( ( EEventConditionCompareSourceURI == eventCondition.iCompareMethod ) || 
+		( EEventConditionCompareParticipantURI == eventCondition.iCompareMethod ) )
+		{
+		aSerializedCondition.PositionL( eventCondition.iUriCondition );
+
+		TPtrC16 eventConditionUri = aSerializedCondition.ReceivePtr16L();
+
+		// source comparsion
+		if( EEventConditionCompareSourceURI == eventCondition.iCompareMethod )
+			{
+			TPtrC16 eventSource( KNullDesC );
+			if ( event.iSourceText.iPtr.iCount > 0 )
+				{
+				aSerializedItem.PositionL( event.iSourceText.iPtr.iOffset );
+				eventSource.Set( aSerializedItem.ReceivePtr16L() );
+				}
+
+			if( ( eventConditionUri.Compare( eventSource ) == 0 ) == eventCondition.iNegated )
+				{
+				return EFalse;
+				}
+			}
+		// participant comparsion
+		else
+			{
+			TPtrC16 eventParticipant( KNullDesC );
+			if (event.iParticipantText.iPtr.iCount > 0)
+				{
+				aSerializedItem.PositionL( event.iParticipantText.iPtr.iOffset );
+				eventParticipant.Set( aSerializedItem.ReceivePtr16L() );
+				}
+
+			if( ( eventConditionUri.Compare( eventParticipant ) == 0 ) == eventCondition.iNegated )
+				{
+				return EFalse;
+				}
+			}
+		}
+
+	return ETrue;
+	}
+
+TBool CMdSNotifyComparator::MatchRelationL(CMdCSerializationBuffer& aSerializedCondition,
+    				 					   CMdCSerializationBuffer& aSerializedItem,
+    				 					   TItemId aRelationId)
+	{
+    const TMdCRelation& relation = 
+    		TMdCRelation::GetFromBufferL( aSerializedItem );
+
+	// check if event is failed
+	if( aRelationId == 0 )
+		{
+		return EFalse;
+		}
+
+	// check if no condition defined
+	if( aSerializedCondition.Size() <= 0 )
+		{
+		// pass all successful events
+		return ETrue;
+		}
+
+	const TMdCRelationCondition& relationCondition = 
+			TMdCRelationCondition::GetFromBufferL( aSerializedCondition );
+
+	// check if relation condition contains relation def ID comparsion
+	if( relationCondition.iRelationDefId != KNoDefId &&
+		BoolEqual( relationCondition.iRelationDefId == relation.iDefId, 
+				relationCondition.iNegated ) )
+		{
+		return EFalse;
+		}
+
+	if ( relationCondition.iRelationId != KNoId &&
+		 	 BoolEqual( relationCondition.iRelationId == aRelationId, 
+		 			 relationCondition.iNegated ) )
+		{
+		return EFalse;
+		}
+	
+	if ( relationCondition.iRelationIds.iPtr.iOffset != KNoOffset &&
+			BoolEqual( MatchRelationIdsL( relationCondition, 
+					aSerializedCondition, aRelationId ), 
+					relationCondition.iNegated ) )
+		{
+		return EFalse;
+		}
+
+	if( relationCondition.iGuid != KNoOffset )
+		{
+		TInt64 conditionGuidHigh;
+		aSerializedCondition.ReceiveL( conditionGuidHigh );
+		TInt64 conditionGuidLow;
+		aSerializedCondition.ReceiveL( conditionGuidLow );
+
+		if ( conditionGuidHigh != 0 && conditionGuidLow != 0 &&
+			 ( BoolEqual( conditionGuidHigh == relation.iGuidHigh, 
+					 relationCondition.iNegated ) ||
+			   BoolEqual( conditionGuidHigh == relation.iGuidLow, 
+					   relationCondition.iNegated ) ) )
+			{
+			return EFalse;
+			}
+		}
+
+	// check relation condition contains relation parameter range comparision
+	if( relation.iParameter != KNoOffset )
+		{
+		aSerializedCondition.PositionL( relation.iParameter );
+		
+		TInt32 rangeType32;
+		aSerializedCondition.ReceiveL( rangeType32 );
+		const TMdERangeType rangeType = (TMdERangeType)rangeType32;
+
+		TMdCValueUnion minValue;
+		aSerializedCondition.ReceiveL( minValue );
+		TMdCValueUnion maxValue;
+		aSerializedCondition.ReceiveL( maxValue );
+
+		// init range for next test
+		TMdEIntRange range( minValue.iInt32, maxValue.iInt32, rangeType );
+
+		// test if event's creation time is in the range
+		if( BoolEqual( range.InRange( relation.iParameter ), 
+				relationCondition.iNegated ) )
+			{
+			return EFalse;
+			}
+		}
+
+	if( relationCondition.iLeftObjectCondition != KNoOffset && 
+			ERelationConditionSideLeft == relationCondition.iObjectSide )
+		{
+		aSerializedCondition.PositionL( relationCondition.iLeftObjectCondition );
+
+		if( BoolEqual( MatchObjectIdToObjectIdConditionsL(
+				aSerializedCondition, relation.iLeftObjectId ), 
+				relationCondition.iNegated ) )
+			{
+			return EFalse;
+			}
+		}
+
+	if( relationCondition.iRightObjectCondition != KNoOffset && 
+			ERelationConditionSideRight  == relationCondition.iObjectSide )
+		{
+		aSerializedCondition.PositionL( 
+				relationCondition.iRightObjectCondition );
+
+		if( BoolEqual( MatchObjectIdToObjectIdConditionsL(
+				aSerializedCondition, relation.iRightObjectId ), 
+				relationCondition.iNegated ) )
+			{
+			return EFalse;
+			}
+		}
+
+	if ( ( relationCondition.iLeftObjectCondition != KNoOffset || 
+			relationCondition.iRightObjectCondition != KNoOffset ) && 
+			ERelationConditionSideEither == relationCondition.iObjectSide )
+		{
+		TBool eitherMatches = EFalse;
+		
+		if ( relationCondition.iLeftObjectCondition != KNoOffset )
+			{
+			aSerializedCondition.PositionL( 
+					relationCondition.iLeftObjectCondition );
+	
+			if( !BoolEqual( MatchObjectIdToObjectIdConditionsL(
+					aSerializedCondition, relation.iLeftObjectId ), 
+					relationCondition.iNegated ) )
+				{
+				eitherMatches = ETrue;
+				}
+			}
+		
+		if ( relationCondition.iRightObjectCondition != KNoOffset )
+			{
+			aSerializedCondition.PositionL( 
+					relationCondition.iRightObjectCondition );
+
+			if( !BoolEqual( MatchObjectIdToObjectIdConditionsL(
+					aSerializedCondition, relation.iRightObjectId ), 
+					relationCondition.iNegated ) )
+				{
+				eitherMatches = ETrue;
+				}
+			}
+
+		// left and right condition didn't match
+		if( !eitherMatches )
+			{
+			return EFalse;
+			}
+		}
+
+	if ( relationCondition.iLastModifiedDateRange != KNoOffset )
+		{
+		aSerializedCondition.PositionL( 
+				relationCondition.iLastModifiedDateRange );
+
+		TInt32 rangeRule;
+		aSerializedCondition.ReceiveL( rangeRule );
+		const TMdERangeType rangeType = (TMdERangeType)rangeRule;
+
+		TMdCValueUnion minValue;
+		aSerializedCondition.ReceiveL( minValue );
+		TMdCValueUnion maxValue;
+		aSerializedCondition.ReceiveL( maxValue );
+
+		// init range for next test
+		TMdEInt64Range range( minValue.iInt64, maxValue.iInt64, rangeType );
+
+		// test if event's creation time is in the range
+		if( BoolEqual( range.InRange( relation.iLastModifiedDate.Int64() ), 
+				relationCondition.iNegated ) )
+			{
+			return EFalse;
+			}
+		}
+
+	return ETrue;
+	}
+
+TBool CMdSNotifyComparator::MatchObjectIdsL(
+						    CMdCSerializationBuffer& aSerializedCondition,
+						    const RArray<TItemId>& aItemIdArray,
+						    RArray<TItemId>& aMatchingItemIdArray
+						    )
+	{
+	// check if condition buffer contains condition
+	if( aSerializedCondition.Size() > 0 )
+		{
+		aSerializedCondition.PositionL( KNoOffset );
+
+		const TMdCLogicCondition& logicCondition = 
+				TMdCLogicCondition::GetFromBufferL( aSerializedCondition );
+
+		for( TUint32 i = 0; i < logicCondition.iChildConditions.iPtr.iCount; i++ )
+		    {
+	       	aSerializedCondition.PositionL( 
+	       			logicCondition.iChildConditions.iPtr.iOffset + 
+	       			i * CMdCSerializationBuffer::KRequiredSizeForTUint32 );
+
+	 		TUint32 childOffset;
+		    aSerializedCondition.ReceiveL( childOffset );
+		    aSerializedCondition.PositionL( childOffset );
+
+		    const TMdCCondition& condition = TMdCCondition::GetFromBufferL( 
+					aSerializedCondition );
+			
+			if( EConditionTypeObject == condition.iConditionType )
+				{
+				const TMdCObjectCondition& objectCondition = 
+						TMdCObjectCondition::GetFromBufferL( aSerializedCondition );
+
+			    if ( EObjectConditionCompareNone == objectCondition.iCompareMethod )
+			    	{
+                    // all matches
+                    return ETrue;
+			    	}
+			    
+	    		// only ID conditions are checked
+	    		if( EObjectConditionCompareId == objectCondition.iCompareMethod )
+	    			{
+	    			aSerializedCondition.PositionL( objectCondition.iCondition );
+	    			
+	    			// get object condition's object ID
+	    			TItemId conditionObjectId;
+	    			aSerializedCondition.ReceiveL( conditionObjectId );
+
+	    			const TInt objectIdCount = aItemIdArray.Count();
+	    			for( TInt i = 0; i < objectIdCount; i++ )
+	    				{
+	    				const TItemId objectId = aItemIdArray[i];
+	
+	    				if( ( objectId == conditionObjectId ) != objectCondition.iNegated )
+	    					{
+	    					aMatchingItemIdArray.AppendL( objectId );
+	    					}
+	    				}
+	
+	    			if( aMatchingItemIdArray.Count() < aItemIdArray.Count() )
+	    				{
+	    				// none or some matches
+	    				return EFalse;
+	    				}	
+	    			else
+	    				{
+	    				// all matches
+	    				return ETrue;
+	    				}
+	    			}
+	    		else
+	    			{
+                    // if condition is something else than ID, return true so that client receives
+                    // needed notification even though also extra notifications will  be received
+                    return ETrue;
+	    			}
+				}
+    		}
+		}
+   return ETrue;
+   }
+
+TBool CMdSNotifyComparator::FindDes( TDesC16& aDes, TDesC16& aFindDes )
+	{
+	if( aDes.Find( aFindDes ) != KErrNotFound  )
+	    {
+	    return ETrue;
+	    }
+	return EFalse;
+	}
+
+TBool CMdSNotifyComparator::CompareDesEndsWith( TDesC16& aDes, TDesC16& aCompareDes )
+	{
+	if( aDes.Length() < aCompareDes.Length() )
+		{
+		return EFalse;
+		}
+
+	return ( aDes.Right( aCompareDes.Length() ).Compare( aCompareDes ) == 0 );
+	}
+
+TBool CMdSNotifyComparator::CompareDesBeginsWith( TDesC16& aDes, TDesC16& aCompareDes )
+	{
+	if( aDes.Length() < aCompareDes.Length() )
+		{
+		return EFalse;
+		}
+
+	return ( aDes.Left( aCompareDes.Length() ).Compare( aCompareDes ) == 0 );
+	}
+
+TBool CMdSNotifyComparator::MatchObjectIdToObjectIdConditionsL(
+	CMdCSerializationBuffer& aSerializedCondition, TItemId aObjectId)
+	{
+	const TMdCLogicCondition& logicCondition = 
+			TMdCLogicCondition::GetFromBufferL( aSerializedCondition );
+	
+	TBool matchingId = EFalse;
+
+	for( TUint32 i = 0; i < logicCondition.iChildConditions.iPtr.iCount; i++ )
+		{
+		aSerializedCondition.PositionL( 
+				logicCondition.iChildConditions.iPtr.iOffset + 
+				i * CMdCSerializationBuffer::KRequiredSizeForTUint32 );
+
+		TUint32 childOffset;
+		aSerializedCondition.ReceiveL( childOffset );
+		aSerializedCondition.PositionL( childOffset );
+
+		const TMdCCondition& condition = TMdCCondition::GetFromBufferL( 
+				aSerializedCondition );
+		
+		if( EConditionTypeObject == condition.iConditionType )
+			{
+			const TMdCObjectCondition& objectCondition = 
+					TMdCObjectCondition::GetFromBufferL( aSerializedCondition );
+			
+			if( EObjectConditionCompareId == objectCondition.iCompareMethod )
+				{
+				aSerializedCondition.PositionL( objectCondition.iCondition );
+
+				TItemId conditionObjectId;
+				aSerializedCondition.ReceiveL( conditionObjectId );
+				
+				TBool currentMatch = ( conditionObjectId == aObjectId ) != objectCondition.iNegated;
+	
+				if( currentMatch )
+					{
+					matchingId = ETrue;
+					break;
+					}
+				}
+			}
+		}
+		
+	return matchingId != logicCondition.iNegated;
+	}
+
+TBool CMdSNotifyComparator::MatchRelationIdsL(
+		const TMdCRelationCondition& aRelationCondition, 
+		CMdCSerializationBuffer& aSerializedCondition, TItemId aRelationId)
+	{
+	if( aRelationCondition.iRelationIds.iPtr.iCount > 0 &&
+			aRelationCondition.iRelationIds.iPtr.iOffset != KNoOffset )
+		{
+		aSerializedCondition.PositionL( aRelationCondition.iRelationIds.iPtr.iOffset );
+
+		for (TInt i = 0; i < aRelationCondition.iRelationIds.iPtr.iCount; ++i)
+			{
+			TItemId relationId;
+			aSerializedCondition.ReceiveL( relationId );
+			if ( relationId == aRelationId )
+				{
+				return ETrue;
+				}
+			}
+		}
+
+	return EFalse;
+	}
+
+TBool CMdSNotifyComparator::MatchRelationItemsL(
+		    CMdCSerializationBuffer& aSerializedCondition,
+		    CMdCSerializationBuffer& aSerializedItems,
+		    RArray<TItemId>& aMatchingItemIdArray)
+    {
+    aSerializedItems.PositionL( KNoOffset );
+    
+    const TMdCItems& items = TMdCItems::GetFromBufferL( aSerializedItems );
+
+    if( items.iRelations.iPtr.iCount == 0 )
+    	{
+    	return EFalse;
+    	}
+
+	for( TUint32 i = 0; i < items.iRelations.iPtr.iCount; i++ )
+		{
+		aSerializedItems.PositionL( items.iRelations.iPtr.iOffset + 
+				+ i * sizeof(TMdCRelation) );
+	    const TMdCRelation& relation = TMdCRelation::GetFromBufferL( aSerializedItems );
+
+		if( aSerializedCondition.Size() > 0 )
+			{
+    		// move condition buffer's position to the begin of the buffer
+    		aSerializedCondition.PositionL( KNoOffset );
+
+    		if( MatchRelationItemL( aSerializedCondition, relation ) )
+    			{
+    			aMatchingItemIdArray.AppendL( relation.iId );
+    			}
+			}
+		else
+			{
+			aMatchingItemIdArray.AppendL( relation.iId );
+			}
+		}
+
+	if( aMatchingItemIdArray.Count() > 0 )
+    	{
+    	return ETrue;
+    	}
+    else
+    	{
+    	return EFalse;
+    	}
+    }
+
+TBool CMdSNotifyComparator::MatchRelationItemL(CMdCSerializationBuffer& aSerializedCondition,
+		   const TMdCRelation& aRelation)
+	{
+	// check if event is failed
+	if( aRelation.iId == 0 )
+		{
+		return EFalse;
+		}
+	
+	const TMdCRelationCondition& relationCondition = 
+			TMdCRelationCondition::GetFromBufferL( aSerializedCondition );
+
+	// check if relation condition contains relation def ID comparsion
+	if( relationCondition.iRelationDefId != KNoDefId &&
+		BoolEqual( relationCondition.iRelationDefId == aRelation.iDefId, 
+				relationCondition.iNegated ) )
+		{
+		return EFalse;
+		}
+	
+	// check if relation condition contains relation ID comparsion
+	if ( relationCondition.iRelationId != KNoId &&
+	 	 BoolEqual( relationCondition.iRelationId == aRelation.iId, 
+	 			relationCondition.iNegated ) )
+		{
+		return EFalse;
+		}
+
+	// check if relation condition contains relation IDs comparsion
+	if ( relationCondition.iRelationIds.iPtr.iOffset != KNoOffset &&
+			BoolEqual( MatchRelationIdsL( relationCondition, 
+					aSerializedCondition, aRelation.iId ), 
+					relationCondition.iNegated ) )
+		{
+		return EFalse;
+		}
+
+	// check relation condition contains left and/or right object condition comparisions
+	if ( ( relationCondition.iLeftObjectCondition != KNoOffset || 
+			relationCondition.iRightObjectCondition != KNoOffset ) && 
+			ERelationConditionSideEither == relationCondition.iObjectSide )
+		{
+		TBool eitherMatches = EFalse;
+		
+		if ( relationCondition.iLeftObjectCondition != KNoOffset )
+			{
+			aSerializedCondition.PositionL( 
+					relationCondition.iLeftObjectCondition );
+	
+			if( !BoolEqual( MatchObjectIdToObjectIdConditionsL(
+					aSerializedCondition, aRelation.iLeftObjectId ), 
+					relationCondition.iNegated ) )
+				{
+				eitherMatches = ETrue;
+				}
+			}
+		
+		if ( relationCondition.iRightObjectCondition != KNoOffset )
+			{
+			aSerializedCondition.PositionL( 
+					relationCondition.iRightObjectCondition );
+
+			if( !BoolEqual( MatchObjectIdToObjectIdConditionsL(
+					aSerializedCondition, aRelation.iRightObjectId ), 
+					relationCondition.iNegated ) )
+				{
+				eitherMatches = ETrue;
+				}
+			}
+
+		// left and right condition didn't match
+		if( !eitherMatches )
+			{
+			return EFalse;
+			}
+		}
+
+	return ETrue;
+	}