|
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 |