metadataengine/client/src/mdeobjectcondition.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 20:34:07 +0200
changeset 0 c53acadfccc6
child 7 3cebc1a84278
permissions -rw-r--r--
Revision: 201001 Kit: 201003

/*
* Copyright (c) 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:  ?Description
*
*/

#include "mdeobjectcondition.h"
#include "mdcserializationbuffer.h"
#include "mdeobjectdef.h"
#include "mdepanic.h"
#include "mdscommoninternal.h"
#include "mdcquery.h"


CMdEObjectCondition* CMdEObjectCondition::NewL( TObjectConditionCompareMethod aCompareMethod,
		TItemId aObjectId, const CMdEObjectDef* aObjectDef,
		TInt64 aObjectGuidHigh, TInt64 aObjectGuidLow )
	{
	CMdEObjectCondition* self = CMdEObjectCondition::NewLC( aCompareMethod,
			aObjectId, aObjectDef, aObjectGuidHigh, aObjectGuidLow );
	CleanupStack::Pop( self );
	return self;	
	}

CMdEObjectCondition* CMdEObjectCondition::NewLC( TObjectConditionCompareMethod aCompareMethod,
		TItemId aObjectId, const CMdEObjectDef* aObjectDef,
		TInt64 aObjectGuidHigh, TInt64 aObjectGuidLow )
	{
	CMdEObjectCondition* self = new (ELeave) CMdEObjectCondition( aCompareMethod,
			aObjectId, aObjectDef, aObjectGuidHigh, aObjectGuidLow );
	CleanupStack::PushL( self );
	self->ConstructL();
	return self;
	}

CMdEObjectCondition* CMdEObjectCondition::NewL( TObjectConditionCompareMethod aCompareMethod,
		const RArray<TItemId>* aObjectIds, const TDesC* aString, const TMdEUintRange* aRange )
	{
	CMdEObjectCondition* self = CMdEObjectCondition::NewLC( aCompareMethod, aObjectIds, aString, aRange );
	CleanupStack::Pop( self );
	return self;	
	}

CMdEObjectCondition* CMdEObjectCondition::NewLC( TObjectConditionCompareMethod aCompareMethod,
		const RArray<TItemId>* aObjectIds, const TDesC* aString, const TMdEUintRange* aRange )
	{
	CMdEObjectCondition* self = new (ELeave) CMdEObjectCondition( aCompareMethod );
	CleanupStack::PushL( self );
	self->ConstructL( aObjectIds, aString, aRange );
	return self;
	}


CMdEObjectCondition::CMdEObjectCondition( TObjectConditionCompareMethod aCompareMethod,
									TItemId aObjectId, const CMdEObjectDef* aObjectDef,
									TInt64 aObjectGuidHigh, TInt64 aObjectGuidLow )
	: CMdECondition(EConditionTypeObject), iObjectDef( aObjectDef ), 
	  iObjectId( aObjectId ), iObjectIds( NULL ), 
	  iString( NULL ), iCompareMethod( aCompareMethod ), iFlags( 0 ),
	  iConfidentialityLevel(EObjectConditionLevelNormal),
	  iGuidHigh( aObjectGuidHigh ), iGuidLow( aObjectGuidLow ),
	  iRange( NULL )
	{
	#ifdef _DEBUG
	if ( iObjectDef )
		{
		__ASSERT_DEBUG(aCompareMethod == EObjectConditionCompareObjectDef, TMdEPanic::Panic(TMdEPanic::EInternal));
		}
	else if ( iObjectId != KNoId )
		{
		__ASSERT_DEBUG(aCompareMethod == EObjectConditionCompareId, TMdEPanic::Panic(TMdEPanic::EInternal));
		}
	else if ( iGuidHigh != 0 || iGuidLow != 0 )
		{
		__ASSERT_DEBUG(aCompareMethod == EObjectConditionCompareGuid, TMdEPanic::Panic(TMdEPanic::EInternal));
		}
	else
		{
		__ASSERT_DEBUG(aCompareMethod == EObjectConditionCompareNone, TMdEPanic::Panic(TMdEPanic::EInternal));
		}
	
	#endif
	}

CMdEObjectCondition::CMdEObjectCondition( TObjectConditionCompareMethod aCompareMethod )
	: CMdECondition(EConditionTypeObject), iObjectDef( NULL ), 
	  iObjectId( KNoId ), iObjectIds( NULL ), 
	  iString( NULL ), iCompareMethod( aCompareMethod ), iFlags( 0 ),
	  iConfidentialityLevel(EObjectConditionLevelNormal), iGuidHigh( 0 ), iGuidLow( 0 )
	{
	__ASSERT_DEBUG(iCompareMethod > EObjectConditionCompareFirst && iCompareMethod < EObjectConditionCompareLast, TMdEPanic::Panic(TMdEPanic::EInternal));
	}

void CMdEObjectCondition::ConstructL()
    {
    // Base class construction.
    ConditionConstruct();
    
    // Non-confidential objects are queried by default
    iConfidentialityLevel = EObjectConditionLevelNormal;
    }

void CMdEObjectCondition::ConstructL( const RArray<TItemId>* aObjectIds,
		const TDesC* aString, const TMdEUintRange* aRange )
	{
	if ( aString )
		{
		iString = HBufC::NewL(aString->Length());
		iString->Des().CopyLC( *aString );
		}
	else if ( aObjectIds )
		{
	    iObjectIds = new (ELeave) RArray<TItemId>;
		
	    const TInt objectIdCount = aObjectIds->Count();
	    iObjectIds->ReserveL( objectIdCount );
	    
		for( TInt i = 0; i < objectIdCount; i++ )
			{
			iObjectIds->Append( (*aObjectIds)[i] );
			}
		}
	else if ( aRange )
		{
		iRange = new(ELeave) TMdEUintRange(*aRange);
		}
	else
		{
		User::Leave( KErrArgument );
		}
	}

CMdEObjectCondition::~CMdEObjectCondition()
	{
   	delete iString;

   	if( iObjectIds )
    	{
    	iObjectIds->Close();
    	
    	delete iObjectIds;
    	}
    
   	delete iRange;
	}

EXPORT_C const CMdEObjectDef* CMdEObjectCondition::ObjectDef() const
    {
    return iObjectDef;
    }

EXPORT_C TItemId CMdEObjectCondition::ObjectId() const
    {
    return iObjectId;
    }

EXPORT_C const RArray<TItemId>* CMdEObjectCondition::ObjectIds() const
	{
	return iObjectIds;
	}

EXPORT_C const TDesC* CMdEObjectCondition::String() const
    {
    return iString;
    }


EXPORT_C TObjectConditionCompareMethod CMdEObjectCondition::CompareMethod() const
    {
    return iCompareMethod;
    }


EXPORT_C TObjectConditionConfidentialityLevel CMdEObjectCondition::ConfidentialityLevel() const
    {
    return iConfidentialityLevel;
    }

EXPORT_C void CMdEObjectCondition::SetConfidentialityLevel( TObjectConditionConfidentialityLevel aLevel )
    {
    iConfidentialityLevel = aLevel;
    }

EXPORT_C TBool CMdEObjectCondition::NotPresent() const
	{
	return iFlags & EMdEObjectFlagNotPresent ? ETrue : EFalse;
	}

EXPORT_C void CMdEObjectCondition::SetNotPresent(TBool aNotPresent)
	{
	if( aNotPresent )
		{
		iFlags |= EMdEObjectFlagNotPresent; 
		}
	else
		{
		iFlags &= ~EMdEObjectFlagNotPresent;
		}
	}

EXPORT_C TBool CMdEObjectCondition::NotPlaceholder() const
	{
	return iFlags & EMdEObjectFlagPlaceholder ? ETrue : EFalse;
	}

EXPORT_C void CMdEObjectCondition::SetNotPlaceholder(TBool aNotPlaceholder)
	{
	if( aNotPlaceholder )
		{
		iFlags |= EMdEObjectFlagPlaceholder; 
		}
	else
		{
		iFlags &= ~EMdEObjectFlagPlaceholder;
		}
	}

EXPORT_C TBool CMdEObjectCondition::PlaceholderOnly() const
    {
    return iPlaceholdersOnly;
    }

EXPORT_C void CMdEObjectCondition::SetPlaceholderOnly(TBool aPlaceholderOnly )
    {
    iPlaceholdersOnly = aPlaceholderOnly;
    }

TUint32 CMdEObjectCondition::InternalQueryOptimizationFlags(TUint32& aFlags)
	{
	TUint32 optimizationFlags = EContainsObjectCondition;

	if( iFlags & EMdEObjectFlagNotPresent )
		{
		optimizationFlags |= EContainsNotPresentCondition;
		}

	switch( iCompareMethod )
		{
        case EObjectConditionCompareFreeText:
        case EObjectConditionCompareFreeTextContains:
        case EObjectConditionCompareFreeTextBeginsWith:
        case EObjectConditionCompareFreeTextEndsWith:
			optimizationFlags |= EContainsFreetextCondition;
			break;
		default:
			break;
		}
	
	if( iPlaceholdersOnly )
	    {
	    optimizationFlags |= EContainsPlaceholdersOnly;
	    }

	aFlags |= optimizationFlags;
	return optimizationFlags;
	}

TUint32 CMdEObjectCondition::RequiredBufferSize() const
	{
	TUint32 bufferSize = sizeof( TMdCObjectCondition );

	switch( iCompareMethod )
		{
		case EObjectConditionCompareNone:
			break;

		case EObjectConditionCompareId:
			{
			// Required size for object ID
			bufferSize += CMdCSerializationBuffer::KRequiredSizeForTItemId;
			}
			break;

		case EObjectConditionCompareIds:
			{
			// Required size for object ID
			bufferSize += CMdCSerializationBuffer::KRequiredSizeForTUint32; // count
			if( iObjectIds )
				{
				bufferSize += CMdCSerializationBuffer::KRequiredSizeForTItemId * iObjectIds->Count();
				}
			}
			break;

	    case EObjectConditionCompareGuid:
	    	{
			// Required size for object GUID high (TInt64), object GUID low (TInt64)
			bufferSize += 2 * CMdCSerializationBuffer::KRequiredSizeForTInt64;
	    	}
			break;

	    case EObjectConditionCompareObjectDef:
	    	{
			// Required size for object def ID (TUint32)
			bufferSize += CMdCSerializationBuffer::KRequiredSizeForTDefId;
	    	}
			break;

	    case EObjectConditionCompareUri:
	    case EObjectConditionCompareUriBeginsWith:
	    case EObjectConditionCompareFreeText:
	    case EObjectConditionCompareFreeTextContains:
	    case EObjectConditionCompareFreeTextBeginsWith:
	    case EObjectConditionCompareFreeTextEndsWith:
	    	{
			// Required size for string
			bufferSize += CMdCSerializationBuffer::RequiredSize( *iString );
	    	}
			break;

	    case EObjectConditionCompareUsageCount:
	    	{
	    	__ASSERT_DEBUG( iRange, User::Panic( _L("Incorrect range condition"), KErrArgument ) );
	    	bufferSize += iRange->RequiredBufferSize();
	    	}
	    	break;

	    default:
			TMdEPanic::Panic( TMdEPanic::EInternal );
			break;
		}

	return bufferSize;
	}

void CMdEObjectCondition::SerializeL(CMdCSerializationBuffer& aBuffer, 
		TMdCOffset& aFreespaceOffset) const
	{
	const TUint32 conditionOffset = aBuffer.Position();
	const TUint32 subConditionOffset = 
			conditionOffset + sizeof( TMdCObjectCondition );

	TMdCObjectCondition condition; 

	condition.iConditionType = iType;
	condition.iNegated = iNegated;
	condition.iConfidentialityLevel = iConfidentialityLevel;
	condition.iCompareMethod = iCompareMethod;
	condition.iFlags = iFlags;
	condition.iCondition = subConditionOffset;

	aBuffer.PositionL( subConditionOffset );

	switch( iCompareMethod )
		{
		case EObjectConditionCompareNone:
			{
			// nothing to compare, so "clear" condition offset
			condition.iCondition = KNoOffset;
			}
			break;
	
		case EObjectConditionCompareId:
			{
			aBuffer.InsertL( iObjectId );
			}
			break;
	
		case EObjectConditionCompareIds:
			{
			if( iObjectIds )
				{
				const TInt count = iObjectIds->Count();
				
				aBuffer.InsertL( (TInt32)count );
				
				for( TInt i = 0; i < count; i++ )
					{
					aBuffer.InsertL( (*iObjectIds)[i] );
					}
				}
			else
				{
				aBuffer.InsertL( TInt32( 0 ) );
				}
			}
			break;
	
	    case EObjectConditionCompareGuid:
			{
			aBuffer.InsertL( iGuidHigh );
			aBuffer.InsertL( iGuidLow );
			}
			break;

	    case EObjectConditionCompareObjectDef:
			{
			aBuffer.InsertL( iObjectDef->Id() );
			}
			break;

	    case EObjectConditionCompareUsageCount:
			{
			__ASSERT_DEBUG( iRange, User::Panic( 
					_L("Incorrect range condition"), KErrArgument ) );
			iRange->SerializeL( aBuffer );
			}
			break;

	    case EObjectConditionCompareUri:
	    case EObjectConditionCompareUriBeginsWith:
	    case EObjectConditionCompareFreeText:
	    case EObjectConditionCompareFreeTextContains:
	    case EObjectConditionCompareFreeTextBeginsWith:
	    case EObjectConditionCompareFreeTextEndsWith:
			{
			aBuffer.InsertL( *iString );
			}
			break;

		default:
			{
#ifdef _DEBUG
			TMdEPanic::Panic(TMdEPanic::EInternal);
#endif
			}
			break;
		}

	// get position after sub condition
	aFreespaceOffset = aBuffer.Position();

	// serialize condition
	aBuffer.PositionL( conditionOffset );
	condition.SerializeL( aBuffer );
	
	// and move back to after sub condition
	aBuffer.PositionL( aFreespaceOffset );
	}