contextframework/cfw/src/basicoperationsplugin/cfcontextoperationutils.cpp
changeset 0 2e3d3ce01487
--- /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 <gmxmlelement.h>
+#include <gmxmltext.h>
+#include <f32file.h> // 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;
+    }