imgtools/sisutils/src/pkgfileparser.cpp
changeset 0 044383f39525
child 590 360bd6b35136
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/sisutils/src/pkgfileparser.cpp	Tue Oct 27 16:36:35 2009 +0000
@@ -0,0 +1,1435 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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 "sisutils.h"
+#include "pkgfileparser.h"
+
+// Parse options lookups
+#define MAXTOKENLEN	30
+struct SParseToken
+{
+	WCHAR pszOpt[MAXTOKENLEN];
+	DWORD dwOpt;
+};
+
+const SParseToken KTokens[] =
+{
+	{L"if",		IF_TOKEN},
+	{L"elseif",	ELSEIF_TOKEN},
+	{L"else",	ELSE_TOKEN},
+	{L"endif",	ENDIF_TOKEN},
+	{L"exists",	EXISTS_TOKEN},
+	{L"devprop",DEVCAP_TOKEN},
+	{L"appcap",	APPCAP_TOKEN},
+	{L"package",DEVCAP_TOKEN},
+	{L"appprop",APPCAP_TOKEN},
+	{L"not",	NOT_TOKEN},
+	{L"and",	AND_TOKEN},
+	{L"or",		OR_TOKEN},
+	{L"type",	TYPE_TOKEN},
+	{L"key",	KEY_TOKEN},
+};
+#define NUMPARSETOKENS (sizeof(KTokens)/sizeof(SParseToken))
+
+/**
+Constructor: PkgParser class
+Initilize the parameters to data members.
+
+@internalComponent
+@released
+
+@param aFile	- Name of the package script file
+*/
+PkgParser::PkgParser(String aFile) : iPkgFile(aFile), m_nLineNo(0)
+{
+}
+
+/**
+Destructor: PkgParser class
+Deallocates the memory for data members
+
+@internalComponent
+@released
+*/
+PkgParser::~PkgParser()
+{
+	if(iPkgHandle != INVALID_HANDLE_VALUE)
+	{
+		::CloseHandle(iPkgHandle);
+	}
+
+	DeleteAll();
+}
+
+/**
+OpenFile: Opens the package script file
+
+@internalComponent
+@released
+*/
+int PkgParser::OpenFile()
+{
+	iPkgHandle = ::CreateFileW(string2wstring(iPkgFile).data(),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+	
+	return (iPkgHandle != INVALID_HANDLE_VALUE) ? 1 : 0;
+}
+
+/**
+GetEmbeddedSisList: Returns the embedded sis file list
+
+@internalComponent
+@released
+
+@param embedSisList	- reference to sis file list structure
+*/
+void PkgParser::GetEmbeddedSisList(SISFILE_LIST& embedSisList)
+{
+	embedSisList = iEmbedSisFiles;
+}
+
+/**
+GetInstallOptions: Returns the install options read from the package file
+
+@internalComponent
+@released
+
+@param aOptions	- reference to the string list structure
+*/
+void PkgParser::GetInstallOptions(FILE_LIST& aOptions)
+{
+	aOptions = iInstallOptions;
+}
+
+/**
+GetLanguageList: Returns the language list read from the package file
+
+@internalComponent
+@released
+
+@param langList	- reference to the language list structure
+*/
+void PkgParser::GetLanguageList(LANGUAGE_LIST& langList)
+{
+	langList = iLangList;
+}
+
+/**
+GetHeader: Returns the header details read from the package file
+
+@internalComponent
+@released
+
+@param pkgHeader	- reference to the package header structure
+*/
+void PkgParser::GetHeader(PKG_HEADER& pkgHeader)
+{
+	pkgHeader = iPkgHeader;
+}
+
+/**
+GetCommandList: Returns the package body details read from the package file
+
+@internalComponent
+@released
+
+@param cmdList	- reference to the command list structure
+*/
+void PkgParser::GetCommandList(CMDBLOCK_LIST& cmdList)
+{
+	cmdList = iPkgBlock;
+}
+
+/**
+ParsePkgFile: Parses the package file
+
+@internalComponent
+@released
+*/
+void PkgParser::ParsePkgFile()
+{
+	if(!OpenFile())
+	{
+		throw SisUtilsException((char*)iPkgFile.data(), "Could not open file");
+	}
+
+	GetNextChar();
+
+	// skip unicode marker if present
+	if(m_pkgChar==0xFEFF) GetNextChar();
+
+	GetNextToken ();
+	while(m_token!=EOF_TOKEN)
+	{
+		ParseEmbeddedBlockL();
+		switch (m_token)
+		{
+		case '&':
+			GetNextToken ();
+			ParseLanguagesL();
+			break;
+		case '#':
+			GetNextToken ();
+			ParseHeaderL();
+			break;
+		case '%':
+			GetNextToken ();
+			ParseVendorNameL();
+			break;
+		case '=':
+			GetNextToken ();
+			ParseLogoL();
+			break;
+		case '(':
+			GetNextToken ();
+			ParseDependencyL();
+			break;
+		case ':':
+			GetNextToken ();
+			ParseVendorUniqueNameL();
+			break;
+		case '[':
+			GetNextToken ();
+			ParseTargetDeviceL();
+			break;
+		case EOF_TOKEN:
+			break;
+		default:
+			ParserError("Unexpected token");
+			break;
+		}
+	}
+}
+
+/**
+ParseLanguagesL: Parses the language section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseLanguagesL()
+{
+	unsigned long langCode = 0;
+	unsigned long dialect = 0;
+	
+	while (true)
+	{
+		if (m_token==ALPHA_TOKEN)
+		{
+			langCode = PkgLanguage::GetLanguageCode(m_tokenValue.pszString);
+		}
+		else if (m_token==NUMERIC_TOKEN && m_tokenValue.dwNumber>=0 && m_tokenValue.dwNumber<=1000)
+		{
+			langCode = (m_tokenValue.dwNumber);
+		}
+
+		GetNextToken ();
+
+		// Check if a dialect is defined
+		if (m_token == '(')
+		{
+			GetNumericToken();
+			// Modify the last added language code, combining it with dialect code
+			dialect = (m_tokenValue.dwNumber);
+			GetNextToken ();
+			GetNextToken ();
+		}
+		AddLanguage(wstring2string(PkgLanguage::GetLanguageName(langCode)), langCode, dialect);
+
+		if (m_token!=',')
+			return;
+		GetNextToken ();
+	}
+}
+
+
+/**
+ParseHeaderL: Parses the package header section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseHeaderL()
+{
+	if (!iLangList.size())
+	{
+		//No languages defined, assuming English."
+		AddLanguage("EN", PkgLanguage::ELangEnglish, 0);
+	}
+	
+	// process application names
+	ExpectToken('{');
+	for (WORD wNumLangs = 0; wNumLangs < iLangList.size(); wNumLangs++)
+	{
+		GetNextToken ();
+		ExpectToken(QUOTED_STRING_TOKEN);
+		iPkgHeader.pkgNameList.push_back(wstring2string(m_tokenValue.pszString));
+		GetNextToken ();
+		if (wNumLangs < (iLangList.size()-1) )
+		{
+			ExpectToken(',');
+		}
+	}
+	ExpectToken('}');
+	GetNextToken (); 
+	
+	ExpectToken(',');
+	GetNextToken ();
+	ExpectToken('(');
+	GetNextToken ();
+	
+	ExpectToken(NUMERIC_TOKEN);
+	iPkgHeader.pkgUid = m_tokenValue.dwNumber;
+	GetNextToken ();
+	
+	ExpectToken(')');
+	GetNextToken ();
+	ExpectToken(',');
+	GetNextToken ();
+	
+	ExpectToken(NUMERIC_TOKEN);
+	iPkgHeader.vMajor = m_tokenValue.dwNumber;
+	GetNextToken ();
+	ExpectToken(',');
+	GetNextToken ();
+	
+	ExpectToken(NUMERIC_TOKEN);
+	iPkgHeader.vMinor = m_tokenValue.dwNumber;
+	GetNextToken ();
+	ExpectToken(',');
+	GetNextToken ();
+	
+	ExpectToken(NUMERIC_TOKEN);
+	iPkgHeader.vBuild = m_tokenValue.dwNumber;
+	GetNextToken ();
+	
+	// Parse any options
+	while (m_token==',')
+	{
+		GetNextToken ();
+		if (m_token==TYPE_TOKEN)
+		{
+			GetNextToken ();
+			ExpectToken('=');
+			GetNextToken ();
+			iPkgHeader.pkgType = wstring2string(m_tokenValue.pszString);
+			GetNextToken ();
+		}
+		else
+			GetNextToken ();
+	}
+}
+
+/**
+ParseEmbeddedBlockL: Parses the package body block
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseEmbeddedBlockL ()
+{
+	while(m_token!=EOF_TOKEN)
+	{
+		switch (m_token)
+		{
+		case QUOTED_STRING_TOKEN:
+			ParseFileL ();
+			break;
+		case '@':
+			GetNextToken ();
+			ParsePackageL ();
+			break;
+		case '!':
+			GetNextToken ();
+			ParseOptionsBlockL();
+			break;
+		case '+':
+			GetNextToken ();
+			ParsePropertyL ();
+			break;
+		case IF_TOKEN:
+			GetNextToken ();
+			ParseIfBlockL ();
+			break;
+		case ';' :
+			ParseCommentL ();
+			break;
+		default :
+			return;
+		}
+	}
+}
+
+/**
+ParseFileL: Parses the file list section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseFileL()
+{
+	PCMD_BLOCK pCmdBlock = 0;
+	PINSTALLFILE_LIST pFileList = 0;
+	
+	std::wstring sourceFile (m_tokenValue.pszString);
+	
+	// Linux and windows both support forward slashes so if source path is given '\' need to convert
+	// in forward slash for compatibility.
+	wchar_t *pBuffer = (wchar_t*)sourceFile.c_str();
+	wchar_t *pCurrent = pBuffer;
+	while (pBuffer && *pBuffer && (pCurrent = wcschr(pBuffer,L'\\')) != NULL)
+	{
+		*pCurrent = L'/';
+		pBuffer = pCurrent + 1;
+	}
+	
+	GetNextToken ();
+	
+	ExpectToken('-');
+	GetNextToken ();
+	
+	ExpectToken(QUOTED_STRING_TOKEN);
+	
+	std::wstring destinationFile (m_tokenValue.pszString);
+	
+	// SWI only supports backward slashesh so need to convert destination path in backward slash if
+	// user gives '/' in Linux.
+	pBuffer = (wchar_t*)destinationFile.c_str();
+	pCurrent = pBuffer;
+	while (pBuffer && *pBuffer && (pCurrent = wcschr(pBuffer,L'/')) != NULL)
+	{
+		*pCurrent = L'\\';
+		pBuffer = pCurrent + 1;
+	}
+	
+	GetNextToken ();
+	
+	// Test for options
+	if (m_token!=',')
+	{
+		pCmdBlock = new CMD_BLOCK;
+		pFileList = new INSTALLFILE_LIST;
+
+		pCmdBlock->cmdType = INSTALLFILE;
+		pCmdBlock->iInstallFileList = pFileList;
+
+		pFileList->langDepFlg = 0;
+		pFileList->srcFiles.push_back(wstring2string(sourceFile));
+		pFileList->destFile = wstring2string(destinationFile);
+
+		iPkgBlock.push_back(pCmdBlock);
+	}
+	else
+	{	
+		bool needAdd = false;
+		while(m_token==',')
+		{
+			GetNextToken ();
+			std::wstring installOption = m_tokenValue.pszString;
+			if((installOption == L"FF") || (installOption == L"FILE"))
+			{
+				needAdd = true;
+			}
+			GetNextToken ();
+		}
+		if (needAdd)
+		{
+			pCmdBlock = new CMD_BLOCK;
+			pFileList = new INSTALLFILE_LIST;
+
+			pCmdBlock->cmdType = INSTALLFILE;
+			pCmdBlock->iInstallFileList = pFileList;
+
+			pFileList->langDepFlg = 0;
+			pFileList->srcFiles.push_back(wstring2string(sourceFile));
+			pFileList->destFile = wstring2string(destinationFile);
+		
+			iPkgBlock.push_back(pCmdBlock);
+		}
+	}
+}
+
+/**
+ParseIfBlockL: Parses the conditional installation body
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseIfBlockL()
+{
+	PCMD_BLOCK pCmdBlock = 0; 
+
+	//IF
+	pCmdBlock = new CMD_BLOCK;
+	pCmdBlock->cmdType = IF;
+	ParseLogicalOp(pCmdBlock->cmdExpression);
+	iPkgBlock.push_back(pCmdBlock);
+
+	ParseEmbeddedBlockL ();
+	
+	while (m_token==ELSEIF_TOKEN)
+	{
+		GetNextToken ();
+		//ELSEIF
+		pCmdBlock = new CMD_BLOCK;
+		pCmdBlock->cmdType = ELSEIF;
+		ParseLogicalOp(pCmdBlock->cmdExpression);
+		iPkgBlock.push_back(pCmdBlock);
+
+		ParseEmbeddedBlockL ();
+	}
+	
+	if (m_token==ELSE_TOKEN)
+	{
+		GetNextToken ();
+		//ELSEIF
+		pCmdBlock = new CMD_BLOCK;
+		pCmdBlock->cmdType = ELSE;
+		iPkgBlock.push_back(pCmdBlock);
+
+		ParseEmbeddedBlockL ();
+	}
+	
+	ExpectToken(ENDIF_TOKEN);
+	//ENDIF
+	pCmdBlock = new CMD_BLOCK;
+	pCmdBlock->cmdType = ENDIF;
+	iPkgBlock.push_back(pCmdBlock);
+
+	GetNextToken ();
+}
+
+/**
+ParseLogicalOp: Parses the logical expression
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseLogicalOp (String& aExpression)
+{
+    ParseRelation (aExpression);
+	switch (m_token)
+	{
+	case AND_TOKEN:
+	case OR_TOKEN:
+		{
+			if (m_token==AND_TOKEN)
+				aExpression.append(" && ");
+			else
+				aExpression.append(" || ");
+			GetNextToken ();
+			ParseLogicalOp (aExpression);
+		}
+		break;
+	}
+}
+
+/**
+ParseRelation: Parses the relational expression
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseRelation(String& aExpression)
+{
+    ParseUnary (aExpression);
+	switch (m_token)
+	{
+	case '=':
+	case '>':
+	case '<':
+	case GE_TOKEN:
+	case LE_TOKEN:
+	case NE_TOKEN:
+	case APPCAP_TOKEN:
+		{
+			switch (m_token)
+			{
+			case '=':
+				aExpression.append(" == ");
+				break;
+			case '>':
+				aExpression.append(" > ");
+				break;
+			case '<':
+				aExpression.append(" < ");
+				break;
+			case GE_TOKEN:
+				aExpression.append(" >= ");
+				break;
+			case LE_TOKEN:
+				aExpression.append(" <= ");
+				break;
+			case NE_TOKEN:
+				aExpression.append(" != ");
+				break;
+			case APPCAP_TOKEN:
+				aExpression.append(" APPPROP ");
+				break;
+			}
+			GetNextToken ();
+			ParseUnary (aExpression);
+			break;
+		}
+	}
+}
+
+/**
+ParseUnary: Parses the unary expression
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseUnary(String& aExpression)
+{
+    switch (m_token)
+	{
+	case NOT_TOKEN:
+		aExpression.append(" !");
+		GetNextToken ();
+		ParseUnary (aExpression);
+		break;
+	case EXISTS_TOKEN:
+	case DEVCAP_TOKEN:
+		{	// 1 arg function
+			int token=m_token;
+			GetNextToken ();
+			ExpectToken('(');
+			GetNextToken ();
+			if (token==EXISTS_TOKEN)
+			{
+				aExpression.append("EXISTS(\"");
+				ExpectToken(QUOTED_STRING_TOKEN);
+				GetNextToken ();
+				aExpression.append(wstring2string(m_tokenValue.pszString));
+				aExpression.append("\")");
+			}
+			else
+			{
+				aExpression.append("DEVCAP(");
+				ParseUnary (aExpression);
+				aExpression.append(")");
+			}
+			ExpectToken(')');
+			GetNextToken ();
+			break;
+		}
+	default:
+		ParseFactor (aExpression);
+		break;
+	}
+}
+
+/**
+ParseFactor: Parses the expression factor
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseFactor(String& aExpression)
+{
+    switch (m_token) {
+	case '(':
+		{
+			aExpression.append("(");
+			GetNextToken ();
+			ParseLogicalOp (aExpression);
+			ExpectToken(')');
+			aExpression.append(")");
+		}
+		break;
+	case QUOTED_STRING_TOKEN:
+	case ALPHA_TOKEN:
+	case NUMERIC_TOKEN:
+		{
+			switch (m_token)
+			{
+			case QUOTED_STRING_TOKEN:
+				aExpression.append("\"");
+				aExpression.append(wstring2string(m_tokenValue.pszString));
+				aExpression.append("\"");
+				break;
+			case ALPHA_TOKEN:
+				if(!CompareNString(m_tokenValue.pszString,L"option",6))
+				{
+					aExpression.append(" defined(");
+					aExpression.append(wstring2string(m_tokenValue.pszString));
+					aExpression.append(") ");
+				}
+				else
+				{
+					aExpression.append(wstring2string(m_tokenValue.pszString));
+				}
+				break;
+			case NUMERIC_TOKEN:
+				{
+					std::ostringstream str;
+
+					str << "(0x" << std::setbase(16) << m_tokenValue.dwNumber << ")";
+					aExpression.append(str.str());
+				}
+				break;
+			}
+		}
+		break;
+	default:
+		ParserError("ErrBadCondFormat");
+	}
+	GetNextToken ();
+}
+
+
+/**
+ParsePackageL: Parses the embedded package section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParsePackageL()
+{
+	PCMD_BLOCK pCmdBlock = 0;
+	int found = 0;
+
+	ExpectToken(QUOTED_STRING_TOKEN);
+
+	//if the sis file already exists then skip it
+	SISFILE_LIST::iterator begin = iEmbedSisFiles.begin();
+	SISFILE_LIST::iterator end = iEmbedSisFiles.end();
+
+	while(begin != end)
+	{
+		if((*begin).compare(wstring2string(m_tokenValue.pszString)) == 0)
+		{
+			found = 1;
+			break;
+		}
+		++begin;
+	}
+
+	if(!found)
+	{
+		iEmbedSisFiles.push_back(wstring2string(m_tokenValue.pszString));
+	}
+	
+	//add as a command block as well
+	{
+		pCmdBlock = new CMD_BLOCK;
+
+		pCmdBlock->cmdType = PACKAGE;
+		pCmdBlock->iInstallFileList = 0;
+		pCmdBlock->cmdExpression = wstring2string(m_tokenValue.pszString);
+
+		iPkgBlock.push_back(pCmdBlock);
+	}
+
+
+	GetNextToken ();
+
+	ExpectToken(',');
+	GetNextToken ();
+	ExpectToken('(');
+	GetNextToken ();
+	ExpectToken(NUMERIC_TOKEN);
+	GetNextToken ();
+	ExpectToken(')');
+	GetNextToken ();
+}
+
+/**
+ParseCommentL: Parses the comment section
+  Parses a comment line (Does nothing, just throws the line away)
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseCommentL()
+{
+	// parse to end of line
+	while (m_pkgChar && (m_pkgChar!='\n')) GetNextChar();
+	GetNextToken ();
+}
+
+/**
+ParseOptionsBlockL: Parses the install options section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseOptionsBlockL()
+{
+	WORD wNumLangs;
+	
+	ExpectToken('(');
+	GetNextToken ();
+	
+	for (;;)
+	{
+		ExpectToken('{');
+		GetNextToken ();
+		
+		wNumLangs = 0;
+		while (wNumLangs < iLangList.size())
+		{
+			ExpectToken(QUOTED_STRING_TOKEN);
+			iInstallOptions.push_back(wstring2string(m_tokenValue.pszString));
+			GetNextToken ();
+			if (wNumLangs < iLangList.size() - 1)
+			{
+				ExpectToken(',');
+				GetNextToken ();
+			}
+			wNumLangs++;
+		}
+		
+		ExpectToken('}');
+		GetNextToken ();
+		if (m_token!=',') break;
+		GetNextToken ();
+	}
+	
+	ExpectToken(')');
+	GetNextToken ();	
+}
+
+/**
+ParsePropertyL: Parses the capability options section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParsePropertyL()
+{
+	ExpectToken('(');
+	do
+	{
+		GetNextToken ();
+		
+		ExpectToken(NUMERIC_TOKEN);
+		GetNextToken ();
+		ExpectToken('=');
+		GetNextToken ();
+		ExpectToken(NUMERIC_TOKEN);
+		GetNextToken ();
+	} while (m_token==',');
+	ExpectToken(')');
+	GetNextToken ();
+}
+
+/**
+ParseVendorNameL: Parses the vendor options section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseVendorNameL()
+{
+	ExpectToken('{');
+	for (WORD wNumLangs = 0; wNumLangs < iLangList.size(); wNumLangs++)
+	{
+		GetNextToken ();
+		ExpectToken(QUOTED_STRING_TOKEN);
+		GetNextToken ();
+		if (wNumLangs < iLangList.size() -1 )
+		{
+			ExpectToken(',');
+		}
+	}
+	ExpectToken('}');
+	GetNextToken ();
+}
+
+/**
+ParseLogoL: Parses the logo options section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseLogoL()
+{
+	ExpectToken (QUOTED_STRING_TOKEN);
+	GetNextToken ();
+	ExpectToken(',');
+	GetNextToken ();
+	ExpectToken (QUOTED_STRING_TOKEN);
+	GetNextToken ();
+	if (m_token==',')
+	{
+		GetNextToken ();
+		ExpectToken (QUOTED_STRING_TOKEN);
+		GetNextToken ();
+	}
+}
+
+/**
+ParseVersion: Parses the version details
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseVersion()
+{
+	GetNextToken();
+	ExpectToken(NUMERIC_TOKEN);
+
+	GetNextToken();
+	ExpectToken(',');
+	GetNextToken();
+	ExpectToken(NUMERIC_TOKEN);
+
+	GetNextToken();
+	ExpectToken(',');
+	GetNextToken();
+	ExpectToken(NUMERIC_TOKEN);
+
+	GetNextToken();
+}
+
+/**
+ParseDependencyL: Parses the dependency package section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseDependencyL()
+{
+	ExpectToken(NUMERIC_TOKEN);
+	GetNextToken ();
+	ExpectToken(')');
+	GetNextToken ();
+	ExpectToken(',');
+
+	ParseVersion();
+	if (m_token == '~')
+	{
+		ParseVersion();
+		ExpectToken(',');
+	}
+	
+	GetNextToken ();
+	ExpectToken('{');
+	for (TUint numLangs = 0; numLangs < iLangList.size(); ++numLangs)
+	{
+		GetNextToken ();
+		ExpectToken(QUOTED_STRING_TOKEN);
+		GetNextToken ();
+		if (numLangs < (iLangList.size() - 1))
+			ExpectToken(',');
+	}
+	ExpectToken('}');
+	GetNextToken ();
+}
+
+/**
+ParseVendorUniqueNameL: Parses the vendor unique name section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseVendorUniqueNameL()
+{
+	ExpectToken(QUOTED_STRING_TOKEN);
+	GetNextToken ();
+}
+
+/**
+ParseTargetDeviceL: Parses the target device name section
+
+@internalComponent
+@released
+*/
+void PkgParser::ParseTargetDeviceL()
+{
+	ExpectToken(NUMERIC_TOKEN);
+	GetNextToken ();
+	ExpectToken(']');
+	GetNextToken ();
+	ExpectToken(',');
+	
+	ParseVersion();
+	if (m_token == '~')
+	{
+		ParseVersion();
+		ExpectToken(',');
+	}
+	GetNextToken ();
+	ExpectToken('{');
+	
+	// must do this before adding language strings	
+	for (TUint numLangs = 0; numLangs < iLangList.size(); ++numLangs)
+	{
+		GetNextToken ();
+		ExpectToken(QUOTED_STRING_TOKEN);
+		GetNextToken ();
+		if (numLangs < (iLangList.size() - 1))
+			ExpectToken(',');
+	}
+	ExpectToken('}');
+	GetNextToken ();
+}
+
+
+/**
+GetNextChar: Reads the next character from the package file
+
+@internalComponent
+@released
+*/
+void PkgParser::GetNextChar()
+{
+#ifdef WIN32
+	DWORD dwBytesRead;
+	if (!::ReadFile(iPkgHandle, (LPVOID)&m_pkgChar, sizeof(WCHAR), &dwBytesRead, NULL) ||
+		dwBytesRead!=sizeof(wchar_t))
+		m_pkgChar='\0';
+#else
+#error "TODO: Implement this function under other OS than Windows"
+#endif
+}
+
+/**
+ExpectToken: Tests the current token value
+
+@internalComponent
+@released
+
+@param aToken - expected token value
+*/
+void PkgParser::ExpectToken(int aToken)
+{
+	if (m_token!=aToken)
+	{
+		ParserError("Unexpected Token");
+	}
+}
+
+/**
+GetNextToken: Reads the next valid token from the package file
+
+@internalComponent
+@released
+*/
+void PkgParser::GetNextToken ()
+{
+	// skip any white space & newLine's
+	while (m_pkgChar == '\n' || isspace(m_pkgChar) || m_pkgChar == 0xA0)
+	{
+		if (m_pkgChar == '\n') ++m_nLineNo;
+		GetNextChar();
+	}
+	
+	if (m_pkgChar == '\0')
+		m_token=EOF_TOKEN;
+	else if (IsNumericToken())
+	{
+		GetNumericToken();
+		m_token=NUMERIC_TOKEN;
+	}
+	else if (isalpha(m_pkgChar))
+	{ // have some alphanumeric text
+		GetAlphaNumericToken();
+		m_token=ALPHA_TOKEN;
+		// check if it is a keyword
+		for(unsigned short wLoop = 0; wLoop < NUMPARSETOKENS; wLoop++)
+		{
+			if(CompareTwoString(m_tokenValue.pszString,(wchar_t*)KTokens[wLoop].pszOpt) == 0)
+			{
+				m_token=KTokens[wLoop].dwOpt;
+				break;
+			}
+		}
+	}
+	else if (m_pkgChar == '\"')
+	{ // have a quoted string
+		GetStringToken();
+		m_token=QUOTED_STRING_TOKEN;
+	}
+	else if (m_pkgChar == '>')
+	{
+		GetNextChar();
+		if (m_pkgChar == '=')
+		{
+			m_token=GE_TOKEN;
+			GetNextChar();
+		}
+		else
+			m_token='>';
+	}
+	else if (m_pkgChar == '<')
+	{
+		// check if start of an escaped string, e.g. <123>"abc"
+		if (GetStringToken())
+			m_token=QUOTED_STRING_TOKEN;
+		else
+		{
+			GetNextChar();
+			if (m_pkgChar == '=')
+			{
+				m_token=LE_TOKEN;
+				GetNextChar();
+			}
+			else if (m_pkgChar == '>')
+			{
+				m_token=NE_TOKEN;
+				GetNextChar();
+			}
+			else
+				m_token='<';
+		}
+	}
+	else
+	{
+		m_token=m_pkgChar;
+		GetNextChar();
+	}
+}
+
+/**
+GetStringToken: Reads the string token from the package file
+
+@internalComponent
+@released
+*/
+bool PkgParser::GetStringToken()
+{
+	DWORD wCount = 0;
+	bool done=false;
+	bool finished=false;
+	DWORD escapeChars = 0;
+	
+	while (!finished)
+	{
+		if (m_pkgChar == '\"')
+		{
+			GetNextChar();
+			while(m_pkgChar && m_pkgChar != '\"')
+			{
+				if(wCount < (MAX_STRING - 1))
+					m_tokenValue.pszString[wCount++] = m_pkgChar;
+				else //We dont want the string with length greater than MAX_STRING to be cut off silently
+					ParserError("Bad String");
+				GetNextChar();
+			}
+			if(m_pkgChar == '\0')
+				ParserError("Bad String");
+			GetNextChar();
+			done=true;
+		}
+		if (m_pkgChar == '<')
+		{
+			m_tokenValue.pszString[wCount] = L'\0';
+			escapeChars=ParseEscapeChars();
+			if (escapeChars>0)
+			{
+				done=true;
+				wCount+=escapeChars;
+				if (wCount>=MAX_STRING) wCount=MAX_STRING-1;
+			}
+		}
+		if (escapeChars==0 || m_pkgChar != '\"')
+			finished=true;
+	}
+	
+	m_tokenValue.pszString[wCount] = L'\0';
+	return done;
+}
+
+/**
+ParseEscapeChars: Parses the escape sequence characters
+
+@internalComponent
+@released
+*/
+WORD PkgParser::ParseEscapeChars()
+{
+	WORD found=0;
+	WCHAR temp[MAX_STRING];
+#ifdef WIN32
+	while (m_pkgChar == '<')
+	{
+		wcscpy(temp,m_tokenValue.pszString);
+		DWORD fileOffset=::SetFilePointer(iPkgHandle, 0L, NULL, FILE_CURRENT);
+		try
+		{
+			GetNextChar();
+			GetNumericToken();
+			if (m_pkgChar=='>')
+				found++;
+			else
+			{
+				::SetFilePointer(iPkgHandle, fileOffset, NULL, FILE_BEGIN);
+				break;
+			}
+		}
+		catch (...)
+		{
+			wcscpy(m_tokenValue.pszString,temp);
+			::SetFilePointer(iPkgHandle, fileOffset, NULL, FILE_BEGIN);
+			break;
+		}
+		DWORD num=m_tokenValue.dwNumber;
+		// watch for CP1252 escapes which aren't appropriate for UNICODE
+		if (num>=0x80 && num<=0x9F) ParserError("Invalid Escape");
+		DWORD len=wcslen(temp);
+		wcscpy(m_tokenValue.pszString,temp);
+		if (len+2<=MAX_STRING)
+		{
+			m_tokenValue.pszString[len]=(WCHAR)num;
+			len++;
+			m_tokenValue.pszString[len]='\0';
+		}
+		GetNextChar();
+	}
+#else
+#error "TODO: Implement this function under other OS than Windows"
+#endif 
+	return found;
+}
+
+/**
+GetAlphaNumericToken: Parse an alphanumeric string from the input line
+
+@internalComponent
+@released
+*/
+void PkgParser::GetAlphaNumericToken()
+{
+	WORD wCount = 0;
+	while(m_pkgChar && (isalnum(m_pkgChar) || ((m_pkgChar) == '_')))
+	{
+		if(wCount < (MAX_STRING - 1))
+			m_tokenValue.pszString[wCount++] = m_pkgChar;
+		GetNextChar();
+	}
+	m_tokenValue.pszString[wCount] = L'\0';
+}
+
+/**
+IsNumericToken: Determines if the next lexeme is a numeric token
+
+@internalComponent
+@released
+*/
+bool PkgParser::IsNumericToken()
+{
+	bool lexemeIsNumber = false;
+	if (iswdigit(m_pkgChar))
+		lexemeIsNumber = true;
+	else if (m_pkgChar == '+' || m_pkgChar == '-')
+	{
+		// we may have a number but we must look ahead one char to be certain
+		
+		WCHAR oldChar = m_pkgChar;
+		DWORD fileOffset=::SetFilePointer(iPkgHandle, 0L, NULL, FILE_CURRENT);
+		GetNextChar();
+		lexemeIsNumber = iswdigit(m_pkgChar) != FALSE;
+		m_pkgChar = oldChar;
+		::SetFilePointer(iPkgHandle,fileOffset,NULL,FILE_BEGIN);
+	}
+	
+	return lexemeIsNumber;
+}
+
+/**
+GetNumericToken: Parse a number from the input line
+
+@internalComponent
+@released
+*/
+void PkgParser::GetNumericToken()
+{
+	WCHAR temp[MAX_STRING];
+	LPWSTR end;
+	bool hexString = false;
+	DWORD dwBytesRead;
+	DWORD fileOffset=::SetFilePointer(iPkgHandle, 0L, NULL, FILE_CURRENT);
+	
+	temp[0]=m_pkgChar;
+	if (!::ReadFile(iPkgHandle, &temp[1], (MAX_STRING-2)*sizeof(WCHAR), &dwBytesRead, NULL) ||
+		dwBytesRead==0)
+		ParserError("Read failed");
+	temp[1+dwBytesRead/sizeof(WCHAR)]='\0';
+	hexString = (!CompareNString(temp, L"0x", 2) || !CompareNString(&temp[1], L"0x", 2));
+	
+	m_tokenValue.dwNumber = wcstoul(temp, &end, (hexString) ? 16 : 10);
+	
+	if (end==temp) ParserError("Read failed"); 
+	::SetFilePointer(iPkgHandle, fileOffset+(end-temp-1)*sizeof(WCHAR), NULL, FILE_BEGIN);
+	GetNextChar();
+}
+
+/**
+AddLanguage: Updates the language list structure
+
+@internalComponent
+@released
+
+@param aLang - Name of the language
+@param aCode - Language code
+@param aDialect - Language dialect code
+*/
+void PkgParser::AddLanguage(String aLang, unsigned long aCode, unsigned long aDialect)
+{
+	PLANG_LIST lc = new LANG_LIST;
+	
+	lc->langName = aLang;
+	lc->langCode = aCode;
+	lc->dialectCode = aDialect;
+
+	iLangList.push_back(lc);
+}
+
+/**
+DeleteAll: Deallocates memory for the data members
+
+@internalComponent
+@released
+*/
+void PkgParser::DeleteAll()
+{
+	while(iPkgBlock.size() > 0)
+	{
+		PCMD_BLOCK ptemp = 0;
+
+		ptemp = iPkgBlock.front();
+		iPkgBlock.pop_front();
+
+		if(ptemp->cmdType == INSTALLFILE)
+		{
+			delete ptemp->iInstallFileList;
+		}
+		delete ptemp;
+	}
+
+	{
+		LANGUAGE_LIST::iterator begin = iLangList.begin();
+		LANGUAGE_LIST::iterator end = iLangList.end();
+		while(begin != end)
+		{
+			PLANG_LIST ptemp = 0;
+			ptemp = (*begin);
+
+			if(ptemp)
+				delete ptemp;
+			++begin;
+		}
+		iLangList.clear();
+	}
+}
+
+/**
+ParserError: Throws exception with the given error message
+
+@internalComponent
+@released
+
+@param msg - error message to be thrown
+*/
+void PkgParser::ParserError(char* msg)
+{
+	std::ostringstream str;
+
+	str << (char*)iPkgFile.data() << "(" << m_nLineNo << "): " << msg;
+
+	throw SisUtilsException("PakageFile-Parser Error", (char*)(str.str()).data());
+}
+
+/**
+wstring2string: Converts wide string to string
+
+@internalComponent
+@released
+
+@param aWide - input wide string
+*/
+String wstring2string (const std::wstring& aWide)
+{
+	int max = ::WideCharToMultiByte(CP_OEMCP,0,aWide.c_str(),aWide.length(),0,0,0,0);
+	String reply;
+	if (max > 0 )
+	{
+		char* buffer = new char [max];
+		try
+		{
+			::WideCharToMultiByte(CP_OEMCP,0,aWide.c_str(),aWide.length(),buffer,max,0,0);
+			reply = String (buffer, max);
+		}
+		catch (...)
+		{
+			throw SisUtilsException("ParserError", "wstring to string conversion failed");
+		}
+		delete [] buffer;
+	}
+	return reply;
+}
+
+/**
+string2wstring: Converts string to wide string
+
+@internalComponent
+@released
+
+@param aNarrow - input string
+*/
+std::wstring string2wstring (const String& aNarrow)
+{
+	int max = ::MultiByteToWideChar(CP_OEMCP,0,aNarrow.c_str(),aNarrow.length(),0,0);
+	std::wstring reply;
+	if (max > 0 )
+	{
+		wchar_t* buffer = new wchar_t [max];
+		try
+		{
+			::MultiByteToWideChar(CP_OEMCP,0,aNarrow.c_str(),aNarrow.length(),buffer,max);
+			reply = std::wstring (buffer, max);
+		}
+		catch (...)
+		{
+			throw SisUtilsException("ParserError", "string to wstring conversion failed");
+		}
+		delete [] buffer;
+	}
+	return reply;
+}
+
+/**
+CompareTwoString: Compares two wide string
+
+@internalComponent
+@released
+
+@param string - first string
+@param option - second string
+*/
+int CompareTwoString(wchar_t* string ,wchar_t* option)
+{
+	return wcsicmp(string,option);
+}
+
+/**
+CompareNString: Compares two wide string for n characters
+
+@internalComponent
+@released
+
+@param string - first string
+@param option - second string
+@param len - no of wide characters to be compared
+*/
+int CompareNString(wchar_t* string ,wchar_t* option, int len)
+{
+	return wcsnicmp(string,option,len);
+}