metadataengine/client/src/mderelationcondition.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 15:02:02 +0300
branchRCL_3
changeset 63 e538444823de
parent 47 b73252188534
permissions -rw-r--r--
Revision: 201039 Kit: 201041

/*
* 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 "mderelationcondition.h"
#include "mderelationdef.h"
#include "mdelogiccondition.h"
#include "mdscommoninternal.h"
#include "mdcserializationbuffer.h"
#include "mdcquery.h"

CMdERelationCondition* CMdERelationCondition::NewL( TItemId aRelationId,
		const RArray<TItemId>* aRelationIds, TRelationConditionSide aSide,
		const CMdERelationDef* aRelationDef, 
		const TMdEIntRange* aParameterRange )
	{
	CMdERelationCondition* self = CMdERelationCondition::NewLC(
			aRelationId, aRelationIds, aSide, aRelationDef, aParameterRange );
    CleanupStack::Pop( self );
    return self;
	}

CMdERelationCondition* CMdERelationCondition::NewLC( TItemId aRelationId,
		const RArray<TItemId>* aRelationIds, TRelationConditionSide aSide,
		const CMdERelationDef* aRelationDef, 
		const TMdEIntRange* aParameterRange )
	{
	CMdERelationCondition* self = new ( ELeave ) CMdERelationCondition( 
			aRelationId, aSide, aRelationDef );
    CleanupStack::PushL( self );
    self->ConstructL( aRelationIds, aParameterRange );
    return self;
	}

CMdERelationCondition::CMdERelationCondition( TItemId aRelationId, 
		TRelationConditionSide aSide, const CMdERelationDef* aRelationDef )
		: CMdECondition( EConditionTypeRelation ), iRelationId( aRelationId ),
		  iRelationDef( aRelationDef ), iSide( aSide )
	{
	iRelationIds = NULL;
	iParameterRange = NULL;
	iRightCondition = NULL;
	iLeftCondition = NULL;
	}

void CMdERelationCondition::ConstructL(const RArray<TItemId>* aRelationIds, 
		const TMdEIntRange* aParameterRange)
    {
    // Base class construction.
    ConditionConstruct();

    if( aRelationIds )
    	{
    	iRelationIds = new (ELeave) RArray<TItemId>();
    	
    	const TInt relationIdCount = aRelationIds->Count();
    	iRelationIds->ReserveL( relationIdCount );
    	
    	for( TInt i = 0; i < relationIdCount; i++ )
    		{
    		iRelationIds->AppendL( (*aRelationIds)[i] );
    		}
    	}

    if( aParameterRange )
        {
        // Make a copy of the parameter range.
        iParameterRange = new (ELeave) TMdEIntRange(*aParameterRange);
        }
    }

CMdERelationCondition::~CMdERelationCondition()
    {
   	delete iLeftCondition;
   	delete iRightCondition;
   	delete iParameterRange;
	delete iLastModifiedDateRange;

	if( iRelationIds )
		{
		iRelationIds->Close();
		delete iRelationIds;
		}
    }

EXPORT_C TItemId CMdERelationCondition::RelationId() const
    {   
    return iRelationId;
    }

EXPORT_C const RArray<TItemId>* CMdERelationCondition::RelationIds() const
	{   
	return iRelationIds;
	}

EXPORT_C const CMdERelationDef* CMdERelationCondition::RelationDef() const
    {   
    return iRelationDef;
    }

EXPORT_C CMdELogicCondition& CMdERelationCondition::LeftL()
    {
    if ( !iLeftCondition )
    	{
    	iLeftCondition = CMdELogicCondition::NewL(ELogicConditionOperatorAnd);
    	}
    
    return *iLeftCondition;
    }

EXPORT_C CMdELogicCondition& CMdERelationCondition::RightL()
    {
    if ( !iRightCondition )
    	{
    	iRightCondition = CMdELogicCondition::NewL(ELogicConditionOperatorAnd);
    	}

    return *iRightCondition;
    }

TRelationConditionSide CMdERelationCondition::Side() const
	{
	return iSide;
	}

EXPORT_C void CMdERelationCondition::SetSide(TRelationConditionSide aSide)
    {
    iSide = aSide;
    }


EXPORT_C const TMdEIntRange* CMdERelationCondition::ParameterRange() const
    {
    return iParameterRange;
    }

EXPORT_C void CMdERelationCondition::SetGuid(const TInt64& aGuidHigh, const TInt64& aGuidLow)
	{
	iGuidHigh = aGuidHigh;
	iGuidLow = aGuidLow;
	}

EXPORT_C TBool CMdERelationCondition::Guid(TInt64& aGuidHigh, TInt64& aGuidLow) const
	{
	if( iGuidHigh == 0 && iGuidLow == 0 )
		{
		return EFalse;
		}
	
	aGuidHigh = iGuidHigh;
	aGuidLow = iGuidLow;
	return ETrue;
	}

EXPORT_C void CMdERelationCondition::SetLastModifiedDateRangeL(const TMdETimeRange& aLastModifiedDateRange)
	{
	if( !iLastModifiedDateRange )
		{
		iLastModifiedDateRange = new (ELeave) TMdETimeRange( aLastModifiedDateRange );
		}
	}

EXPORT_C TBool CMdERelationCondition::LastModifiedDateRange(TMdETimeRange& aLastModifiedDateRange) const
	{
	if( iLastModifiedDateRange )
		{		
		aLastModifiedDateRange.SetType( iLastModifiedDateRange->Type() );
		aLastModifiedDateRange.SetMin( iLastModifiedDateRange->Min() );
		aLastModifiedDateRange.SetMax( iLastModifiedDateRange->Max() );
		return ETrue;
		}
	
	return EFalse;
	}

TUint32 CMdERelationCondition::InternalQueryOptimizationFlags(TUint32& aFlags)
	{
	aFlags |= EContainsRelationCondition;
	return EContainsRelationCondition;
	}

TUint32 CMdERelationCondition::RequiredBufferSize() const
	{
	TUint32 bufferSize = sizeof( TMdCRelationCondition );

	if( iRelationIds )
		{
		// count and IDs
		bufferSize += CMdCSerializationBuffer::KRequiredSizeForTUint32 + 
			iRelationIds->Count() * CMdCSerializationBuffer::KRequiredSizeForTItemId;
		}	

	if( iGuidHigh != 0 || iGuidLow != 0 )
		{
		bufferSize += 2 * CMdCSerializationBuffer::KRequiredSizeForTInt64;
		}

	if ( iParameterRange )
		{
		bufferSize += iParameterRange->RequiredBufferSize();
		}

	if ( iLeftCondition && iLeftCondition->Count() > 0 )
		{
		bufferSize += iLeftCondition->RequiredBufferSize();
		}

	if ( iRightCondition && iRightCondition->Count() > 0  )
		{
		bufferSize += iRightCondition->RequiredBufferSize();
		}

	if( iLastModifiedDateRange )
		{
		bufferSize += iLastModifiedDateRange->RequiredBufferSize();
		}

	return bufferSize;
	}

void CMdERelationCondition::SerializeL(CMdCSerializationBuffer& aBuffer,
		TMdCOffset& aFreespaceOffset) const
	{
	TMdCRelationCondition condition;

	condition.iConditionType = iType;
	condition.iNegated = iNegated;
	condition.iObjectSide = iSide;

	if( iRelationDef )
		{
		condition.iRelationDefId = iRelationDef->Id();
		}
	else
		{
		condition.iRelationDefId = KNoDefId;
		}

	condition.iRelationId = iRelationId;

	// updated later, if relation IDs exists
	condition.iRelationIds.iPtr.iCount = 0;
	condition.iRelationIds.iPtr.iOffset = KNoOffset;
	// updated later, if GUID exists
	condition.iGuid = KNoOffset;
	// updated later, if parameter range exists
	condition.iParameterRange = KNoOffset;
	// updated later, if left object condition exists
	condition.iLeftObjectCondition = KNoOffset;
	// updated later, if right object condition exists
	condition.iRightObjectCondition = KNoOffset;
	// updated later, if last modified date range exists
	condition.iLastModifiedDateRange = KNoOffset;

	const TUint32 conditionOffset = aBuffer.Position();

	// get position after condition
	aFreespaceOffset = conditionOffset + sizeof( TMdCRelationCondition );
	aBuffer.PositionL( aFreespaceOffset );

	if( iRelationIds )
		{
		condition.iRelationIds.iPtr.iCount = iRelationIds->Count();
		condition.iRelationIds.iPtr.iOffset = aFreespaceOffset;
		
		const TInt relationIdCount = iRelationIds->Count();
		for( TInt i = 0; i < relationIdCount; i++ )
			{
			const TItemId relationId = (*iRelationIds)[i];
			aBuffer.InsertL( relationId );
			}
		
		aFreespaceOffset = aBuffer.Position();
		}
	
	if( iGuidHigh != 0 || iGuidLow != 0 )
		{
		condition.iGuid = aFreespaceOffset;

		aBuffer.InsertL( iGuidHigh );
		aBuffer.InsertL( iGuidLow );
		
		aFreespaceOffset = aBuffer.Position();
		}

	if ( iParameterRange )
		{
		condition.iParameterRange = aFreespaceOffset;

		iParameterRange->SerializeL( aBuffer );

		aFreespaceOffset = aBuffer.Position();
		}

	if ( iLeftCondition && iLeftCondition->Count() > 0  )
		{
		condition.iLeftObjectCondition = aFreespaceOffset;

		iLeftCondition->SerializeL( aBuffer, aFreespaceOffset );

		aFreespaceOffset = aBuffer.Position();
		}

	if ( iRightCondition && iRightCondition->Count() > 0  )
		{
		condition.iRightObjectCondition = aFreespaceOffset;

		iRightCondition->SerializeL( aBuffer, aFreespaceOffset );

		aFreespaceOffset = aBuffer.Position();
		}

	if ( iLastModifiedDateRange )
		{
		condition.iLastModifiedDateRange = aFreespaceOffset;

		iLastModifiedDateRange->SerializeL( aBuffer );

		aFreespaceOffset = aBuffer.Position();
		}

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