--- /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;
+ }
+
+
+