testexecfw/useremul/src/XmlHandler.cpp
changeset 0 3e07fef1e154
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecfw/useremul/src/XmlHandler.cpp	Mon Mar 08 15:03:44 2010 +0800
@@ -0,0 +1,791 @@
+/*------------------------------------------------------------------
+ -
+ * Software Name : UserEmulator
+ * Version       : v4.2.1309
+ * 
+ * Copyright (c) 2009 France Telecom. All rights reserved.
+ * This software is distributed under the License 
+ * "Eclipse Public License - v 1.0" the text of which is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * France Telecom 
+ *
+ * Contributors:
+ *------------------------------------------------------------------
+ -
+ * File Name: XmlHandler.cpp
+ * 
+ * Created: 13/08/2009
+ * Author(s): Marcell Kiss, Reshma Sandeep Das
+ *   
+ * Description:
+ * XML Parser implementation
+ * There are two methods to parse XML document, i.e.;
+ *   - StartParsingL() -> parse XML document without active object.
+ *   - StartParsingWithAoL() -> parse XML document with active object.
+ *------------------------------------------------------------------
+ -
+ *
+ */
+
+// System Includes
+#include <coemain.h>
+#include <f32file.h>
+#include <eikenv.h>
+#include <xml/parserfeature.h>
+#include <utf.h>
+#include <aknnotewrappers.h>
+#include <coecntrl.h>
+
+// User Includes
+#include <UserEmulator_0x2001C3AF.rsg>
+#include "XmlHandler.h"
+#include "Utils.h"
+#include "UserEmulatorAppUi.h"
+
+//Constants
+/**
+ * XML Tags
+ */
+_LIT8(KAction,"action");
+_LIT8(KName,"name");
+_LIT8(KType,"type");
+_LIT8(KParams,"params");
+_LIT8(KPrintLog,"print");
+_LIT8(KKeys,"keys");
+_LIT8(KLoop,"loop");
+_LIT8(KCount,"count");
+_LIT8(KScreenShot,"screenshot");
+
+/**
+ * Action Types
+ */
+_LIT( KParamActionsApp, "app" );
+_LIT( KParamActionsView, "view" );
+_LIT( KParamActionsJavaApp, "javaapp" );
+_LIT( KParamActionsWait, "wait" );
+_LIT( KParamActionsOrient, "orientation" );
+_LIT( KParamActionsScreenReset, "screenreset" );
+_LIT( KParamActionsPointerEvent, "pointerevent" );
+_LIT( KParamActionsKeyPress, "keypress" );
+_LIT( KParamCloseApp, "closeapp");
+_LIT( KParamActionsLoop, "loop");
+_LIT( KParamActionsLoopEnd, "loopend");
+
+/**
+ * Keys
+ */
+_LIT(KLeftSoftKey,"LSK");
+_LIT(KRightSoftKey,"RSK");
+_LIT(KMiddleSoftKey,"MSK");
+_LIT(KDownArrowKey,"DAK");
+_LIT(KUpArrowKey,"UAK");
+_LIT(KRightArrowKey,"RAK");    		
+_LIT(KLeftArrowKey,"LAK");
+_LIT(KKeySpace,"SP");
+_LIT(KKeyBackSpace,"BS");
+_LIT(KKeyGreaterThan, "gt");
+_LIT(KKeyAmpersand,"amp");
+_LIT(KKeyLessThan,"lt");
+_LIT(KKeyOkKey,"OK");
+_LIT(KKeyMenu,"MENU"); //EAKeyApplication0
+_LIT(KKeyYes,"KYES"); //EKeyYes
+_LIT(KKeyNo,"KNO"); //EKeyNo
+_LIT(KKeyCamera,"CAM");
+_LIT(KKeyHash,"#");
+
+/**
+ * General Constants
+ */
+_LIT(KOpeningTag, "<" );
+_LIT(KClosingTag, ">" );
+_LIT(KSlash,      "/" );
+_LIT(KEndOfLine,  "\f" ); // CEikEdwin uses '\f' as EOF mark.
+
+_LIT(KF842,"0xF842"); 
+_LIT(KF843,"0xF843");              
+_LIT(Ka7,"0xa7");                
+_LIT(KF80A,"0xF80A");              
+_LIT(KF809,"0xF809");               
+_LIT(KF808,"0xF808");               
+_LIT(KF807,"0xF807");               
+_LIT(K0008,"0x0008");               
+_LIT(K0020,"0x0020");
+_LIT(K0026,"0x0026");
+_LIT(K003C,"0x003C");
+_LIT(K003E,"0x003E");
+_LIT(KF852,"0xF852");
+_LIT(KF862,"0xF862");
+_LIT(KF863,"0xF863");
+_LIT(KF893,"0xF893");
+
+
+_LIT8(KXmlMimeType, "text/xml" );
+
+const TInt KMaxFileNameLength=200;
+
+
+// METHODS DEFINITION
+// -----------------------------------------------------------------------------
+// CXmlHandler::NewL
+// Creates the instance of class and returns it.
+// -----------------------------------------------------------------------------
+//
+
+CXmlHandler* CXmlHandler::NewL( MXmlHandlerObserver& aObserver, RPointerArray<CAction>& aActionList)
+    {
+    CXmlHandler* self = CXmlHandler::NewLC( aObserver ,aActionList);
+    CleanupStack::Pop();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::NewLC
+// Creates the instance of class and pushes it to the CleanupStack and return
+// it.
+// -----------------------------------------------------------------------------
+//
+CXmlHandler* CXmlHandler::NewLC( MXmlHandlerObserver& aObserver ,
+								 RPointerArray<CAction>& aActionList)
+    {
+    CXmlHandler* self = new ( ELeave ) CXmlHandler( aObserver, aActionList);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::~CXmlHandler
+// Cancels any outstanding requests and deletes members.
+// -----------------------------------------------------------------------------
+//
+CXmlHandler::~CXmlHandler()
+{
+    Cancel();
+    delete iParser;
+    delete iDisplayResult;
+    delete iBuffer;
+    delete iContent; 
+    iContent=NULL;
+}
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::CXmlHandler
+// Calls base classes constructor with priority value. Add class to the 
+// active sheduler.
+// -----------------------------------------------------------------------------
+//
+CXmlHandler::CXmlHandler( MXmlHandlerObserver& aObserver ,RPointerArray<CAction>& aActionList)
+    :CActive( EPriorityStandard ),
+    iObserver( aObserver ),
+    iParser( 0 ),
+    iDisplayResult( 0 ),
+    iState( EIdle ),
+    iActionList(aActionList),
+    iActionListIndex(0)
+{
+	iIndex = 0;
+   
+    CActiveScheduler::Add( this );
+}
+// -----------------------------------------------------------------------------
+// CXmlHandler::DoCancel
+// From CActive. Cancels any outstanding request according the engine state.
+// -----------------------------------------------------------------------------
+//
+void CXmlHandler::DoCancel()
+{
+	TRAP_IGNORE(iParser->ParseEndL());
+	iFile.Close();
+	delete iBuffer;
+	iBuffer = 0;
+}
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::RunL
+// From CActive. Handles the state changes and notifing the observer.
+// -----------------------------------------------------------------------------
+//
+void CXmlHandler::RunL()
+    {
+    if ( KErrNone == iStatus.Int() )
+        {
+        // If the buffer length is zero, it means we have reached
+        // the end of the file.
+        if ( iBuffer->Length() == 0)
+            {
+            iParser->ParseEndL();
+            iFile.Close();
+            delete iBuffer;
+            iBuffer = 0;
+            }
+            
+        // Otherwise, we continue reading the next chunk of the XML file.
+        else
+            {
+            // Parse the next "part" of the XML document.
+            iParser->ParseL( *iBuffer );
+            
+            // Read the next chunk of the file.
+            TPtr8 bufferPtr( iBuffer->Des() );
+            iFile.Read( bufferPtr, KBuffer1024, iStatus );
+            
+            // Don't forget to call this..
+            SetActive();
+            }
+        }
+    else
+        {
+        iObserver.OnParseCompletedL( iStatus.Int(), iState );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::ConstructL
+// Construction of parser and buffer allocations
+// -----------------------------------------------------------------------------
+//
+void CXmlHandler::ConstructL()
+    {
+    iDisplayResult = HBufC::NewL( KBuffer1024 );
+    iContent = HBufC8::NewL(KBuffer128);
+    }
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::StartParsingL
+// Function to start parsing the XML script without active object
+// -----------------------------------------------------------------------------
+//   
+TInt CXmlHandler::StartParsingL( const TDesC& aFileName )
+    {
+    // If file name is too long then don't parse it just mark it as a failed script
+    TInt pos=aFileName.LocateReverse('\\');
+    if(aFileName.Right(aFileName.Length()-pos).Length()>KMaxFileNameLength)
+        {
+        TRAPD(err, iObserver.OnParseCompletedL( KErrGeneral,EOnError ));
+        return err;
+        }
+    
+    RFile file;
+    User::LeaveIfError( file.Open( CCoeEnv::Static()->FsSession(), aFileName,
+        EFileRead ) );
+    CleanupClosePushL( file );
+    
+    iDisplayResult->Des().Zero();
+    TInt size;
+    User::LeaveIfError( file.Size( size ) );
+    delete iBuffer;
+    iBuffer = 0;
+    iBuffer = HBufC8::NewL( size );
+    TPtr8 bufferPtr( iBuffer->Des() );
+    User::LeaveIfError( file.Read( bufferPtr ) );
+    
+    file.Close();
+    CleanupStack::PopAndDestroy(); // file
+    
+    delete iParser;
+    iParser= NULL;
+    iParser = CParser::NewL( KXmlMimeType, *this );
+    
+    iActionListIndex = iActionList.Count();
+    TRAPD(err,iParser->ParseBeginL());
+    if(err!=KErrNone)
+        return err;
+    TRAPD(err1,iParser->ParseL( *iBuffer ));
+    if(err1!=KErrNone)
+        return err1;
+    TRAPD(err2,iParser->ParseEndL());
+    if(err2!=KErrNone)
+        return err2;
+        
+    return KErrNone;
+    
+    }
+    
+// -----------------------------------------------------------------------------
+// CXmlHandler::StartParsingWithAoL
+// Function to start parsing the XML script 
+// -----------------------------------------------------------------------------
+//   
+   
+void CXmlHandler::StartParsingWithAoL( const TDesC& aFileName )
+    {   
+     // Remember to cancel any outstanding request first.
+    if ( IsActive() )
+        {
+        Cancel();
+        }
+    // If file name is too long then don't parse it just mark it as a failed script
+	TInt pos=aFileName.LocateReverse('\\');
+	if(aFileName.Right(aFileName.Length()-pos).Length()>KMaxFileNameLength)
+		{
+		
+		TRAPD(err, iObserver.OnParseCompletedL( KErrGeneral,EOnError ));
+		return;
+		}    
+    User::LeaveIfError( iFile.Open( CCoeEnv::Static()->FsSession(), aFileName,
+        EFileRead ) );
+
+    // Create a buffer to store the file content.
+    // Note that this method uses active object to read the file.
+    // So we have to call SetActive() at the end. Then we call CParser::ParseL()
+    // in RunL() method.
+    iDisplayResult->Des().Zero();
+    delete iBuffer;
+    iBuffer = 0;
+    iBuffer = HBufC8::NewL( KBuffer1024 );
+    TPtr8 bufferPtr( iBuffer->Des() );
+    iFile.Read( bufferPtr, KBuffer1024, iStatus );
+    SetActive();
+
+	// Tell the parser that we are about to parse a XML document.    
+    iParser->ParseBeginL();
+    }
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnStartDocumentL
+// Callback to indicate start of the document
+// -----------------------------------------------------------------------------
+// 
+void CXmlHandler::OnStartDocumentL( const RDocumentParameters& /*aDocParam*/,
+        TInt aErrorCode )
+{
+    if ( KErrNone == aErrorCode )
+    {
+    // Nothing for now
+    }
+    else
+    {
+    	iObserver.OnParseCompletedL( aErrorCode, EOnStartElement );
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnEndDocumentL
+// Callback to indicate end of the document
+// -----------------------------------------------------------------------------
+//     
+void CXmlHandler::OnEndDocumentL( TInt aErrorCode )
+{
+    if ( KErrNone == aErrorCode )
+    {
+    	// Create action object
+		CAction *action = new(ELeave) CAction();
+		CleanupStack::PushL(action);
+		iActionList.AppendL(action);   
+		
+		CleanupStack::Pop(); // action
+		action->iType = EActionTypeEndScript;
+    }
+    iObserver.OnParseCompletedL( aErrorCode , EOnEndElement);
+}
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnStartElementL
+// Callback to indicate an element has been parsed
+// -----------------------------------------------------------------------------
+// 
+void CXmlHandler::OnStartElementL( const RTagInfo& aElement,
+        const RAttributeArray& aAttributes, TInt aErrorCode )
+{
+    if ( KErrNone == aErrorCode )
+    {
+    	const TDesC8& name = aElement.LocalName().DesC();
+    	
+    	iContent->Des().Zero();
+    	
+    	TInt i;
+    	
+    	if (name == KAction || name == KLoop)
+    	{
+    		// Create action object
+    		CAction *action = new(ELeave) CAction();
+    		CleanupStack::PushL(action);
+    		
+    		if(name == KLoop)
+              {
+              for (i=0; i<aAttributes.Count(); i++)
+                {
+                    RAttribute attrib = aAttributes[i];
+                    const TDesC8& attribName = attrib.Attribute().LocalName().DesC();
+                    const TDesC8& attribValue = attrib.Value().DesC();          
+                    TBuf<KBuffer256> tmp;
+                    tmp.Copy(attribValue);
+                
+                    if(attribName == KCount)
+                    {
+                        action->iType = EActionTypeLoopStart;
+                        if(attribValue == KInfinite)
+                           tmp.Copy(KMinus1);
+                           
+                        action->iParams = tmp.AllocL();      
+                    }
+                }
+              }
+    		
+    		iActionList.AppendL(action);    			
+    		
+    		CleanupStack::Pop(); // action
+    		iAction = action;    		
+    		
+    		   		
+    	}
+    	else if (name == KName)
+    		iContentType = EContentName;
+    	else if (name == KType)
+    		iContentType = EContentType;
+    	else if (name == KParams)
+    		iContentType = EContentParams;
+    	else if (name == KPrintLog)
+    		iContentType = EContentPrintLog;
+    	else if (name == KKeys)
+    		iContentType = EContentKeys;
+    	else if (name == KScreenShot)
+    	    iContentType = EContentScreenshot;
+    	else
+    		{    		
+    		}
+    }
+    else
+    {
+    	iObserver.OnParseCompletedL( aErrorCode, EOnStartElement );
+    }
+}
+        
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnEndElementL
+// Callback to indicate the end of the element has been reached.
+// -----------------------------------------------------------------------------
+// 
+void CXmlHandler::OnEndElementL( const RTagInfo &aElement, TInt aErrorCode )
+{
+    if ( KErrNone == aErrorCode )
+    {
+        // If we find the end of an element, we write it to the screen,
+        // for example: "</tag>"
+    	const TDesC8& name = aElement.LocalName().DesC();
+    	
+    	TPtr8 des(iContent->Des());
+    	CUtils::StripSpaces(des);
+    	
+    	HBufC *txt = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*iContent);
+    	CleanupStack::PushL(txt);
+
+    	if (name == KAction)
+    	{
+    		iAction = NULL;
+    	}
+    	else if (name == KLoop)
+		{
+			//reset the flag iLoopExists
+			CAction *action = new(ELeave) CAction();
+            CleanupStack::PushL(action);
+            action->iType = EActionTypeLoopEnd;
+            iActionList.AppendL(action);                
+            
+            CleanupStack::Pop(); // action
+            iAction = action;  
+		}
+    	else if (name == KType && iContentType == EContentType && iAction)
+    	{
+    		TLex lex(txt->Des());
+    		lex.SkipSpace();
+    		TPtrC token = lex.NextToken();
+    		if (token == KParamActionsView)
+    			iAction->iType = EActionTypeView;
+    		else if (token == KParamActionsApp)
+    			iAction->iType = EActionTypeApp;
+    		else if (token == KParamActionsJavaApp)
+    			iAction->iType = EActionTypeJavaApp;
+    		else if (token == KParamActionsPointerEvent)
+        		iAction->iType = EActionTypePointerEvent;
+    		else if (token == KParamActionsWait)
+    			iAction->iType = EActionTypeWait;
+    		else if (token == KParamActionsOrient)
+    		    iAction->iType = EActionTypeOrientationChange;
+    		else if (token == KParamActionsScreenReset)
+    			iAction->iType = EActionTypeScreenReset;
+    		else if (token == KParamActionsKeyPress)
+    			iAction->iType = EActionTypeKeys;
+    		else if (token == KParamCloseApp)
+    			iAction->iType = EActionCloseApp;
+    	}
+    	else if (name == KParams && iContentType == EContentParams && iAction)
+    	{
+    		delete iAction->iParams; 
+    		iAction->iParams=NULL;
+    		iAction->iParams = txt->Des().AllocL();  
+    	}
+		else if (name == KPrintLog && iContentType == EContentPrintLog && iAction)
+        	{
+        		delete iAction->iPrintLog; 
+        		iAction->iPrintLog=NULL;
+        		iAction->iPrintLog = txt->Des().AllocL();  
+        	}
+    	else if (name == KScreenShot && iContentType == EContentScreenshot && iAction)
+		{
+			delete iAction->iScreenshotTag; 
+			iAction->iScreenshotTag = NULL;
+			iAction->iScreenshotTag = txt->Des().AllocL();  
+		}
+    	else if (name == KKeys && iContentType == EContentKeys && iAction)
+    	{
+    		TLex lex(txt->Des());
+    		TBuf<KBuffer20> keyName(KN);
+    		
+    		for (lex.SkipSpace(); !lex.Eos(); lex.SkipSpace())
+    		{
+    			TPtrC token = lex.NextToken();
+    			keyName.FillZ();
+    			keyName.Copy(token);
+  
+    			if(token.Compare(KLeftSoftKey) == 0 )
+    				keyName.Copy(KF842);
+    			else if(token.Compare(KRightSoftKey)  == 0 )
+    				keyName.Copy(KF843);
+    			else if(token.Compare(KMiddleSoftKey) == 0 )
+    				keyName.Copy(Ka7);
+    			else if(token.Compare(KDownArrowKey)  == 0 )
+    				keyName.Copy(KF80A);
+    			else if(token.Compare(KUpArrowKey)    == 0 )
+    				keyName.Copy(KF809);
+    			else if(token.Compare(KRightArrowKey) == 0 )
+    				keyName.Copy(KF808);
+    			else if(token.Compare(KLeftArrowKey)  == 0 )
+    				keyName.Copy(KF807);
+    			else if(token.Compare(KKeyBackSpace)  == 0 )
+    				keyName.Copy(K0008);
+    			else if(token.Compare(KKeySpace)  == 0 )
+    			    keyName.Copy(K0020);
+    			else if(token.Compare(KKeyAmpersand)  == 0 )
+    			    keyName.Copy(K0026);
+    			else if(token.Compare(KKeyLessThan)  == 0 )
+    			    keyName.Copy(K003C);
+    			else if(token.Compare(KKeyGreaterThan)  == 0 )
+    			    keyName.Copy(K003E);
+    			else if(token.Compare(KKeyMenu)  == 0 ) 
+    				keyName.Copy(KF852);
+    			else if(token.Compare(KKeyYes)  == 0 ) 
+    				keyName.Copy(KF862);
+    			else if(token.Compare(KKeyNo)  == 0 ) 
+    				keyName.Copy(KF863);
+    			else if(token.Compare(KKeyCamera)  == 0 )
+    			    keyName.Copy(KF893);
+                else if(token.Compare(KKeyHash)  == 0 )
+                    keyName.Copy(_L("0x23"));
+    
+    			if (keyName.Left(2) == KHEX)
+    			{
+    				//Special keys
+    				TLex lex2(keyName.Mid(2));
+    				TUint value;
+    				if (lex2.Val(value,EHex) == KErrNone)
+    					iAction->iKeys.AppendL(value);
+    			}
+    			else
+    			{
+    				//alpha numeric keys and symbols
+    			    for(TInt i=0; i<token.Length(); i++)
+    			    {
+	    				TUint value = token.operator [](i);
+	    				iAction->iKeys.AppendL(value);
+    			    }
+    			}
+    		}
+    	}
+    	else
+		{
+		}
+    	CleanupStack::PopAndDestroy(); // txt
+    	iContentType = EContentNone;
+    }
+    else
+    {
+        iObserver.OnParseCompletedL( aErrorCode,EOnEndElement );
+    }
+}
+    
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnContentL
+// Callback that sends the content of the element
+// -----------------------------------------------------------------------------
+//
+
+void CXmlHandler::OnContentL( const TDesC8 &aBytes, TInt aErrorCode )
+{
+    if ( KErrNone == aErrorCode )
+    {
+        while (iContent->Des().MaxLength() < iContent->Des().Length()+aBytes.Length())
+    	{
+    		iContent = iContent->ReAllocL(iContent->Des().Length()*3/2);
+    	}
+    	iContent->Des().Append(aBytes);	 
+    }
+    else
+    {
+        iObserver.OnParseCompletedL( aErrorCode, EOnContent);
+    }
+}
+    
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnStartPrefixMappingL
+// This method is a notification of the beginning of the scope of a prefix-URI 
+// Namespace mapping. This method is always called before the corresponding 
+// OnStartElementL method.
+// -----------------------------------------------------------------------------
+//
+
+void CXmlHandler::OnStartPrefixMappingL( const RString& /*aPrefix*/,
+        const RString& /*aUri*/, TInt aErrorCode )
+{
+	if ( KErrNone == aErrorCode )
+    {
+    }
+	else
+    {
+    	iObserver.OnParseCompletedL( aErrorCode,EOnStartPrefixMapping );
+    }
+}
+        
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnEndPrefixMappingL
+// This method is a notification of the end of the scope of a prefix-URI mapping.
+// This method is called after the corresponding DoEndElementL method.
+// -----------------------------------------------------------------------------
+//
+
+void CXmlHandler::OnEndPrefixMappingL( const RString& /*aPrefix*/,
+        TInt aErrorCode )
+{
+	if ( KErrNone == aErrorCode )
+    {
+    }
+	else
+    {
+    	iObserver.OnParseCompletedL( aErrorCode,EOnEndPrefixMapping );
+    }
+}    
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnEndPrefixMappingL
+// This method is a notification of ignorable whitespace in element content.
+// -----------------------------------------------------------------------------
+//
+void CXmlHandler::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/,
+        TInt aErrorCode )
+{
+	if ( KErrNone == aErrorCode )
+    {
+    }
+	else
+    {
+    	iObserver.OnParseCompletedL( aErrorCode, EOnIgnorableWhiteSpace );
+    }
+}    
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnSkippedEntityL
+// This method is a notification of a skipped entity. If the parser encounters an 
+// external entity it does not need to expand it - it can return the entity as aName 
+// for the client to deal with.
+// -----------------------------------------------------------------------------
+//
+void CXmlHandler::OnSkippedEntityL( const RString& /*aName*/,
+        TInt aErrorCode )
+{
+	if ( KErrNone == aErrorCode )
+    {
+    }
+	else
+    {
+    	iObserver.OnParseCompletedL( aErrorCode, EOnSkippedEntity );
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnProcessingInstructionL
+// This method is a receive notification of a processing instruction.
+// -----------------------------------------------------------------------------
+//
+
+void CXmlHandler::OnProcessingInstructionL( const TDesC8& /*aTarget*/,
+        const TDesC8& /*aData*/, TInt aErrorCode )
+{
+    if ( KErrNone == aErrorCode )
+	{
+	}
+    else
+    {
+    	iObserver.OnParseCompletedL( aErrorCode, EOnProcessingInstruction );
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnError
+// This method indicates an error has occurred.
+// -----------------------------------------------------------------------------
+//
+void CXmlHandler::OnError( TInt aErrorCode )
+{
+    _LIT( KErrorMessage, "*** OnError ***\f" );
+    TRAPD(error, AppendTextL( KErrorMessage ));
+    
+    iAction = NULL;
+    //reset the flag iLoopExists
+    for(TInt i = iActionList.Count() - 1; i >= iActionListIndex; i--)
+	{
+		CAction *action = iActionList.operator [](iActionListIndex);
+		if(action)
+		{
+			delete action;
+			action = NULL;
+		}
+		iActionList.Remove(iActionListIndex);
+	}
+    TRAPD(err, iObserver.OnParseCompletedL( aErrorCode,EOnError )); 
+}
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::OnError
+// This method obtains the interface matching the specified uid.
+// -----------------------------------------------------------------------------
+//
+
+TAny* CXmlHandler::GetExtendedInterface( const TInt32 /*aUid*/ )
+{
+    return NULL;
+}
+
+// -----------------------------------------------------------------------------
+// CXmlHandler::AppendTextL
+// Function to expand the actual buffer size
+// -----------------------------------------------------------------------------
+//
+
+void CXmlHandler::AppendTextL( const TDesC& aText )
+{
+    TPtr displayResultPtr( iDisplayResult->Des() );
+    if ( displayResultPtr.Length() + aText.Length() > displayResultPtr.MaxLength() )
+    {
+        TRAPD(err, iDisplayResult = iDisplayResult->ReAllocL( displayResultPtr.MaxLength()
+            + KBuffer1024 ));
+        displayResultPtr.Set( iDisplayResult->Des() );
+    }    
+    displayResultPtr.Append( aText );
+}
+
+// -----------------------------------------------------------------------------
+// CAction::~CAction
+// Destructor for the CAction class
+// -----------------------------------------------------------------------------
+//
+CAction::~CAction()
+{
+	delete iParams; 
+	iParams=NULL;
+	delete iPrintLog;
+	iPrintLog = NULL;
+	delete iScreenshotTag;
+	iScreenshotTag = NULL;
+	iKeys.Close();
+}
+// End of File