secureswitools/swisistools/source/sisxlibrary/sisexpression.cpp
changeset 0 ba25891c3a9e
child 24 5cc91383ab1e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 /**
       
    20  @file 
       
    21  @internalComponent
       
    22  @released
       
    23 */
       
    24 
       
    25 #include "sisexpression.h"
       
    26 #include "utility.h"
       
    27 #include <hal_data.h>
       
    28 
       
    29 #define LANGUAGE_VARIABLE	L"LANGUAGE"
       
    30 
       
    31 
       
    32 const SKeyword KVariables [] =
       
    33 	{
       
    34 		{L"MANUFACTURER",				HALData::EManufacturer},
       
    35 		{L"MANUFACTURERHARDWAREREV",	HALData::EManufacturerHardwareRev},
       
    36 		{L"MANUFACTURERSOFTWAREREV",	HALData::EManufacturerSoftwareRev},
       
    37 		{L"MANUFACTURERSOFTWAREBUILD",	HALData::EManufacturerSoftwareBuild},
       
    38 		{L"MODEL",						HALData::EModel},
       
    39 		{L"MACHINEUID",					HALData::EMachineUid},
       
    40 		{L"DEVICEFAMILY",				HALData::EDeviceFamily},
       
    41 		{L"DEVICEFAMILYREV",			HALData::EDeviceFamilyRev},
       
    42 		{L"CPU",						HALData::ECPU},
       
    43 		{L"CPUARCH",					HALData::ECPUArch},
       
    44 		{L"CPUABI",						HALData::ECPUABI},
       
    45 		{L"CPUSPEED",					HALData::ECPUSpeed},
       
    46 		//{L"SystemStartupReason",		HALData::ESystemStartupReason},
       
    47 		//{L"SystemException",			HALData::ESystemException},
       
    48 		{L"SYSTEMTICKPERIOD",			HALData::ESystemTickPeriod},
       
    49 		{L"MEMORYRAM",					HALData::EMemoryRAM},
       
    50 		{L"MEMORYRAMFREE",				HALData::EMemoryRAMFree},
       
    51 		{L"MEMORYROM",					HALData::EMemoryROM},
       
    52 		{L"MEMORYPAGESIZE",				HALData::EMemoryPageSize},
       
    53 		//{L"PowerGood",				HALData::EPowerGood},
       
    54 		//{L"PowerBatteryGood",			HALData::EPowerBatteryGood},
       
    55 		{L"POWERBACKUP",				HALData::EPowerBackup},
       
    56 		//{L"PowerBackupGood",			HALData::EPowerBackupGood},
       
    57 		//{L"PowerExternal",				HALData::EPowerExternal},
       
    58 		{L"KEYBOARD",					HALData::EKeyboard},
       
    59 		{L"KEYBOARDDEVICEKEYS",			HALData::EKeyboardDeviceKeys},
       
    60 		{L"KEYBOARDAPPKEYS",			HALData::EKeyboardAppKeys},
       
    61 		{L"KEYBOARDCLICK",				HALData::EKeyboardClick},
       
    62 		//{L"KeyboardClickState",		HALData::EKeyboardClickState},
       
    63 		//{L"KeyboardClickVolume",		HALData::EKeyboardClickVolume},
       
    64 		{L"KEYBOARDCLICKVOLUMEMAX",		HALData::EKeyboardClickVolumeMax},
       
    65 		{L"DISPLAYXPIXELS",				HALData::EDisplayXPixels},
       
    66 		{L"DISPLAYYPIXELS",				HALData::EDisplayYPixels},
       
    67 		{L"DISPLAYXTWIPS",				HALData::EDisplayXTwips},
       
    68 		{L"DISPLAYYTWIPS",				HALData::EDisplayYTwips},
       
    69 		{L"DISPLAYCOLORS",				HALData::EDisplayColors},
       
    70 		//{L"DisplayState",				HALData::EDisplayState},
       
    71 		//{L"DisplayContrast",			HALData::EDisplayContrast},
       
    72 		{L"DISPLAYCONTRASTMAX",			HALData::EDisplayContrastMax},
       
    73 		{L"BACKLIGHT",					HALData::EBacklight},
       
    74 		//{L"BacklightState",			HALData::EBacklightState},
       
    75 		{L"PEN",						HALData::EPen},
       
    76 		{L"PENX",						HALData::EPenX},
       
    77 		{L"PENY",						HALData::EPenY},
       
    78 		{L"PENDISPLAYON",				HALData::EPenDisplayOn},
       
    79 		{L"PENCLICK",					HALData::EPenClick},
       
    80 		//{L"PenClickState",			HALData::EPenClickState},
       
    81 		//{L"PenClickVolume",			HALData::EPenClickVolume},
       
    82 		{L"PENCLICKVOLUMEMAX",			HALData::EPenClickVolumeMax},
       
    83 		{L"MOUSE",						HALData::EMouse},
       
    84 		{L"MOUSEX",						HALData::EMouseX},
       
    85 		{L"MOUSEY",						HALData::EMouseY},
       
    86 		//{L"MouseState",				HALData::EMouseState},
       
    87 		//{L"MouseSpeed",				HALData::EMouseSpeed},
       
    88 		//{L"MouseAcceleration",		HALData::EMouseAcceleration},
       
    89 		{L"MOUSEBUTTONS",				HALData::EMouseButtons},
       
    90 		//{L"MouseButtonState",			HALData::EMouseButtonState},
       
    91 		//{L"CaseState",					HALData::ECaseState},
       
    92 		{L"CASESWITCH",					HALData::ECaseSwitch},
       
    93 		//{L"CaseSwitchDisplayOn",		HALData::ECaseSwitchDisplayOn},
       
    94 		//{L"CaseSwitchDisplayOff",		HALData::ECaseSwitchDisplayOff},
       
    95 		{L"LEDS",						HALData::ELEDs},
       
    96 		//{L"LEDmask",					HALData::ELEDmask},
       
    97 		{L"INTEGRATEDPHONE",			HALData::EIntegratedPhone},
       
    98 		{L"DISPLAYBRIGHTNESS",			HALData::EDisplayBrightness},
       
    99 		{L"DISPLAYBRIGHTNESSMAX",		HALData::EDisplayBrightnessMax},
       
   100 		{L"KEYBOARDBACKLIGHTSTATE",		HALData::EKeyboardBacklightState},
       
   101 		{L"ACCESSORYPOWER",				HALData::EAccessoryPower},
       
   102 		{L"SYSTEMDRIVE",				HALData::ESystemDrive},
       
   103 		
       
   104 		{L"FPHARDWARE",					HALData::EHardwareFloatingPoint},		
       
   105 		{L"NUMHALATTRIBUTES",			HALData::ENumHalAttributes},
       
   106 
       
   107 		{LANGUAGE_VARIABLE,				EVarLanguage},
       
   108 		{L"REMOTEINSTALL",				EVarRemoteInstall},
       
   109 
       
   110 		{NULL,							0}
       
   111 	};
       
   112 
       
   113 
       
   114 struct TExpressionFeatures
       
   115 	{
       
   116 	bool			iLeftNeeded;
       
   117 	bool			iRightNeeded;
       
   118 	bool			iStringNeeded;
       
   119 	bool			iNumberNeeded;
       
   120 	const wchar_t*	iName;
       
   121 	};
       
   122 
       
   123 static TExpressionFeatures expressionFeatures[] =
       
   124 	{
       
   125 		// Left	Right	String	Number	Name
       
   126 		{true,	true,	false,	false,	L"="		},	 //EBinOpEqual
       
   127 		{true,	true,	false,	false,	L"<>"		},	//EBinOpNotEqual
       
   128 		{true,	true,	false,	false,	L">"		},	//EBinOpGreaterThan
       
   129 		{true,	true,	false,	false,	L"<"		},	//EBinOpLessThan
       
   130 		{true,	true,	false,	false,	L">="		},	//EBinOpGreaterThanOrEqual
       
   131 		{true,	true,	false,	false,	L"<="		},	//EBinOpLessThanOrEqual
       
   132 		{true,	true,	false,	false,	L"AND"		},	//ELogOpAnd
       
   133 		{true,	true,	false,	false,	L"OR"		},	//ELogOpOr
       
   134 		{false,	true,	false,	false,	L"NOT"		},	//EUnaryOpNot
       
   135 		{false,	false,	true,	false,	L"exists"	},	//EFuncExists
       
   136 		{true,	true,	false,	false,	L"appprop"	},	//EFuncAppProperties
       
   137 		{false,	true,	false,	false,	L"package"	},	//EFuncDevProperties
       
   138 		{false,	false,	true,	false,	L""			},	//EPrimTypeString
       
   139 		{false,	false,	false,	true,	L"option"	},	//EPrimTypeOption
       
   140 		{false,	false,	false,	true,	L""			},	//EPrimTypeVariable
       
   141 		{false,	false,	false,	true,	L""			}	//EPrimTypeNumber
       
   142 	};
       
   143 
       
   144 TExpressionFeatures* findExpressionFeature (TUint32 aOperator)
       
   145 	{
       
   146 	if(aOperator <= CSISExpression::EOpNone ||aOperator >= CSISExpression::EOpUnknown)
       
   147 		{
       
   148 		return NULL;
       
   149 		}
       
   150 	return &expressionFeatures[aOperator-1];
       
   151 	}
       
   152 
       
   153 
       
   154 
       
   155 void CSISExpression::InsertMembers ()
       
   156 	{
       
   157 	InsertMember (iOperator);
       
   158 	InsertMember (iInteger);
       
   159 	InsertMember (iString);
       
   160 	InsertMember (iLeaf);
       
   161 	}
       
   162 
       
   163 
       
   164 CSISExpression::CSISExpression (const CSISExpression& aExpression) :
       
   165 		CStructure <CSISFieldRoot::ESISExpression> (aExpression),
       
   166 		iOperator (aExpression.iOperator),
       
   167 		iInteger (aExpression.iInteger),
       
   168 		iString (aExpression.iString),
       
   169 		iLeaf (aExpression.iLeaf)					
       
   170 	{ 
       
   171 	InsertMembers (); 
       
   172 	}
       
   173 
       
   174 
       
   175 void CSISExpression::Verify (const TUint32 aLanguages) const
       
   176 	{
       
   177 	CStructure <CSISFieldRoot::ESISExpression>::Verify (aLanguages);
       
   178 	assert (iLeaf.size () < 3);
       
   179 	CSISException::ThrowIf (	static_cast <TOperator> (iOperator.Value ()) > EOpUnknown,
       
   180 								CSISException::EVerification,
       
   181 								"illegal or unknown operator");
       
   182 	}
       
   183 
       
   184 
       
   185 CSISExpression& CSISExpression::operator = (const CSISExpression& aExpression)
       
   186 	{
       
   187 	iOperator = aExpression.iOperator;
       
   188 	iInteger = aExpression.iInteger;
       
   189 	iString = aExpression.iString;
       
   190 	iLeaf.clear ();
       
   191 	iLeaf.assign (aExpression.iLeaf.begin (), aExpression.iLeaf.end ());
       
   192 	return *this;
       
   193 	}
       
   194 
       
   195 
       
   196 void CSISExpression::SetOperator (const TOperator aOperator, const CSISExpression& aLHS)	
       
   197 	{
       
   198 	switch (aOperator)
       
   199 		{
       
   200 	case EBinOpEqual :
       
   201 	case EBinOpNotEqual :
       
   202 	case EBinOpGreaterThan :
       
   203 	case EBinOpLessThan :
       
   204 	case EBinOpGreaterThanOrEqual :
       
   205 	case EBinOpLessThanOrEqual :
       
   206 	case ELogOpAnd :
       
   207 	case ELogOpOr :
       
   208 	case EFuncAppProperties :
       
   209 		{
       
   210 		AddLeaf (aLHS);
       
   211 		AddLeaf ();
       
   212 		break;
       
   213 		}
       
   214 
       
   215 	case EUnaryOpNot :
       
   216 	case EFuncDevProperties :
       
   217 		{
       
   218 		AddLeaf (aLHS);
       
   219 		break;
       
   220 		}
       
   221 
       
   222 	case EPrimTypeString :
       
   223 	case EFuncExists :
       
   224 		{
       
   225 		iString.SetRequired(true);
       
   226 		break;
       
   227 		}
       
   228 
       
   229 	case EPrimTypeVariable :
       
   230 	case EPrimTypeOption :
       
   231 	case EPrimTypeNumber :
       
   232 		{
       
   233 		break;
       
   234 		}
       
   235 
       
   236 	default :
       
   237 		{
       
   238 		assert (false);	
       
   239 		}
       
   240 		}
       
   241 	iOperator = aOperator; 
       
   242 	assert (iLeaf.size () < 3);
       
   243 	}
       
   244 
       
   245 
       
   246 void CSISExpression::SetLanguageComparision (const TInt32 aValue)
       
   247 	{
       
   248 	AddLeaf ();
       
   249 	AddLeaf ();
       
   250 	LHS ().SetOperator (EPrimTypeVariable);
       
   251 	LHS ().SetLanguage ();
       
   252 	RHS ().SetOperator (EPrimTypeNumber);
       
   253 	RHS ().SetNumeric (aValue);
       
   254 	iOperator =	EBinOpEqual;
       
   255 	}
       
   256 
       
   257 
       
   258 void CSISExpression::SetLanguage ()
       
   259 	{
       
   260 	iOperator =	EPrimTypeVariable;
       
   261 	iInteger = EVarLanguage;
       
   262 	}
       
   263 
       
   264 
       
   265 void CSISExpression::SetVariable (const std::wstring& aIdentifier)
       
   266 	{
       
   267 	SetOperator (CSISExpression::EPrimTypeVariable);
       
   268 	SetValue (static_cast <TUint32> (IdentifyUCKeyword (KVariables, aIdentifier, L"unknown variable")));
       
   269 	}
       
   270 
       
   271 void CSISExpression::AddPackageEntry(std::wostream& aStream, bool aVerbose) const
       
   272 	{
       
   273 	TExpressionFeatures* features = findExpressionFeature (iOperator);
       
   274 	if(NULL == features)
       
   275 		{
       
   276 		aStream << L"UNKNOWN";
       
   277 		return;
       
   278 		}
       
   279 	
       
   280 	if (features->iLeftNeeded)
       
   281 		{
       
   282 		aStream << L"(";
       
   283 		if(iOperator.Value() == EFuncExists)
       
   284 			{
       
   285 			aStream << L"\"";
       
   286 			}
       
   287 
       
   288 		LHS().AddPackageEntry(aStream, aVerbose);
       
   289 		if(iOperator.Value() == EFuncExists)
       
   290 			{
       
   291 			aStream << L"\"";
       
   292 			}
       
   293 		aStream << L")";
       
   294 		}
       
   295 	
       
   296 	std::wstring versionStr = iString.GetString().substr(0,KFuncVersionPrefix.length());
       
   297 	std::wstring supportedLanguageStr = iString.GetString().substr(0,KFuncSupportedLanguagePrefix.length());
       
   298 	if((iOperator.Value() == EFuncExists) && (versionStr == KFuncVersionPrefix))
       
   299 		{
       
   300 		WriteVersionCondition (aStream, aVerbose);
       
   301 		}
       
   302 	else if ((iOperator.Value() == EFuncExists) && (supportedLanguageStr == KFuncSupportedLanguagePrefix))
       
   303 		{
       
   304 		WriteSupportedLanguageCondition (aStream, aVerbose);
       
   305 		}
       
   306 	else
       
   307 		{	
       
   308 		aStream << features->iName;
       
   309 		}
       
   310 	
       
   311 	if (features->iRightNeeded)
       
   312 		{
       
   313 		aStream << L"(";
       
   314 		if(iOperator.Value() == EFuncExists)
       
   315 			{
       
   316 			aStream << L"\"";
       
   317 			}
       
   318 
       
   319 		RHS().AddPackageEntry(aStream, aVerbose);
       
   320 		if(iOperator.Value() == EFuncExists)
       
   321 			{
       
   322 			aStream << L"\"";
       
   323 			}
       
   324 		aStream << L")";
       
   325 		}
       
   326 
       
   327 	if (features->iStringNeeded)
       
   328 		{
       
   329 		if(((iOperator.Value() == EFuncExists) && (versionStr != KFuncVersionPrefix)) && ((iOperator.Value() == EFuncExists) && (supportedLanguageStr != KFuncSupportedLanguagePrefix)))
       
   330 			{
       
   331 			aStream << L"(";
       
   332 
       
   333 			if(iOperator.Value() == EFuncExists)
       
   334 				{
       
   335 				aStream << L"\"";
       
   336 				}
       
   337 			
       
   338 			iString.AddPackageEntry(aStream, aVerbose);
       
   339 			if(iOperator.Value() == EFuncExists)
       
   340 				{
       
   341 				aStream << L"\"";
       
   342 				}
       
   343 			aStream << L")";
       
   344 			}
       
   345 		}
       
   346 	
       
   347 	if (features->iNumberNeeded)
       
   348 		{
       
   349 		if(iOperator.Value() == EPrimTypeVariable)
       
   350 			{
       
   351 			if(iInteger.Value() == EVarLanguage)
       
   352 				{
       
   353 				aStream << L"LANGUAGE";
       
   354 				}
       
   355 			else
       
   356 				{
       
   357 				for (int i=0; KVariables[i].iName != NULL; ++i)
       
   358 					{
       
   359 					if (KVariables[i].iId == iInteger)
       
   360 						{
       
   361 						aStream << KVariables[i].iName;
       
   362 						}
       
   363 					}
       
   364 				}
       
   365 			}
       
   366 		else
       
   367 			{
       
   368 			aStream << iInteger;
       
   369 			}
       
   370 		}
       
   371 	}
       
   372 
       
   373 void CSISExpression::WriteVersionCondition(std::basic_ostream<wchar_t>& aStream, bool aVerbose) const
       
   374 	{
       
   375 	std::wstring parseString = iString.GetString().substr(KFuncVersionPrefix.length());
       
   376 	std::wstring outputArgs;
       
   377 
       
   378 	try
       
   379 		{
       
   380 		// *** Parse Package UID Argument ***
       
   381 		std::wstring packageUidStr;
       
   382 		if(!ExtractNextToken(parseString,packageUidStr))
       
   383 			{
       
   384 			throw "Failed to Parse Package UID";
       
   385 			}
       
   386 		
       
   387 		// Package UID format checking
       
   388 		packageUidStr[1] = tolower(packageUidStr[1]);
       
   389 		if(packageUidStr.find(L"0x") != 0 || packageUidStr.length() != 10)
       
   390 			{
       
   391 			throw "Invalid Package UID Format";
       
   392 			}
       
   393 
       
   394 		// Check that the UID string can be converted to Hexadecimal
       
   395 		if(!IsHexadecimal(packageUidStr.substr(2)))
       
   396 			{
       
   397 			throw "Package UID contains non hexadecimal characters";
       
   398 			}
       
   399 
       
   400 		// Update Condition Output 
       
   401 		outputArgs.append(packageUidStr);
       
   402 		outputArgs.append(L",");
       
   403 		
       
   404 		
       
   405 		// *** Parse Relational Operator ***
       
   406 		std::wstring relationOpStr;
       
   407 		if(!ExtractNextToken(parseString,relationOpStr))
       
   408 			{
       
   409 			throw "Failed to Parse the Relational Operator";
       
   410 			}
       
   411 
       
   412 		// Update the condition argument string as necessary depending on the operator code
       
   413 		if(relationOpStr == L"ET") 
       
   414 			{
       
   415 			outputArgs.append(L"=");
       
   416 			}
       
   417 		else if(relationOpStr == L"LT")
       
   418 			{
       
   419 			outputArgs.append(L"<");
       
   420 			}
       
   421 		else if(relationOpStr == L"LE") 
       
   422 			{
       
   423 			outputArgs.append(L"<=");
       
   424 			}
       
   425 		else if(relationOpStr == L"GT")
       
   426 			{
       
   427 			outputArgs.append(L">");
       
   428 			}
       
   429 		else if(relationOpStr == L"GE") 
       
   430 			{
       
   431 			outputArgs.append(L">=");
       
   432 			}
       
   433 		else if(relationOpStr == L"NE")
       
   434 			{
       
   435 			outputArgs.append(L"<>");
       
   436 			}
       
   437 		else 
       
   438 			{
       
   439 			// If the operator is not recognised, throw an exception
       
   440 			throw "Invalid Relational Operator";
       
   441 			}
       
   442 
       
   443 		// Update Condition Output
       
   444 		outputArgs.append(L",");
       
   445 
       
   446 
       
   447 		// *** Parse Major Version Component ***
       
   448 		std::wstring vMajorStr;
       
   449 		if(!ExtractNextToken(parseString,vMajorStr))
       
   450 			{
       
   451 			throw "Failed to parse the MAJOR version component";
       
   452 			}
       
   453 
       
   454 		// Check and convert the wstring to an integer
       
   455 		TInt vMajor;
       
   456 		if(!IsDecimal(vMajorStr,vMajor))
       
   457 			{
       
   458 			throw "MAJOR version component contains non numeric characters (0-9)";
       
   459 			}
       
   460 
       
   461 		// Check the Major component value lies within range
       
   462 		if(vMajor < 0 || vMajor > 127)
       
   463 			{
       
   464 			throw "MAJOR version component out of range (0 - 127)";
       
   465 			}
       
   466 
       
   467 		// Update Condition Output
       
   468 		outputArgs.append(vMajorStr);
       
   469 		outputArgs.append(L",");
       
   470 
       
   471 
       
   472 		// *** Parse Minor Version Component ***
       
   473 		std::wstring vMinorStr;
       
   474 		if(!ExtractNextToken(parseString,vMinorStr))
       
   475 			{
       
   476 			throw "Failed to parse the MINOR version component";
       
   477 			}
       
   478 
       
   479 		// Check and convert the wstring to an integer
       
   480 		TInt vMinor;
       
   481 		if(!IsDecimal(vMinorStr,vMinor))
       
   482 			{
       
   483 			throw "MINOR version component contains non numeric characters (0-9)";
       
   484 			}
       
   485 		
       
   486 		// Check the Minor component value lies within range
       
   487 		if(vMinor < 0 || vMinor > 99)
       
   488 			{
       
   489 			throw "MINOR version component out of range (0 - 99)";
       
   490 			}
       
   491 
       
   492 		// Update Condition Output
       
   493 		outputArgs.append(vMinorStr);
       
   494 		outputArgs.append(L",");
       
   495 
       
   496 
       
   497 		// *** Parse Build Version Component ***
       
   498 		std::wstring vBuildStr(parseString); 
       
   499 
       
   500 		// Check and convert the wstring to an integer
       
   501 		TInt vBuild;
       
   502 		if(!IsDecimal(vBuildStr,vBuild))
       
   503 			{
       
   504 			throw "BUILD version component contains non numeric characters (0-9)";
       
   505 			}
       
   506 
       
   507 		// Check the Build component value lies within range
       
   508 		if(vBuild < 0 || vBuild > 32767)
       
   509 			{
       
   510 			throw "BUILD version component out of range (0 - 32767)";
       
   511 			}
       
   512 
       
   513 		// Update Condition Output
       
   514 		outputArgs.append(vBuildStr);
       
   515 
       
   516 		// Output the successfully parsed version condition to the stream
       
   517 		aStream << L"version(";
       
   518 		aStream << outputArgs;
       
   519 		aStream << L")";
       
   520 		}
       
   521 	catch(const char* aWarnMsg) 
       
   522 		{
       
   523 		// Convert Char* into a wstring 
       
   524 		TInt bufferLength = strlen(aWarnMsg);
       
   525 		wchar_t* buffer = new wchar_t[bufferLength+1];
       
   526 
       
   527 		mbstowcs(buffer,aWarnMsg,bufferLength+1);
       
   528 		std::wstring msgString(buffer);
       
   529 		delete buffer;
       
   530 
       
   531 		// Output the condition as an exists statement and comment warnings to the stream
       
   532 		aStream << L"exists(\"";
       
   533 		iString.AddPackageEntry(aStream, aVerbose);
       
   534 		aStream << L"\")" << std::endl;
       
   535 		aStream << L"; warning: \"VERSION\" condition output as \"EXISTS\"" << std::endl;
       
   536 		aStream << L"; " << msgString;
       
   537 		}
       
   538 	}
       
   539 
       
   540 bool CSISExpression::ExtractNextToken(std::wstring& aParseString, std::wstring& aTokenString)
       
   541 	{
       
   542 	TInt separatorPosition = aParseString.find(L",");
       
   543 
       
   544 	// Check that a separator was located within the parse string
       
   545 	if(separatorPosition == -1 || separatorPosition > aParseString.length()-1)
       
   546 		{
       
   547 		return false;
       
   548 		}
       
   549 
       
   550 	// Set the extracted token string and remove the token from the parse string
       
   551 	aTokenString = aParseString.substr(0,separatorPosition);
       
   552 	aParseString = aParseString.substr(separatorPosition + 1);
       
   553 
       
   554 	return true;
       
   555 	}
       
   556 
       
   557 bool CSISExpression::IsHexadecimal(const std::wstring& aString)
       
   558 	{
       
   559 	TUint32 i;
       
   560 	return IsHexadecimal(aString,i);
       
   561 	}
       
   562 
       
   563 bool CSISExpression::IsHexadecimal(const std::wstring& aString, TUint32& aHexValue)
       
   564 	{
       
   565 	if(aString.size() == 0)
       
   566 		{
       
   567 		return false;
       
   568 		}
       
   569 
       
   570 	std::wistringstream wStrStream(aString);
       
   571 
       
   572 	if((wStrStream >> std::hex >> aHexValue) && wStrStream.eof())
       
   573 		{
       
   574 		return true;
       
   575 		}
       
   576 
       
   577 	return false;
       
   578 	} 
       
   579 
       
   580 bool CSISExpression::IsDecimal(const std::wstring& aString, TInt& aDecimalValue)
       
   581 	{
       
   582 	if(aString.size() == 0)
       
   583 		{
       
   584 		return false;
       
   585 		}
       
   586 
       
   587 	std::wistringstream wStrStream(aString);
       
   588 
       
   589 	if((wStrStream >> std::dec >> aDecimalValue) && wStrStream.eof())
       
   590 		{
       
   591 		return true;
       
   592 		}
       
   593 
       
   594 	return false;
       
   595 	}
       
   596 
       
   597 void CSISExpression::WriteSupportedLanguageCondition(std::basic_ostream<wchar_t>& aStream, bool aVerbose) const
       
   598 	{
       
   599 	std::wstring parseString = iString.GetString().substr(KFuncSupportedLanguagePrefix.length());
       
   600 	std::wstring outputArgs;
       
   601 	try
       
   602 		{
       
   603 		// Check and convert the wstring to an integer
       
   604 		TInt vLanguageId;
       
   605 		if(!IsDecimal(parseString,vLanguageId))
       
   606 			{
       
   607 			throw "Supported_Language option contains non-numeric value";
       
   608 			}
       
   609 		// Output the successfully parsed version condition to the stream
       
   610 		aStream << L"Supported_Language = ";
       
   611 		aStream << vLanguageId;
       
   612 
       
   613 		}
       
   614 	catch(const char* aWarnMsg) 
       
   615 		{
       
   616 		// Convert Char* into a wstring 
       
   617 		TInt bufferLength = strlen(aWarnMsg);
       
   618 		wchar_t* buffer = new wchar_t[bufferLength+1];
       
   619 
       
   620 		mbstowcs(buffer,aWarnMsg,bufferLength+1);
       
   621 		std::wstring msgString(buffer);
       
   622 		delete buffer;
       
   623 
       
   624 		// Output the condition as an exists statement and comment warnings to the stream
       
   625 		aStream << L"exists(\"";
       
   626 		iString.AddPackageEntry(aStream, aVerbose);
       
   627 		aStream << L"\")" << std::endl;
       
   628 		aStream << L"; warning: \"Supported_Language\" condition output as \"EXISTS\"" << std::endl;
       
   629 		aStream << L"; " << msgString;
       
   630 		}
       
   631 	}
       
   632