diff -r 000000000000 -r ba25891c3a9e secureswitools/swisistools/source/sisxlibrary/sisexpression.cpp --- /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 + +#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 (aExpression), + iOperator (aExpression.iOperator), + iInteger (aExpression.iInteger), + iString (aExpression.iString), + iLeaf (aExpression.iLeaf) + { + InsertMembers (); + } + + +void CSISExpression::Verify (const TUint32 aLanguages) const + { + CStructure ::Verify (aLanguages); + assert (iLeaf.size () < 3); + CSISException::ThrowIf ( static_cast (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 (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& 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& 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; + } + } +