secureswitools/swisistools/source/sisxlibrary/sisexpression.cpp
changeset 0 ba25891c3a9e
child 24 5cc91383ab1e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/secureswitools/swisistools/source/sisxlibrary/sisexpression.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,632 @@
+/*
+* Copyright (c) 2004-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: 
+*
+*/
+
+
+/**
+ @file 
+ @internalComponent
+ @released
+*/
+
+#include "sisexpression.h"
+#include "utility.h"
+#include <hal_data.h>
+
+#define LANGUAGE_VARIABLE	L"LANGUAGE"
+
+
+const SKeyword KVariables [] =
+	{
+		{L"MANUFACTURER",				HALData::EManufacturer},
+		{L"MANUFACTURERHARDWAREREV",	HALData::EManufacturerHardwareRev},
+		{L"MANUFACTURERSOFTWAREREV",	HALData::EManufacturerSoftwareRev},
+		{L"MANUFACTURERSOFTWAREBUILD",	HALData::EManufacturerSoftwareBuild},
+		{L"MODEL",						HALData::EModel},
+		{L"MACHINEUID",					HALData::EMachineUid},
+		{L"DEVICEFAMILY",				HALData::EDeviceFamily},
+		{L"DEVICEFAMILYREV",			HALData::EDeviceFamilyRev},
+		{L"CPU",						HALData::ECPU},
+		{L"CPUARCH",					HALData::ECPUArch},
+		{L"CPUABI",						HALData::ECPUABI},
+		{L"CPUSPEED",					HALData::ECPUSpeed},
+		//{L"SystemStartupReason",		HALData::ESystemStartupReason},
+		//{L"SystemException",			HALData::ESystemException},
+		{L"SYSTEMTICKPERIOD",			HALData::ESystemTickPeriod},
+		{L"MEMORYRAM",					HALData::EMemoryRAM},
+		{L"MEMORYRAMFREE",				HALData::EMemoryRAMFree},
+		{L"MEMORYROM",					HALData::EMemoryROM},
+		{L"MEMORYPAGESIZE",				HALData::EMemoryPageSize},
+		//{L"PowerGood",				HALData::EPowerGood},
+		//{L"PowerBatteryGood",			HALData::EPowerBatteryGood},
+		{L"POWERBACKUP",				HALData::EPowerBackup},
+		//{L"PowerBackupGood",			HALData::EPowerBackupGood},
+		//{L"PowerExternal",				HALData::EPowerExternal},
+		{L"KEYBOARD",					HALData::EKeyboard},
+		{L"KEYBOARDDEVICEKEYS",			HALData::EKeyboardDeviceKeys},
+		{L"KEYBOARDAPPKEYS",			HALData::EKeyboardAppKeys},
+		{L"KEYBOARDCLICK",				HALData::EKeyboardClick},
+		//{L"KeyboardClickState",		HALData::EKeyboardClickState},
+		//{L"KeyboardClickVolume",		HALData::EKeyboardClickVolume},
+		{L"KEYBOARDCLICKVOLUMEMAX",		HALData::EKeyboardClickVolumeMax},
+		{L"DISPLAYXPIXELS",				HALData::EDisplayXPixels},
+		{L"DISPLAYYPIXELS",				HALData::EDisplayYPixels},
+		{L"DISPLAYXTWIPS",				HALData::EDisplayXTwips},
+		{L"DISPLAYYTWIPS",				HALData::EDisplayYTwips},
+		{L"DISPLAYCOLORS",				HALData::EDisplayColors},
+		//{L"DisplayState",				HALData::EDisplayState},
+		//{L"DisplayContrast",			HALData::EDisplayContrast},
+		{L"DISPLAYCONTRASTMAX",			HALData::EDisplayContrastMax},
+		{L"BACKLIGHT",					HALData::EBacklight},
+		//{L"BacklightState",			HALData::EBacklightState},
+		{L"PEN",						HALData::EPen},
+		{L"PENX",						HALData::EPenX},
+		{L"PENY",						HALData::EPenY},
+		{L"PENDISPLAYON",				HALData::EPenDisplayOn},
+		{L"PENCLICK",					HALData::EPenClick},
+		//{L"PenClickState",			HALData::EPenClickState},
+		//{L"PenClickVolume",			HALData::EPenClickVolume},
+		{L"PENCLICKVOLUMEMAX",			HALData::EPenClickVolumeMax},
+		{L"MOUSE",						HALData::EMouse},
+		{L"MOUSEX",						HALData::EMouseX},
+		{L"MOUSEY",						HALData::EMouseY},
+		//{L"MouseState",				HALData::EMouseState},
+		//{L"MouseSpeed",				HALData::EMouseSpeed},
+		//{L"MouseAcceleration",		HALData::EMouseAcceleration},
+		{L"MOUSEBUTTONS",				HALData::EMouseButtons},
+		//{L"MouseButtonState",			HALData::EMouseButtonState},
+		//{L"CaseState",					HALData::ECaseState},
+		{L"CASESWITCH",					HALData::ECaseSwitch},
+		//{L"CaseSwitchDisplayOn",		HALData::ECaseSwitchDisplayOn},
+		//{L"CaseSwitchDisplayOff",		HALData::ECaseSwitchDisplayOff},
+		{L"LEDS",						HALData::ELEDs},
+		//{L"LEDmask",					HALData::ELEDmask},
+		{L"INTEGRATEDPHONE",			HALData::EIntegratedPhone},
+		{L"DISPLAYBRIGHTNESS",			HALData::EDisplayBrightness},
+		{L"DISPLAYBRIGHTNESSMAX",		HALData::EDisplayBrightnessMax},
+		{L"KEYBOARDBACKLIGHTSTATE",		HALData::EKeyboardBacklightState},
+		{L"ACCESSORYPOWER",				HALData::EAccessoryPower},
+		{L"SYSTEMDRIVE",				HALData::ESystemDrive},
+		
+		{L"FPHARDWARE",					HALData::EHardwareFloatingPoint},		
+		{L"NUMHALATTRIBUTES",			HALData::ENumHalAttributes},
+
+		{LANGUAGE_VARIABLE,				EVarLanguage},
+		{L"REMOTEINSTALL",				EVarRemoteInstall},
+
+		{NULL,							0}
+	};
+
+
+struct TExpressionFeatures
+	{
+	bool			iLeftNeeded;
+	bool			iRightNeeded;
+	bool			iStringNeeded;
+	bool			iNumberNeeded;
+	const wchar_t*	iName;
+	};
+
+static TExpressionFeatures expressionFeatures[] =
+	{
+		// Left	Right	String	Number	Name
+		{true,	true,	false,	false,	L"="		},	 //EBinOpEqual
+		{true,	true,	false,	false,	L"<>"		},	//EBinOpNotEqual
+		{true,	true,	false,	false,	L">"		},	//EBinOpGreaterThan
+		{true,	true,	false,	false,	L"<"		},	//EBinOpLessThan
+		{true,	true,	false,	false,	L">="		},	//EBinOpGreaterThanOrEqual
+		{true,	true,	false,	false,	L"<="		},	//EBinOpLessThanOrEqual
+		{true,	true,	false,	false,	L"AND"		},	//ELogOpAnd
+		{true,	true,	false,	false,	L"OR"		},	//ELogOpOr
+		{false,	true,	false,	false,	L"NOT"		},	//EUnaryOpNot
+		{false,	false,	true,	false,	L"exists"	},	//EFuncExists
+		{true,	true,	false,	false,	L"appprop"	},	//EFuncAppProperties
+		{false,	true,	false,	false,	L"package"	},	//EFuncDevProperties
+		{false,	false,	true,	false,	L""			},	//EPrimTypeString
+		{false,	false,	false,	true,	L"option"	},	//EPrimTypeOption
+		{false,	false,	false,	true,	L""			},	//EPrimTypeVariable
+		{false,	false,	false,	true,	L""			}	//EPrimTypeNumber
+	};
+
+TExpressionFeatures* findExpressionFeature (TUint32 aOperator)
+	{
+	if(aOperator <= CSISExpression::EOpNone ||aOperator >= CSISExpression::EOpUnknown)
+		{
+		return NULL;
+		}
+	return &expressionFeatures[aOperator-1];
+	}
+
+
+
+void CSISExpression::InsertMembers ()
+	{
+	InsertMember (iOperator);
+	InsertMember (iInteger);
+	InsertMember (iString);
+	InsertMember (iLeaf);
+	}
+
+
+CSISExpression::CSISExpression (const CSISExpression& aExpression) :
+		CStructure <CSISFieldRoot::ESISExpression> (aExpression),
+		iOperator (aExpression.iOperator),
+		iInteger (aExpression.iInteger),
+		iString (aExpression.iString),
+		iLeaf (aExpression.iLeaf)					
+	{ 
+	InsertMembers (); 
+	}
+
+
+void CSISExpression::Verify (const TUint32 aLanguages) const
+	{
+	CStructure <CSISFieldRoot::ESISExpression>::Verify (aLanguages);
+	assert (iLeaf.size () < 3);
+	CSISException::ThrowIf (	static_cast <TOperator> (iOperator.Value ()) > EOpUnknown,
+								CSISException::EVerification,
+								"illegal or unknown operator");
+	}
+
+
+CSISExpression& CSISExpression::operator = (const CSISExpression& aExpression)
+	{
+	iOperator = aExpression.iOperator;
+	iInteger = aExpression.iInteger;
+	iString = aExpression.iString;
+	iLeaf.clear ();
+	iLeaf.assign (aExpression.iLeaf.begin (), aExpression.iLeaf.end ());
+	return *this;
+	}
+
+
+void CSISExpression::SetOperator (const TOperator aOperator, const CSISExpression& aLHS)	
+	{
+	switch (aOperator)
+		{
+	case EBinOpEqual :
+	case EBinOpNotEqual :
+	case EBinOpGreaterThan :
+	case EBinOpLessThan :
+	case EBinOpGreaterThanOrEqual :
+	case EBinOpLessThanOrEqual :
+	case ELogOpAnd :
+	case ELogOpOr :
+	case EFuncAppProperties :
+		{
+		AddLeaf (aLHS);
+		AddLeaf ();
+		break;
+		}
+
+	case EUnaryOpNot :
+	case EFuncDevProperties :
+		{
+		AddLeaf (aLHS);
+		break;
+		}
+
+	case EPrimTypeString :
+	case EFuncExists :
+		{
+		iString.SetRequired(true);
+		break;
+		}
+
+	case EPrimTypeVariable :
+	case EPrimTypeOption :
+	case EPrimTypeNumber :
+		{
+		break;
+		}
+
+	default :
+		{
+		assert (false);	
+		}
+		}
+	iOperator = aOperator; 
+	assert (iLeaf.size () < 3);
+	}
+
+
+void CSISExpression::SetLanguageComparision (const TInt32 aValue)
+	{
+	AddLeaf ();
+	AddLeaf ();
+	LHS ().SetOperator (EPrimTypeVariable);
+	LHS ().SetLanguage ();
+	RHS ().SetOperator (EPrimTypeNumber);
+	RHS ().SetNumeric (aValue);
+	iOperator =	EBinOpEqual;
+	}
+
+
+void CSISExpression::SetLanguage ()
+	{
+	iOperator =	EPrimTypeVariable;
+	iInteger = EVarLanguage;
+	}
+
+
+void CSISExpression::SetVariable (const std::wstring& aIdentifier)
+	{
+	SetOperator (CSISExpression::EPrimTypeVariable);
+	SetValue (static_cast <TUint32> (IdentifyUCKeyword (KVariables, aIdentifier, L"unknown variable")));
+	}
+
+void CSISExpression::AddPackageEntry(std::wostream& aStream, bool aVerbose) const
+	{
+	TExpressionFeatures* features = findExpressionFeature (iOperator);
+	if(NULL == features)
+		{
+		aStream << L"UNKNOWN";
+		return;
+		}
+	
+	if (features->iLeftNeeded)
+		{
+		aStream << L"(";
+		if(iOperator.Value() == EFuncExists)
+			{
+			aStream << L"\"";
+			}
+
+		LHS().AddPackageEntry(aStream, aVerbose);
+		if(iOperator.Value() == EFuncExists)
+			{
+			aStream << L"\"";
+			}
+		aStream << L")";
+		}
+	
+	std::wstring versionStr = iString.GetString().substr(0,KFuncVersionPrefix.length());
+	std::wstring supportedLanguageStr = iString.GetString().substr(0,KFuncSupportedLanguagePrefix.length());
+	if((iOperator.Value() == EFuncExists) && (versionStr == KFuncVersionPrefix))
+		{
+		WriteVersionCondition (aStream, aVerbose);
+		}
+	else if ((iOperator.Value() == EFuncExists) && (supportedLanguageStr == KFuncSupportedLanguagePrefix))
+		{
+		WriteSupportedLanguageCondition (aStream, aVerbose);
+		}
+	else
+		{	
+		aStream << features->iName;
+		}
+	
+	if (features->iRightNeeded)
+		{
+		aStream << L"(";
+		if(iOperator.Value() == EFuncExists)
+			{
+			aStream << L"\"";
+			}
+
+		RHS().AddPackageEntry(aStream, aVerbose);
+		if(iOperator.Value() == EFuncExists)
+			{
+			aStream << L"\"";
+			}
+		aStream << L")";
+		}
+
+	if (features->iStringNeeded)
+		{
+		if(((iOperator.Value() == EFuncExists) && (versionStr != KFuncVersionPrefix)) && ((iOperator.Value() == EFuncExists) && (supportedLanguageStr != KFuncSupportedLanguagePrefix)))
+			{
+			aStream << L"(";
+
+			if(iOperator.Value() == EFuncExists)
+				{
+				aStream << L"\"";
+				}
+			
+			iString.AddPackageEntry(aStream, aVerbose);
+			if(iOperator.Value() == EFuncExists)
+				{
+				aStream << L"\"";
+				}
+			aStream << L")";
+			}
+		}
+	
+	if (features->iNumberNeeded)
+		{
+		if(iOperator.Value() == EPrimTypeVariable)
+			{
+			if(iInteger.Value() == EVarLanguage)
+				{
+				aStream << L"LANGUAGE";
+				}
+			else
+				{
+				for (int i=0; KVariables[i].iName != NULL; ++i)
+					{
+					if (KVariables[i].iId == iInteger)
+						{
+						aStream << KVariables[i].iName;
+						}
+					}
+				}
+			}
+		else
+			{
+			aStream << iInteger;
+			}
+		}
+	}
+
+void CSISExpression::WriteVersionCondition(std::basic_ostream<wchar_t>& aStream, bool aVerbose) const
+	{
+	std::wstring parseString = iString.GetString().substr(KFuncVersionPrefix.length());
+	std::wstring outputArgs;
+
+	try
+		{
+		// *** Parse Package UID Argument ***
+		std::wstring packageUidStr;
+		if(!ExtractNextToken(parseString,packageUidStr))
+			{
+			throw "Failed to Parse Package UID";
+			}
+		
+		// Package UID format checking
+		packageUidStr[1] = tolower(packageUidStr[1]);
+		if(packageUidStr.find(L"0x") != 0 || packageUidStr.length() != 10)
+			{
+			throw "Invalid Package UID Format";
+			}
+
+		// Check that the UID string can be converted to Hexadecimal
+		if(!IsHexadecimal(packageUidStr.substr(2)))
+			{
+			throw "Package UID contains non hexadecimal characters";
+			}
+
+		// Update Condition Output 
+		outputArgs.append(packageUidStr);
+		outputArgs.append(L",");
+		
+		
+		// *** Parse Relational Operator ***
+		std::wstring relationOpStr;
+		if(!ExtractNextToken(parseString,relationOpStr))
+			{
+			throw "Failed to Parse the Relational Operator";
+			}
+
+		// Update the condition argument string as necessary depending on the operator code
+		if(relationOpStr == L"ET") 
+			{
+			outputArgs.append(L"=");
+			}
+		else if(relationOpStr == L"LT")
+			{
+			outputArgs.append(L"<");
+			}
+		else if(relationOpStr == L"LE") 
+			{
+			outputArgs.append(L"<=");
+			}
+		else if(relationOpStr == L"GT")
+			{
+			outputArgs.append(L">");
+			}
+		else if(relationOpStr == L"GE") 
+			{
+			outputArgs.append(L">=");
+			}
+		else if(relationOpStr == L"NE")
+			{
+			outputArgs.append(L"<>");
+			}
+		else 
+			{
+			// If the operator is not recognised, throw an exception
+			throw "Invalid Relational Operator";
+			}
+
+		// Update Condition Output
+		outputArgs.append(L",");
+
+
+		// *** Parse Major Version Component ***
+		std::wstring vMajorStr;
+		if(!ExtractNextToken(parseString,vMajorStr))
+			{
+			throw "Failed to parse the MAJOR version component";
+			}
+
+		// Check and convert the wstring to an integer
+		TInt vMajor;
+		if(!IsDecimal(vMajorStr,vMajor))
+			{
+			throw "MAJOR version component contains non numeric characters (0-9)";
+			}
+
+		// Check the Major component value lies within range
+		if(vMajor < 0 || vMajor > 127)
+			{
+			throw "MAJOR version component out of range (0 - 127)";
+			}
+
+		// Update Condition Output
+		outputArgs.append(vMajorStr);
+		outputArgs.append(L",");
+
+
+		// *** Parse Minor Version Component ***
+		std::wstring vMinorStr;
+		if(!ExtractNextToken(parseString,vMinorStr))
+			{
+			throw "Failed to parse the MINOR version component";
+			}
+
+		// Check and convert the wstring to an integer
+		TInt vMinor;
+		if(!IsDecimal(vMinorStr,vMinor))
+			{
+			throw "MINOR version component contains non numeric characters (0-9)";
+			}
+		
+		// Check the Minor component value lies within range
+		if(vMinor < 0 || vMinor > 99)
+			{
+			throw "MINOR version component out of range (0 - 99)";
+			}
+
+		// Update Condition Output
+		outputArgs.append(vMinorStr);
+		outputArgs.append(L",");
+
+
+		// *** Parse Build Version Component ***
+		std::wstring vBuildStr(parseString); 
+
+		// Check and convert the wstring to an integer
+		TInt vBuild;
+		if(!IsDecimal(vBuildStr,vBuild))
+			{
+			throw "BUILD version component contains non numeric characters (0-9)";
+			}
+
+		// Check the Build component value lies within range
+		if(vBuild < 0 || vBuild > 32767)
+			{
+			throw "BUILD version component out of range (0 - 32767)";
+			}
+
+		// Update Condition Output
+		outputArgs.append(vBuildStr);
+
+		// Output the successfully parsed version condition to the stream
+		aStream << L"version(";
+		aStream << outputArgs;
+		aStream << L")";
+		}
+	catch(const char* aWarnMsg) 
+		{
+		// Convert Char* into a wstring 
+		TInt bufferLength = strlen(aWarnMsg);
+		wchar_t* buffer = new wchar_t[bufferLength+1];
+
+		mbstowcs(buffer,aWarnMsg,bufferLength+1);
+		std::wstring msgString(buffer);
+		delete buffer;
+
+		// Output the condition as an exists statement and comment warnings to the stream
+		aStream << L"exists(\"";
+		iString.AddPackageEntry(aStream, aVerbose);
+		aStream << L"\")" << std::endl;
+		aStream << L"; warning: \"VERSION\" condition output as \"EXISTS\"" << std::endl;
+		aStream << L"; " << msgString;
+		}
+	}
+
+bool CSISExpression::ExtractNextToken(std::wstring& aParseString, std::wstring& aTokenString)
+	{
+	TInt separatorPosition = aParseString.find(L",");
+
+	// Check that a separator was located within the parse string
+	if(separatorPosition == -1 || separatorPosition > aParseString.length()-1)
+		{
+		return false;
+		}
+
+	// Set the extracted token string and remove the token from the parse string
+	aTokenString = aParseString.substr(0,separatorPosition);
+	aParseString = aParseString.substr(separatorPosition + 1);
+
+	return true;
+	}
+
+bool CSISExpression::IsHexadecimal(const std::wstring& aString)
+	{
+	TUint32 i;
+	return IsHexadecimal(aString,i);
+	}
+
+bool CSISExpression::IsHexadecimal(const std::wstring& aString, TUint32& aHexValue)
+	{
+	if(aString.size() == 0)
+		{
+		return false;
+		}
+
+	std::wistringstream wStrStream(aString);
+
+	if((wStrStream >> std::hex >> aHexValue) && wStrStream.eof())
+		{
+		return true;
+		}
+
+	return false;
+	} 
+
+bool CSISExpression::IsDecimal(const std::wstring& aString, TInt& aDecimalValue)
+	{
+	if(aString.size() == 0)
+		{
+		return false;
+		}
+
+	std::wistringstream wStrStream(aString);
+
+	if((wStrStream >> std::dec >> aDecimalValue) && wStrStream.eof())
+		{
+		return true;
+		}
+
+	return false;
+	}
+
+void CSISExpression::WriteSupportedLanguageCondition(std::basic_ostream<wchar_t>& aStream, bool aVerbose) const
+	{
+	std::wstring parseString = iString.GetString().substr(KFuncSupportedLanguagePrefix.length());
+	std::wstring outputArgs;
+	try
+		{
+		// Check and convert the wstring to an integer
+		TInt vLanguageId;
+		if(!IsDecimal(parseString,vLanguageId))
+			{
+			throw "Supported_Language option contains non-numeric value";
+			}
+		// Output the successfully parsed version condition to the stream
+		aStream << L"Supported_Language = ";
+		aStream << vLanguageId;
+
+		}
+	catch(const char* aWarnMsg) 
+		{
+		// Convert Char* into a wstring 
+		TInt bufferLength = strlen(aWarnMsg);
+		wchar_t* buffer = new wchar_t[bufferLength+1];
+
+		mbstowcs(buffer,aWarnMsg,bufferLength+1);
+		std::wstring msgString(buffer);
+		delete buffer;
+
+		// Output the condition as an exists statement and comment warnings to the stream
+		aStream << L"exists(\"";
+		iString.AddPackageEntry(aStream, aVerbose);
+		aStream << L"\")" << std::endl;
+		aStream << L"; warning: \"Supported_Language\" condition output as \"EXISTS\"" << std::endl;
+		aStream << L"; " << msgString;
+		}
+	}
+