diff -r 000000000000 -r 2e3d3ce01487 contextframework/cfw/src/basicoperationsplugin/cfcontextoperationutils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contextframework/cfw/src/basicoperationsplugin/cfcontextoperationutils.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,457 @@ +/* +* Copyright (c) 2007-2007 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: CFContextOperationUtils class implementation. +* +*/ + + + +// INCLUDES +#include +#include +#include // For delimiter definitions. + +#include "cfcontextoperationutils.h" +#include "cfbasicoptrace.h" + +// CONSTANTS +_LIT( KScriptContextRefName, "contextRef" ); + +_LIT( KScriptCepInt, "cep:int" ); +_LIT( KScriptInt, "int" ); +_LIT( KScriptCepString, "cep:string" ); +_LIT( KScriptString, "string" ); +_LIT( KScriptCepFloat, "cep:double" ); +_LIT( KScriptFloat, "double" ); +_LIT( KScriptCepPosition, "cep:position" ); +_LIT( KScriptCepDate, "cep:date" ); +_LIT( KScriptDate, "date" ); + +_LIT( KScriptSourceAttribute, "source" ); +_LIT( KScriptTypeAttribute, "type" ); +_LIT( KScriptValueAttribute, "value" ); +_LIT( KScriptEvaluationDelayAttribute, "evaluationDelay" ); + +// ======== MEMBER FUNCTIONS ======== + +// ----------------------------------------------------------------------------- +// CFContextOperationUtils::ParseTwoComparisonArgs +// ----------------------------------------------------------------------------- +// +TBool CFContextOperationUtils::ParseTwoComparisonArgs( CMDXMLNode& aNode, + TPtrC& aContextSource, + TPtrC& aContextType, + CCFContextOperation::TCmpType& aCompareType, + TPtrC& aCompareValue, + TInt& aContextLevelDelay ) + { + FUNC_LOG; + + TPtrC contextValue; + TBool contextRefOK( EFalse ); + TBool comparisonTypeValueOK( EFalse ); + TBool argsOK( ETrue ); // Will be set to false if unknown nodes detected. + CMDXMLNode* child = aNode.FirstChild(); + while ( child ) + { + if ( child->NodeType() == CMDXMLNode::EElementNode ) + { + if ( child->NodeName().CompareF( KScriptContextRefName ) == 0 ) + { + if ( !contextRefOK ) + { + contextRefOK = CFContextOperationUtils::ParseContextRef( + *child, + aContextSource, + aContextType, + contextValue, + aContextLevelDelay ); + if ( !contextRefOK ) + { + argsOK = EFalse; + break; + } + } + else + { + INFO( "CFContextOperationUtils::ParseTwoComparisonArgs - Redefinition not allowed, context ref already defined" ); + argsOK = EFalse; + break; + } + } + else + { + if ( !comparisonTypeValueOK ) + { + comparisonTypeValueOK + = CFContextOperationUtils::ParseComparisonTypeValue( + *child, + aCompareType, + aCompareValue ); + if ( !comparisonTypeValueOK ) + { + argsOK = EFalse; + break; + } + } + else + { + INFO( "CFContextOperationUtils::ParseTwoComparisonArgs - Redefinition not allowed, comparison type value already defined" ); + argsOK = EFalse; + break; + } + } + } + else if ( child->NodeType() != CMDXMLNode::ECommentNode ) + { + TPtrC nodeName( child->NodeName() ); + INFO_1( "CFContextOperationUtils::ParseTwoComparisonArgs - Unsupported node [%S]", + &nodeName ); + argsOK = EFalse; + break; + } + child = child->NextSibling(); + } + + TBool parsed( EFalse ); + if ( argsOK && contextRefOK ) + { + if ( ( comparisonTypeValueOK && !contextValue.Length() ) + || ( !comparisonTypeValueOK && contextValue.Length() ) ) + { + if ( !comparisonTypeValueOK ) + { + aCompareType = CCFContextOperation::EStringCmp; + aCompareValue.Set( contextValue ); + } + parsed = ETrue; + } + else + { + if ( !comparisonTypeValueOK ) + { + INFO( "CFContextOperationUtils::ParseTwoComparisonArgs - Value to compare the context with not defined" ); + } + else + { + INFO( "CFContextOperationUtils::ParseTwoComparisonArgs - Ambiguous, value to compare the context with defined twice" ); + } + } + } + + return parsed; + } + +// ----------------------------------------------------------------------------- +// CFContextOperationUtils::ParseContextRef +// ----------------------------------------------------------------------------- +// +TBool CFContextOperationUtils::ParseContextRef( CMDXMLNode& aNode, + TPtrC& aContextSource, + TPtrC& aContextType, + TPtrC& aContextValue, + TInt& aContextLevelDelay ) + { + FUNC_LOG; + + if ( aNode.NodeName().CompareF( KScriptContextRefName ) != 0 + || aNode.NodeType() != CMDXMLNode::EElementNode ) + { + return EFalse; // Cannot parse context ref from the given node. + } + + TBool contextRefOK( EFalse ); + CMDXMLElement& element = static_cast< CMDXMLElement& >( aNode ); + TPtrC evaluationDelay; + if ( KErrNone == element.GetAttribute( KScriptSourceAttribute, + aContextSource ) ) + { + if ( KErrNone == element.GetAttribute( KScriptTypeAttribute, + aContextType ) ) + { + if ( aContextSource.Length() && aContextType.Length() + && !element.HasChildNodes() ) + { + contextRefOK = ETrue; + TInt numAttributes( 2 ); // Two attributes read so far. + TPtrC evaluationDelay; + // Extract context level evaluation delay if defined. + if ( KErrNone == element.GetAttribute( + KScriptEvaluationDelayAttribute, + evaluationDelay ) ) + { + ++numAttributes; + if ( evaluationDelay.Length() ) + { + // Convert delay to integer. + TLex parseInt( evaluationDelay ); + parseInt.SkipSpace(); + TInt contextLevelDelay( 0 ); + TInt err = parseInt.Val( contextLevelDelay ); + if ( err != KErrNone || contextLevelDelay < 0 ) + { + // Evaluation delay defined but invalid. + contextRefOK = EFalse; + } + else if ( contextLevelDelay > 0 ) + { + aContextLevelDelay = contextLevelDelay; + } + } + } + // Extract context value if defined. + if ( KErrNone != element.GetAttribute( KScriptValueAttribute, + aContextValue ) ) + { + // Ensure empty value when it is not defined. + aContextValue.Set( 0, 0 ); + } + else + { + ++numAttributes; + } + + if ( numAttributes != element.NumAttributes() ) + { + INFO( "CFContextOperationUtils::ParseContextRef - Unsupported amount of attributes" ); + contextRefOK = EFalse; // Unsupported contextRef. + } + } + else + { + INFO( "CFContextOperationUtils::ParseContextRef - Unsupported context ref" ); + } + } + else + { + INFO( "CFContextOperationUtils::ParseContextRef - Getting type failed" ); + } + } + else + { + INFO( "CFContextOperationUtils::ParseContextRef - Getting source failed" ); + } + + return contextRefOK; + } + +// ----------------------------------------------------------------------------- +// CFContextOperationUtils::ParseComparisonTypeValue +// ----------------------------------------------------------------------------- +// +TBool CFContextOperationUtils::ParseComparisonTypeValue( CMDXMLNode& aNode, + CCFContextOperation::TCmpType& aCompareType, + TPtrC& aCompareValue ) + { + FUNC_LOG; + + TBool parsed( EFalse ); + if ( aNode.NodeType() == CMDXMLNode::EElementNode ) + { + aCompareType + = CFContextOperationUtils::ComparisonType( aNode.NodeName() ); + + if ( aCompareType != CCFContextOperation::EInvalidCmpType ) + { + // Parse comparison value from first text node child. + CMDXMLNode* child = aNode.FirstChild(); + while ( child ) + { + // Allow one text node and multiple comments, nothing else. + if ( child->NodeType() == CMDXMLNode::ETextNode ) + { + if ( parsed ) + { + TPtrC nodeName( child->NodeName() ); + INFO_1( "CFContextOperationUtils::ParseComparisonTypeValue - One definition is allowed. [%S] is not supported", + &nodeName ); + // Already parsed, flag inability to parse. + parsed = EFalse; + break; + } + CMDXMLText* text = static_cast< CMDXMLText* >( child ); + aCompareValue.Set( text->Data() ); + parsed = ETrue; + } + else if ( child->NodeType() != CMDXMLNode::ECommentNode ) + { + TPtrC nodeName( child->NodeName() ); + INFO_1( "CFContextOperationUtils::ParseComparisonTypeValue - Unsupported node [%S]", + &nodeName ); + parsed = EFalse; + break; + } + child = child->NextSibling(); + } + } + else + { + INFO( "CFContextOperationUtils::ParseComparisonTypeValue - Invalid comparison type" ); + } + } + else + { + TPtrC nodeName( aNode.NodeName() ); + INFO_1( "CFContextOperationUtils::ParseComparisonTypeValue - Unsupported node [%S]", + &nodeName ); + } + + return parsed; + } + +// ----------------------------------------------------------------------------- +// CFContextOperationUtils::ComparisonType +// ----------------------------------------------------------------------------- +// +CCFContextOperation::TCmpType CFContextOperationUtils::ComparisonType( + const TDesC& aComparisonType ) + { + FUNC_LOG; + + CCFContextOperation::TCmpType ret( CCFContextOperation::EInvalidCmpType ); + + if ( aComparisonType.CompareF( KScriptCepInt ) == 0 || + aComparisonType.CompareF( KScriptInt ) == 0 ) + { + ret = CCFContextOperation::EIntCmp; + } + else if ( aComparisonType.CompareF( KScriptCepDate ) == 0 || + aComparisonType.CompareF( KScriptDate ) == 0 ) + { + ret = CCFContextOperation::ETimeCmp; + } + else if ( aComparisonType.CompareF( KScriptCepPosition ) == 0 ) + { + ret = CCFContextOperation::EPositionCmp; + } + else if ( aComparisonType.CompareF( KScriptCepString ) == 0 || + aComparisonType.CompareF( KScriptString ) == 0 ) + { + ret = CCFContextOperation::EStringCmp; + } + else if ( aComparisonType.CompareF( KScriptCepFloat ) == 0 || + aComparisonType.CompareF( KScriptFloat ) == 0 ) + { + ret = CCFContextOperation::EFloatCmp; + } + + return ret; + } + + +// --------------------------------------------------------------------------- +// CFContextOperationUtils::StringToTimeL +// --------------------------------------------------------------------------- +// +TTime CFContextOperationUtils::StringToTimeL( const TDesC& aString ) + { + FUNC_LOG; + + TTime val; + TInt err = val.Set( aString ); + if ( err != KErrNone ) + { + ERROR_1( err, "Cannot interpret string as TTime. Value: %S", &aString ); + User::Leave( err ); + } + + return val; + } + +// --------------------------------------------------------------------------- +// CFContextOperationUtils::StringToRealL +// --------------------------------------------------------------------------- +// +TReal CFContextOperationUtils::StringToRealL( const TDesC& aString ) + { + FUNC_LOG; + + TLex lexer( aString ); + TInt err( KErrNone ); + TReal val( 0 ); + TChar decPoint( KExtDelimiter ); // '.' + + // Parse float from string; note that decimal point delimiter must be '.' + err = lexer.Val( val, decPoint ); + if ( err != KErrNone ) + { + ERROR_1( err, "Cannot interpret string as float. Value: %S", &aString ); + User::Leave( err ); + } + + return val; + } + +// --------------------------------------------------------------------------- +// CFContextOperationUtils::PositionToRealsL +// Converts a string containing latitude and longitude values into two real +// values passed by reference. +// --------------------------------------------------------------------------- +// +void CFContextOperationUtils::PositionToRealsL( const TDesC& aString, + TReal& aLatitude, + TReal& aLongitude ) + { + FUNC_LOG; + + TLex lexer( aString ); + TBuf< KMaxName > latDes( KErrNone ); + TBuf< KMaxName > lonDes( KErrNone ); + TChar posDelimiter( KDriveDelimiter ); // ':' + + // Get the latitude to descriptor. + while ( lexer.Peek() != posDelimiter && // Delimiter char not found. + !lexer.Eos() ) // End of string not reached. + { + latDes.Append( lexer.Get() ); + } + + if ( lexer.Eos() || // Eos already. + lexer.Peek() != posDelimiter ) // Delimiter not found. + { + ERROR_GEN_1( "Cannot interpret position as floats. String: %S", &aString ); + User::Leave( KErrBadDescriptor ); + } + + // Skip over delimiter. + lexer.Inc(); + + // Get the longitude to descriptor. + while ( !lexer.Eos() ) + { + latDes.Append( lexer.Get() ); + } + // Parse latitude and longitude into given reals. + aLatitude = StringToRealL( latDes ); + aLongitude = StringToRealL( lonDes ); + } + +// --------------------------------------------------------------------------- +// CFContextOperationUtils::StringToIntL +// --------------------------------------------------------------------------- +// +TInt CFContextOperationUtils::StringToIntL( const TDesC& aString ) + { + FUNC_LOG; + + TLex lexer( aString ); + TInt val( KErrNone ); + TInt err = lexer.Val( val ); + if ( err != KErrNone ) + { + ERROR_1( err, "Cannot interpret string as int. Value: %S", &aString ); + User::Leave( err ); + } + return val; + }