webservices/wsxml/src/senfilterstatemachine.cpp
changeset 0 62f9d29f7211
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsxml/src/senfilterstatemachine.cpp	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,430 @@
+/*
+* Copyright (c) 2005 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:      
+*
+*/
+
+
+
+
+
+
+
+
+#include "SenFilterCondition.h"
+
+#include "SenFilterStateMachine.h"
+
+#include "SenDebug.h"
+#include "SenLogger.h"
+
+
+_LIT(KLogFileDir, "WsLog");
+_LIT(KLogFileName, "SenXml.log");
+
+// ----------------------------------------------
+//
+// Implementation of class CSenFilterStateMachine
+//
+// ----------------------------------------------
+
+
+EXPORT_C CSenFilterStateMachine::CSenFilterStateMachine()
+: iStateTable(ETrue, ETrue)
+{
+    TLSLOG_OPEN(KSenXmlLogChannel, KSenXmlLogLevel, KSenXml, KSenXmlLog);
+    TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel , _L8("CSenFilterStateMachine::CSenFilterStateMachine(): Log opened"));
+
+    iStates = 0;
+    iFilterState = 0;
+
+		TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel ,  _L8("CSenFilterStateMachine::CSenFilterStateMachine(): End"));
+} 
+
+
+EXPORT_C CSenFilterStateMachine::~CSenFilterStateMachine()
+{
+    iStateTable.Reset();
+
+    // Close the log file and the connection to the server.
+  	TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel ,  (_L("Log file closed.")));
+		TLSLOG_CLOSE(KSenXmlLogChannel);
+}
+
+
+/* Add a node to the state tree */
+EXPORT_C CSenFilterStateNode* 
+CSenFilterStateMachine::AddChildLC(CSenFilterStateNode& aStartState,
+                                 const TDesC8& aEvent, 
+                                 const CSenFilterCondition& aCondition,
+                                 MSenFilterAction& aStartAction,
+                                 MSenFilterAction& aEndAction)
+{
+    CSenFilterStateNode* newNode = new CSenFilterStateNode(aEvent, 
+                                                           aCondition, 
+                                                           aStartAction, 
+                                                           aEndAction, 
+                                                           *this);
+
+    CleanupStack::PushL(newNode);
+    newNode->SetParent(aStartState);
+
+    // Array takes care of memory deallocation
+    aStartState.Children().Append(newNode);
+
+    return newNode;
+}
+
+
+/* Add the root node to the state tree */
+EXPORT_C CSenFilterStateNode* 
+CSenFilterStateMachine::AddParentLC(const TDesC8& aEvent, 
+                                 const CSenFilterCondition& aCondition,
+                                 MSenFilterAction& aStartAction,
+                                 MSenFilterAction& aEndAction)
+{
+    CSenFilterStateNode* newNode = new CSenFilterStateNode(aEvent,
+                                                           aCondition, 
+                                                           aStartAction, 
+                                                           aEndAction, 
+                                                           *this);
+    CleanupStack::PushL(newNode);
+    return newNode;
+}
+
+
+/* Recursively compile the tree into a state table */
+EXPORT_C void CSenFilterStateMachine::CompileL(CSenFilterStateNode& aStartNode)
+{
+    TInt p = 0; // initial state
+
+    p = aStartNode.Parent().State();
+
+    AddEntryL(p, 
+             aStartNode.Event(), 
+             aStartNode.Condition(), 
+             aStartNode.State(), 
+             aStartNode.StartAction(), 
+             aStartNode.EndAction());
+
+    TInt count = aStartNode.Children().Count();
+    for ( TInt i=0; i < count; i++ )
+    {
+        CSenFilterStateNode* node = (aStartNode.Children())[i];
+        CompileL(*node);
+    }
+}
+
+
+EXPORT_C void CSenFilterStateMachine::StartElementL(const TDesC8& aName, 
+                                                    const RAttributeArray& aAttributes)
+{
+    TransitionL(iFilterState, aName, (TInt)EStart, aAttributes);
+}
+
+
+EXPORT_C void CSenFilterStateMachine::EndElementL(const TDesC8& aName)
+{
+    RAttributeArray attrs;
+    TransitionL(iFilterState, aName, (TInt)EEnd, attrs);
+}
+
+
+
+const TInt CSenFilterStateMachine::RegisterState()
+{
+    return ++iStates;
+}
+
+
+const TInt CSenFilterStateMachine::States() const
+{
+    return iStates;
+}
+
+
+void CSenFilterStateMachine::AddEntryL(TInt aInitialState, 
+                                      const TDesC8& aEvent, 
+                                      const CSenFilterCondition& aCondition, 
+                                      TInt aNextState, 
+                                      MSenFilterAction& aStartAction, 
+                                      MSenFilterAction& aEndAction)
+{
+    CSenFilterTableEntry *entry = NULL;
+    TUint16 c;
+
+
+    // Start node
+    c = GetStateKeyL(aInitialState, 
+                    aEvent, 
+                    (TInt)EStart);
+
+    entry = new CSenFilterTableEntry(aNextState, 
+                                     aCondition, 
+                                     aStartAction);
+    CleanupStack::PushL(entry);
+
+    // Map takes care of memory deallocation
+    iStateTable.Append(&c, entry);
+
+    CleanupStack::Pop(); // entry
+
+    // End node
+    c = GetStateKeyL(aNextState, 
+                    aEvent, 
+                    (TInt)EEnd);
+
+    entry = new CSenFilterTableEntry(aInitialState, 
+                                     aCondition, 
+                                     aEndAction);
+    CleanupStack::PushL(entry);
+
+    // Map takes care of memory deallocation
+    iStateTable.Append(&c, entry);
+
+    CleanupStack::Pop(); // entry
+
+}
+
+
+// Create an unique key for state table node
+const TUint16 CSenFilterStateMachine::GetStateKeyL(TInt aState, 
+                                                  const TDesC8& aEvent, 
+                                                  TInt aStart)
+{
+    TUint16 ret = 0;
+    TInt intMaxLen = 32;
+
+    TInt bufLen = aEvent.Size() + (2 * intMaxLen);
+    HBufC8* buf = HBufC8::NewLC(bufLen);
+    TPtr8 bufPtr = (buf->Des());
+    bufPtr.Append(aEvent);
+    bufPtr.AppendNum(aState);
+    bufPtr.AppendNum(aStart);
+
+    Mem::Crc(ret, (TAny *)bufPtr.Ptr(), bufPtr.Size());
+
+    CleanupStack::PopAndDestroy(); // buf
+
+    return(ret);
+}
+
+
+const TInt CSenFilterStateMachine::TransitionL(TInt aState, 
+                                              const TDesC8& aEvent, 
+                                              TInt start, 
+                                              const RAttributeArray& aAttributes)
+{
+
+    TUint16 c = GetStateKeyL(aState, aEvent, start);
+    TInt i = iStateTable.Find(c);
+    if ( KErrNotFound != i ) {
+        const CSenFilterTableEntry* entry = iStateTable.ValueAt(i);
+        if ( entry != NULL )
+        {
+            // Evaluate conditions
+            if ( !entry->Condition().Test() )
+            {
+                return iFilterState;
+            }
+            //Perform action
+            entry->Action().PerformL(aEvent, aAttributes);
+    
+            // Make the state transition
+            iFilterState = entry->NewState();
+        }
+    }
+    return iFilterState;
+}
+
+
+RFileLogger* CSenFilterStateMachine::Log() const
+    {
+    return (RFileLogger*) &iLog;
+    }
+
+
+// -------------------------------------
+//
+// Implementation of class CSenFilterStateNode
+//
+// -------------------------------------
+
+
+EXPORT_C CSenFilterStateNode::CSenFilterStateNode(const TDesC8& aEvent, 
+                                                  const CSenFilterCondition& aCondition, 
+                                                  MSenFilterAction& aStartAction, 
+                                                  MSenFilterAction& aEndAction,
+                                                  CSenFilterStateMachine& aStateMachine)
+: ipPrev(NULL),
+  iEvent(aEvent),
+  iCondition(aCondition),
+  iStartAction(aStartAction),
+  iEndAction(aEndAction)
+{
+    TLSLOG_OPEN(KSenXmlLogChannel, KSenXmlLogLevel, KSenXml, KSenXmlLog);
+    TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel , _L8("CSenFilterStateNode::CSenFilterStateNode(): Log opened"));
+
+    iState = aStateMachine.RegisterState();
+
+    TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel , _L8("CSenFilterStateNode::CSenFilterStateNode(): End"));
+} 
+
+
+EXPORT_C CSenFilterStateNode::CSenFilterStateNode(const CSenFilterStateNode& aFilterStateNode)
+: ipPrev(NULL),
+  iEvent(aFilterStateNode.Event()),
+  iCondition(aFilterStateNode.Condition()),
+  iStartAction(aFilterStateNode.StartAction()),
+  iEndAction(aFilterStateNode.EndAction())
+{
+    TLSLOG_OPEN(KSenXmlLogChannel, KSenXmlLogLevel, KSenXml, KSenXmlLog);
+    TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel , _L8("CSenFilterStateNode::CSenFilterStateNode(): Log opened"));
+
+    iState = aFilterStateNode.State();
+    
+
+    if (NULL != aFilterStateNode.ipPrev)
+    {
+        ipPrev = new CSenFilterStateNode(aFilterStateNode.Parent());
+    }
+    
+    for (TInt i = 0; i < aFilterStateNode.Children().Count(); i++)
+    {
+        iChildren.Append((const_cast<CSenFilterStateNode>(aFilterStateNode).Children())[i]);
+    }
+
+    TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel , _L8("CSenFilterStateNode::CSenFilterStateNode(): End"));
+}
+
+
+EXPORT_C CSenFilterStateNode::~CSenFilterStateNode()
+{
+    iChildren.ResetAndDestroy();
+
+    // Close the log file and the connection to the server.
+    TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel , _L("Log file closed."));
+ 		TLSLOG_CLOSE(KSenXmlLogChannel);
+}
+
+
+EXPORT_C TInt CSenFilterStateNode::State() const
+{
+    return iState;
+}
+
+
+EXPORT_C TDesC8 CSenFilterStateNode::Event() const
+{
+    return iEvent;
+}
+
+
+EXPORT_C CSenFilterCondition CSenFilterStateNode::Condition() const
+{
+    return iCondition;
+}
+
+
+EXPORT_C MSenFilterAction& CSenFilterStateNode::StartAction() const
+{
+    return iStartAction;
+}
+
+
+EXPORT_C MSenFilterAction& CSenFilterStateNode::EndAction() const
+{
+    return iEndAction;
+}
+
+
+EXPORT_C CSenFilterStateNode& CSenFilterStateNode::Parent() const
+{
+    return *ipPrev;
+}
+
+
+EXPORT_C RStateNodeArray CSenFilterStateNode::Children() const
+{
+    return iChildren;
+}
+
+
+EXPORT_C void CSenFilterStateNode::SetParent(CSenFilterStateNode& aNode)
+{
+    ipPrev = &aNode;
+}
+
+
+RFileLogger* CSenFilterStateNode::Log() const
+    {
+    return (RFileLogger*) &iLog;
+    }
+
+
+// --------------------------------------
+//
+// Implementation of class CSenFilterTableEntry
+//
+// --------------------------------------
+
+
+CSenFilterTableEntry::CSenFilterTableEntry(TInt aNewState, 
+                                           const CSenFilterCondition& aCondition,
+                                           MSenFilterAction& aAction)
+: iAction(aAction),
+  iCondition(aCondition)
+{
+    TLSLOG_OPEN(KSenXmlLogChannel, KSenXmlLogLevel, KSenXml, KSenXmlLog);
+    TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel , _L8("CSenFilterTableEntry::CSenFilterTableEntry(): Log opened"));
+
+    iNewState = aNewState;
+
+    TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel , _L8("CSenFilterTableEntry::CSenFilterTableEntry(): End"));
+}
+
+
+CSenFilterTableEntry::~CSenFilterTableEntry()
+{
+    // Close the log file and the connection to the server.
+    TLSLOG(KSenXmlLogChannel  , KSenXmlLogLevel , _L("Log file closed."));
+		TLSLOG_CLOSE(KSenXmlLogChannel);
+}
+
+
+TInt CSenFilterTableEntry::NewState() const
+{
+    return iNewState;
+}
+
+
+CSenFilterCondition CSenFilterTableEntry::Condition() const
+{
+    return iCondition;
+}
+
+
+MSenFilterAction& CSenFilterTableEntry::Action() const
+{
+    return iAction;
+}
+
+
+RFileLogger* CSenFilterTableEntry::Log() const
+    {
+    return (RFileLogger*) &iLog;
+    }
+
+
+