testconns/statdesktop/desktop/source/lib/src/statscriptdecoder.cpp
changeset 4 b8d1455fddc0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testconns/statdesktop/desktop/source/lib/src/statscriptdecoder.cpp	Mon Oct 04 02:58:21 2010 +0300
@@ -0,0 +1,353 @@
+/*
+* Copyright (c) 2005-2009 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 "stdafx.h"
+#include "statscriptdecoder.h"
+
+//----------------------------------------------------------------------------
+// Contructor
+CSTATScriptCommand::CSTATScriptCommand()
+: cCommandID(0), pCommand(NULL), ulLength(0)
+{
+}
+
+//----------------------------------------------------------------------------
+// Destructor
+CSTATScriptCommand::~CSTATScriptCommand()
+{
+	Reset();
+}
+
+
+//----------------------------------------------------------------------------
+// Set command data
+bool CSTATScriptCommand::SetData(const char *pData, const unsigned long theLength)
+{
+	Reset();
+
+	if (pData && theLength)
+	{
+		pCommand = new char[theLength + 1];
+		if (!pCommand)
+			return false;
+
+		memcpy(pCommand, pData, theLength);
+		*(pCommand + theLength) = (char)0;
+		ulLength = theLength;
+	}
+
+	return true;
+}
+
+
+//----------------------------------------------------------------------------
+// Destructor
+void CSTATScriptCommand::Reset()
+{
+	if (pCommand)
+	{
+		delete [] pCommand;
+		pCommand = NULL;
+	}
+
+	ulLength = 0;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Script Decoder class
+////////////////////////////////////////////////////////////////////////////////////////
+
+//----------------------------------------------------------------------------
+// Constructor
+CSTATScriptDecoder::CSTATScriptDecoder(CSTATLogFile *theLog)
+: lFileLength(0), iCounter(0),
+  lpBuffer(NULL)
+{
+	pLog = theLog;
+}
+
+
+//----------------------------------------------------------------------------
+// Destructor
+CSTATScriptDecoder::~CSTATScriptDecoder()
+{
+	Release();
+}
+
+
+//----------------------------------------------------------------------------
+// Read the script into memory
+int
+CSTATScriptDecoder::Initialise(const CString& file, bool bIsFile)
+{
+	lpBuffer = NULL;
+	int ret = OPEN_SCRIPT_FILE_COMPLETE_FAILURE;
+
+	// read the commands into memory
+	if (bIsFile)
+	{
+		CFile script_file;
+		if (script_file.Open(file, CFile::modeRead))
+		{
+			ret = ReadFileIntoMemory(script_file);
+			script_file.Abort();
+		}
+	}
+	else
+		ret = ReadDataIntoMemory(file);
+
+	// make sure we have valid start/end points in the script
+	if (ret == ITS_OK)
+		ret = ValidateScript();
+
+	if (ret == ITS_OK)
+	{
+		pLog->WriteTimeToLog();
+
+		if(bIsFile)
+		{
+			CString cBuffer = _T("Script file is : ");
+			cBuffer += file;
+			pLog->Write(cBuffer);
+		}
+		else
+			pLog->Write(_T("Interpreting command script..."));
+
+		ret = ITS_OK;
+	}
+	else
+		Release();
+
+	return ret;
+}
+
+
+//----------------------------------------------------------------------------
+// Release resources
+void CSTATScriptDecoder::Release()
+{
+	LastCommand.Reset();
+
+	// release the script
+	if (lpBuffer && lFileLength)
+	{
+		delete [] lpBuffer;
+		lpBuffer = NULL;
+		lFileLength = iCounter = 0;
+	}
+}
+
+
+//----------------------------------------------------------------------------
+// get the contents of a single command
+int
+CSTATScriptDecoder::GetNextCommand(CSTATScriptCommand **ppCommand)
+{
+	// get to the start of the command
+	while (lpBuffer[iCounter] != '<')
+	{
+		// comment
+		if (lpBuffer[iCounter] == '/' && lpBuffer[iCounter + 1] == '*')
+		{
+			if (ExtractComment())
+			{
+				*ppCommand = &LastCommand;
+				return LastCommand.cCommandID;
+			}
+
+			return 0;
+		}
+
+		if (!IncrementCounter())
+			return 0;
+	}
+
+	// step over the '<'
+	if (!IncrementCounter())
+		return 0;
+
+	// save the command ID
+	LastCommand.cCommandID = (char)toupper(lpBuffer[iCounter]);
+	if (!IncrementCounter())
+		return 0;
+
+	// need to step over 'image' with '#image' command
+	if (LastCommand.cCommandID == '#')
+	{
+		while (lpBuffer[iCounter] != ' ')
+			if (!IncrementCounter())
+				return 0;
+
+		// step over the space
+		if (!IncrementCounter())
+			return 0;
+	}
+
+	int iBeginning = iCounter;
+
+	// extract the command
+	while (lpBuffer[iCounter] != '>')
+		if (!IncrementCounter())
+			return 0;
+
+	// save our command
+	LastCommand.SetData(lpBuffer + iBeginning, iCounter - iBeginning);
+
+	// step over the '>'
+	IncrementCounter();
+
+	// set pointer to the command
+	*ppCommand = &LastCommand;
+	return LastCommand.cCommandID;
+}
+
+
+//----------------------------------------------------------------------------
+// PRIVATE METHODS
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+//reads string data into memory so that it can be decoded
+int CSTATScriptDecoder::ReadDataIntoMemory(const CString& commands)
+{
+	// Convert CString to char *
+	lFileLength = commands.GetLength();		//set length
+	lpBuffer = new char [lFileLength + 1];		//allocate temporary buffer
+	if (lpBuffer)
+	{
+		if (!pLog->ToAnsi(commands, 
+								  lpBuffer, 
+								  lFileLength))
+		{
+			return INTERPRET_COMMANDS_FAILURE;		//unable to convert to 8-bit
+		}
+
+		lpBuffer[lFileLength] = 0;
+		return ITS_OK;
+	}
+
+	return E_OUTOFMEM;
+}
+//----------------------------------------------------------------------------
+//reads file data into memory so that it can be decoded
+int CSTATScriptDecoder::ReadFileIntoMemory(CFile& scriptdata)
+{
+	try
+	{
+		lFileLength = scriptdata.GetLength();		//file length
+		lpBuffer = new char [lFileLength + 1];		//allocate temporary buffer
+		if (lpBuffer)
+		{
+			scriptdata.Read(lpBuffer, lFileLength);	//read in from the file and store in the buffer
+			lpBuffer[lFileLength] = 0;
+			return ITS_OK;
+		}
+	}
+	catch(CFileException *e)
+	{
+		e -> Delete();
+		return OPEN_SCRIPT_FILE_COMPLETE_FAILURE;
+	}
+
+	return E_OUTOFMEM;
+}
+
+
+//----------------------------------------------------------------------------
+// checks that start and end codes exist in the script
+// on success, iCounter will be left ready for the first STAT command
+int CSTATScriptDecoder::ValidateScript()
+{
+	CSTATScriptCommand *pCommand;
+	bool bFound = false;
+
+	// reset
+	iCounter = 0;
+
+	// look for end
+	while (GetNextCommand(&pCommand))
+	{
+		if (pCommand->cCommandID == 'E')
+		{
+			bFound = true;
+			break;
+		}
+	}
+
+	if (bFound)
+	{
+		// reset
+		iCounter = 0;
+		bFound = false;
+
+		// look for begin
+		while (GetNextCommand(&pCommand))
+		{
+			if (pCommand->cCommandID == 'B')
+			{
+				bFound = true;
+				iCounter -= 3;	// step back so this is the first command sent
+				break;
+			}
+		}
+	}
+
+	if (!bFound)
+		return BEGIN_COMMAND_FAILURE;
+
+	return ITS_OK;
+}
+
+
+//----------------------------------------------------------------------------
+// get a comment
+int
+CSTATScriptDecoder::ExtractComment()
+{
+	int iBeginning = iCounter;
+
+	LastCommand.cCommandID = lpBuffer[iCounter];
+	iCounter += 2;
+
+	while (((iCounter + 1) < lFileLength) &&
+		   !(lpBuffer[iCounter] == '*' && lpBuffer[iCounter + 1] == '/') )
+	{
+		if (!IncrementCounter())
+			return 0;
+	}
+
+	// get the last bit of the comment '*/'
+	if ((iCounter + 1) < lFileLength)
+		iCounter += 2;
+
+	// save our comment
+	LastCommand.SetData(lpBuffer + iBeginning, iCounter - iBeginning);
+	return LastCommand.cCommandID;
+}
+
+
+//----------------------------------------------------------------------------
+// increment counter but make sure we don't go over the end of the script
+bool CSTATScriptDecoder::IncrementCounter(void)
+{
+	return (++iCounter < lFileLength);
+}