2 PlatformPcdPreprocessAction class.
4 The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's
5 pcd build information from fpd file.
6 This class will be extended by building tools and wizard tools.
8 Copyright (c) 2006, Intel Corporation
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 package org
.tianocore
.pcd
.action
;
20 import java
.util
.ArrayList
;
21 import java
.util
.List
;
22 import java
.util
.UUID
;
23 import java
.util
.regex
.Matcher
;
24 import java
.util
.regex
.Pattern
;
26 import org
.tianocore
.DynamicPcdBuildDefinitionsDocument
.DynamicPcdBuildDefinitions
;
27 import org
.tianocore
.PcdBuildDefinitionDocument
.PcdBuildDefinition
;
28 import org
.tianocore
.pcd
.entity
.*;
29 import org
.tianocore
.pcd
.entity
.Token
;
30 import org
.tianocore
.pcd
.entity
.MemoryDatabaseManager
;
31 import org
.tianocore
.pcd
.exception
.PlatformPcdPreprocessException
;
34 The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's
35 pcd build information from fpd file.
36 This class will be extended by building tools and wizard tools.
39 public abstract class PlatformPcdPreprocessAction
{
41 /// PCD memory database
43 private MemoryDatabaseManager pcdDbManager
;
46 Set parameter pcdDbManager
50 public void setPcdDbManager(MemoryDatabaseManager pcdDbManager
) {
51 this.pcdDbManager
= pcdDbManager
;
55 Get parameter pcdDbManager
57 @return MemoryDatabaseManager
59 public MemoryDatabaseManager
getPcdDbManager() {
63 Abstract function: retrieve module information from FPD file.
65 In building environement, this function will be implementated by FpdParserTask.
67 @return List<ModuleInfo> the component array.
68 @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.
71 public abstract List
<ModulePcdInfoFromFpd
> getComponentsFromFpd()
72 throws PlatformPcdPreprocessException
;
75 Abstract function to get GUID string from SPD file.
77 In building evnironment, this function will be implementated by GlobaData.
79 @param guidCName the CName of GUID
81 @return String[] Guid information from SPD file.
82 @throws PlatformPcdPreprocessException
83 Fail to get Guid information from SPD file.
85 public abstract String
[] getGuidInfoFromSpd(String guidCName
)
86 throws PlatformPcdPreprocessException
;
89 Abstract function: Verification the PCD data.
91 In different environment, such as building environment and wizard environment,
92 it has different implementation according to optimization.
94 @param cName The token name
95 @param moduleName The module who use this PCD token
96 @param datum The PCD's datum
97 @param datumType The PCD's datum type
98 @param maxDatumSize The max size for PCD's Datum.
100 @return String exception strings.
103 public abstract String
verifyDatum(String cName
,
106 Token
.DATUM_TYPE datumType
,
110 Abstract function: Get dynamic information for a token
115 @return DynamicPcdBuildDefinitions.PcdBuildData
117 public abstract DynamicPcdBuildDefinitions
.PcdBuildData
118 getDynamicInfoFromFpd(Token token
,
120 throws PlatformPcdPreprocessException
;
123 Abstract function: Get all dynamic PCD information from FPD file.
125 @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.
126 @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.
129 public abstract List
<DynamicPcdBuildDefinitions
.PcdBuildData
>
130 getAllDynamicPcdInfoFromFpd()
131 throws PlatformPcdPreprocessException
;
134 Collect all PCD information from FPD file into PCD memory database.
137 public void initPcdMemoryDbWithPlatformInfo()
138 throws PlatformPcdPreprocessException
{
141 List
<PcdBuildDefinition
.PcdData
> pcdBuildDataArray
= new ArrayList
<PcdBuildDefinition
.PcdData
>();
142 PcdBuildDefinition
.PcdData pcdBuildData
= null;
144 List
<ModulePcdInfoFromFpd
> modules
= null;
145 String primaryKey
= null;
146 String exceptionString
= null;
147 UsageInstance usageInstance
= null;
148 Token
.PCD_TYPE pcdType
= Token
.PCD_TYPE
.UNKNOWN
;
149 Token
.DATUM_TYPE datumType
= Token
.DATUM_TYPE
.UNKNOWN
;
150 long tokenNumber
= 0;
151 String moduleName
= null;
153 int maxDatumSize
= 0;
154 String
[] tokenSpaceStrRet
= null;
157 // ----------------------------------------------
158 // 1), Get all <ModuleSA> from FPD file.
159 // ----------------------------------------------
161 modules
= getComponentsFromFpd();
163 if (modules
== null) {
164 throw new PlatformPcdPreprocessException(
165 "No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");
169 // -------------------------------------------------------------------
170 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.
171 // -------------------------------------------------------------------
173 for (index
= 0; index
< modules
.size(); index
++) {
175 // It is legal for a module does not contains ANY pcd build definitions.
177 if (modules
.get(index
).pcdBuildDefinition
== null) {
181 pcdBuildDataArray
= modules
.get(index
).pcdBuildDefinition
.getPcdDataList();
183 moduleName
= modules
.get(index
).usageId
.moduleName
;
186 // ----------------------------------------------------------------------
187 // 2.1), Loop all Pcd entry for a module and add it into memory database.
188 // ----------------------------------------------------------------------
190 for (pcdIndex
= 0; pcdIndex
< pcdBuildDataArray
.size(); pcdIndex
++) {
191 pcdBuildData
= pcdBuildDataArray
.get(pcdIndex
);
193 tokenSpaceStrRet
= getGuidInfoFromSpd(pcdBuildData
.getTokenSpaceGuidCName());
195 if (tokenSpaceStrRet
== null) {
196 throw new PlatformPcdPreprocessException(
197 "Fail to get Token space guid for token" + pcdBuildData
.getCName() +
198 " from all SPD files. You must have an <GuidDeclaration> for this token space Guid");
201 primaryKey
= Token
.getPrimaryKeyString(pcdBuildData
.getCName(), tokenSpaceStrRet
[1]);
202 pcdType
= Token
.getPcdTypeFromString(pcdBuildData
.getItemType().toString());
203 datumType
= Token
.getdatumTypeFromString(pcdBuildData
.getDatumType().toString());
204 tokenNumber
= Long
.decode(pcdBuildData
.getToken().toString());
205 if (pcdBuildData
.getValue() != null) {
206 datum
= pcdBuildData
.getValue().toString();
210 maxDatumSize
= pcdBuildData
.getMaxDatumSize();
212 if ((pcdType
== Token
.PCD_TYPE
.FEATURE_FLAG
) &&
213 (datumType
!= Token
.DATUM_TYPE
.BOOLEAN
)){
214 exceptionString
= String
.format("In FPD file, for PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+
215 "datum type of this PCD entry is not BOOLEAN!",
216 pcdBuildData
.getCName(),
218 throw new PlatformPcdPreprocessException(exceptionString
);
222 // -------------------------------------------------------------------------------------------
223 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule
224 // -------------------------------------------------------------------------------------------
226 if (!Token
.isDynamic(pcdType
)) {
228 // Value is required.
231 exceptionString
= String
.format("In FPD file, there is no value for PCD entry %s in module %s!",
232 pcdBuildData
.getCName(),
234 throw new PlatformPcdPreprocessException(exceptionString
);
238 // Check whether the datum size is matched datum type.
240 if ((exceptionString
= verifyDatum(pcdBuildData
.getCName(),
244 maxDatumSize
)) != null) {
245 throw new PlatformPcdPreprocessException(exceptionString
);
250 // ---------------------------------------------------------------------------------
251 // 2.1.2), Create token or update token information for current anaylized PCD data.
252 // ---------------------------------------------------------------------------------
254 if (pcdDbManager
.isTokenInDatabase(primaryKey
)) {
256 // If the token is already exist in database, do some necessary checking
257 // and add a usage instance into this token in database
259 token
= pcdDbManager
.getTokenByKey(primaryKey
);
262 // checking for DatumType, DatumType should be unique for one PCD used in different
265 if (token
.datumType
!= datumType
) {
266 exceptionString
= String
.format("In FPD file, the datum type of PCD entry %s is %s, which is different with %s defined in before!",
267 pcdBuildData
.getCName(),
268 pcdBuildData
.getDatumType().toString(),
269 Token
.getStringOfdatumType(token
.datumType
));
270 throw new PlatformPcdPreprocessException(exceptionString
);
274 // Check token number is valid
276 if (tokenNumber
!= token
.tokenNumber
) {
277 exceptionString
= String
.format("In FPD file, the token number of PCD entry %s in module %s is different with same PCD entry in other modules!",
278 pcdBuildData
.getCName(),
280 throw new PlatformPcdPreprocessException(exceptionString
);
284 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.
286 if (token
.isDynamicPCD
!= Token
.isDynamic(pcdType
)) {
287 exceptionString
= String
.format("In FPD file, for PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+
288 " is different with others module's",
291 throw new PlatformPcdPreprocessException(exceptionString
);
294 if (token
.isDynamicPCD
) {
296 // Check datum is equal the datum in dynamic information.
297 // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,
298 // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.
300 if (!token
.isSkuEnable() &&
301 (token
.getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.DEFAULT_TYPE
) &&
303 if (!datum
.equalsIgnoreCase(token
.getDefaultSku().value
)) {
304 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in module %s, the datum in <ModuleSA> is "+
305 "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+
306 "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",
309 throw new PlatformPcdPreprocessException(exceptionString
);
313 if ((maxDatumSize
!= 0) &&
314 (maxDatumSize
!= token
.datumSize
)){
315 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in module %s, the max datum size is %d which "+
316 "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",
321 throw new PlatformPcdPreprocessException(exceptionString
);
327 // If the token is not in database, create a new token instance and add
328 // a usage instance into this token in database.
330 tokenSpaceStrRet
= this.getGuidInfoFromSpd(pcdBuildData
.getTokenSpaceGuidCName());
332 if (tokenSpaceStrRet
== null) {
333 throw new PlatformPcdPreprocessException(
334 "Fail to get Token space guid for token" + token
.cName
+
335 " from all SPD files. You must have an <GuidDeclaration> for this token space Guid");
339 token
= new Token(pcdBuildData
.getCName(), tokenSpaceStrRet
[1]);
341 token
.datumType
= datumType
;
342 token
.tokenNumber
= tokenNumber
;
343 token
.isDynamicPCD
= Token
.isDynamic(pcdType
);
344 token
.datumSize
= maxDatumSize
;
346 if (token
.isDynamicPCD
) {
348 // For Dynamic and Dynamic Ex type, need find the dynamic information
349 // in <DynamicPcdBuildDefinition> section in FPD file.
351 updateDynamicInformation(moduleName
,
357 pcdDbManager
.addTokenToDatabase(primaryKey
, token
);
361 // -----------------------------------------------------------------------------------
362 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.
363 // -----------------------------------------------------------------------------------
365 token
.updateSupportPcdType(pcdType
);
368 // ------------------------------------------------
369 // 2.1.4), Create an usage instance for this token.
370 // ------------------------------------------------
372 usageInstance
= new UsageInstance(token
,
373 modules
.get(index
).usageId
,
377 if (!token
.addUsageInstance(usageInstance
)) {
378 throw new PlatformPcdPreprocessException(
379 String
.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+
380 "in modules %s in <ModuleSA> to make sure no duplicated definitions in FPD file!",
389 // ------------------------------------------------
390 // 3), Add unreference dynamic_Ex pcd token into Pcd database.
391 // ------------------------------------------------
393 List
<Token
> tokenArray
= getUnreferencedDynamicPcd();
394 if (tokenArray
!= null) {
395 for (index
= 0; index
< tokenArray
.size(); index
++) {
396 pcdDbManager
.addTokenToDatabase(tokenArray
.get(index
).getPrimaryKeyString(),
397 tokenArray
.get(index
));
403 Update dynamic information for PCD entry.
405 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in
408 @param moduleName The name of the module who use this PCD
409 @param token The token instance
410 @param datum The <datum> in module's PCD information
411 @param maxDatumSize The <maxDatumSize> in module's PCD information
415 private Token
updateDynamicInformation(String moduleName
,
419 throws PlatformPcdPreprocessException
{
422 String exceptionString
= null;
423 SkuInstance skuInstance
= null;
425 boolean hasSkuId0
= false;
426 long tokenNumber
= 0;
427 String hiiDefaultValue
= null;
428 String
[] variableGuidString
= null;
430 List
<DynamicPcdBuildDefinitions
.PcdBuildData
.SkuInfo
> skuInfoList
= null;
431 DynamicPcdBuildDefinitions
.PcdBuildData dynamicInfo
= null;
433 dynamicInfo
= getDynamicInfoFromFpd(token
, moduleName
);
434 if (dynamicInfo
== null) {
435 exceptionString
= String
.format("In FPD file, for Dynamic PCD %s used by module %s, "+
436 "there is no dynamic information in <DynamicPcdBuildDefinitions> "+
437 "in FPD file, but it is required!",
440 throw new PlatformPcdPreprocessException(exceptionString
);
443 token
.datumSize
= dynamicInfo
.getMaxDatumSize();
445 exceptionString
= verifyDatum(token
.cName
,
450 if (exceptionString
!= null) {
451 throw new PlatformPcdPreprocessException(exceptionString
);
454 if ((maxDatumSize
!= 0) &&
455 (maxDatumSize
!= token
.datumSize
)) {
456 exceptionString
= String
.format("In FPD file, for dynamic PCD %s, the datum size in module %s is %d, but "+
457 "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",
461 dynamicInfo
.getMaxDatumSize());
462 throw new PlatformPcdPreprocessException(exceptionString
);
464 tokenNumber
= Long
.decode(dynamicInfo
.getToken().toString());
465 if (tokenNumber
!= token
.tokenNumber
) {
466 exceptionString
= String
.format("In FPD file, for dynamic PCD %s, the token number in module %s is 0x%x, but"+
467 "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",
472 throw new PlatformPcdPreprocessException(exceptionString
);
475 token
.dynamicExTokenNumber
= tokenNumber
;
477 skuInfoList
= dynamicInfo
.getSkuInfoList();
482 for (index
= 0; index
< skuInfoList
.size(); index
++) {
483 skuInstance
= new SkuInstance();
485 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.
487 temp
= skuInfoList
.get(index
).getSkuId().toString();
488 skuInstance
.id
= Integer
.decode(temp
);
489 if (skuInstance
.id
== 0) {
493 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.
495 if (skuInfoList
.get(index
).getValue() != null) {
496 skuInstance
.value
.setValue(skuInfoList
.get(index
).getValue().toString());
497 if ((exceptionString
= verifyDatum(token
.cName
,
499 skuInfoList
.get(index
).getValue().toString(),
501 token
.datumSize
)) != null) {
502 throw new PlatformPcdPreprocessException(exceptionString
);
505 token
.skuData
.add(skuInstance
);
508 // Judege wether is same of datum between module's information
509 // and dynamic information.
512 if ((skuInstance
.id
== 0) &&
513 !datum
.toString().equalsIgnoreCase(skuInfoList
.get(index
).getValue().toString())) {
514 exceptionString
= "In FPD file, for dynamic PCD " + token
.cName
+ ", the value in module " + moduleName
+ " is " + datum
.toString() + " but the "+
515 "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance
.value
.value
+ ". They are must be same!"+
516 " or you could not define value for a dynamic PCD in every <ModuleSA>!";
517 throw new PlatformPcdPreprocessException(exceptionString
);
524 // Judge whether is HII group case.
526 if (skuInfoList
.get(index
).getVariableName() != null) {
527 exceptionString
= null;
528 if (skuInfoList
.get(index
).getVariableGuid() == null) {
529 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
530 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",
533 if (exceptionString
!= null) {
534 throw new PlatformPcdPreprocessException(exceptionString
);
538 if (skuInfoList
.get(index
).getVariableOffset() == null) {
539 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
540 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",
543 if (exceptionString
!= null) {
544 throw new PlatformPcdPreprocessException(exceptionString
);
548 if (skuInfoList
.get(index
).getHiiDefaultValue() == null) {
549 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
550 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",
553 if (exceptionString
!= null) {
554 throw new PlatformPcdPreprocessException(exceptionString
);
558 if (skuInfoList
.get(index
).getHiiDefaultValue() != null) {
559 hiiDefaultValue
= skuInfoList
.get(index
).getHiiDefaultValue().toString();
561 hiiDefaultValue
= null;
564 if ((exceptionString
= verifyDatum(token
.cName
,
568 token
.datumSize
)) != null) {
569 throw new PlatformPcdPreprocessException(exceptionString
);
572 offset
= Integer
.decode(skuInfoList
.get(index
).getVariableOffset());
573 if (offset
> 0xFFFF) {
574 throw new PlatformPcdPreprocessException(
575 String
.format("In FPD file, for dynamic PCD %s , the variable offset defined in sku %d data "+
576 "exceed 64K, it is not allowed!",
582 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.
584 variableGuidString
= getGuidInfoFromSpd(skuInfoList
.get(index
).getVariableGuid().toString());
585 if (variableGuidString
== null) {
586 throw new PlatformPcdPreprocessException(
587 String
.format("In FPD file, for dynamic PCD %s, the variable guid %s can be found in all SPD file!",
589 skuInfoList
.get(index
).getVariableGuid().toString()));
591 String variableStr
= skuInfoList
.get(index
).getVariableName();
592 Pattern pattern
= Pattern
.compile("0x([a-fA-F0-9]){4}");
593 Matcher matcher
= pattern
.matcher(variableStr
);
594 List
<String
> varNameList
= new ArrayList
<String
>();
595 while (matcher
.find()){
596 String str
= variableStr
.substring(matcher
.start(),matcher
.end());
597 varNameList
.add(str
);
600 skuInstance
.value
.setHiiData(varNameList
,
601 translateSchemaStringToUUID(variableGuidString
[1]),
602 skuInfoList
.get(index
).getVariableOffset(),
603 skuInfoList
.get(index
).getHiiDefaultValue().toString());
604 token
.skuData
.add(skuInstance
);
608 if (skuInfoList
.get(index
).getVpdOffset() != null) {
609 skuInstance
.value
.setVpdData(skuInfoList
.get(index
).getVpdOffset());
610 token
.skuData
.add(skuInstance
);
614 exceptionString
= String
.format("In FPD file, for dynamic PCD %s, the dynamic info must "+
615 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",
617 throw new PlatformPcdPreprocessException(exceptionString
);
621 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+
622 "no sku id = 0 data, which is required for every dynamic PCD",
624 throw new PlatformPcdPreprocessException(exceptionString
);
631 Get all dynamic PCD defined in <DynamicPcdBuildDefinitions> which unreferenced by
632 any <ModuleSA> in FPD file.
634 @return List<Token> Return PCD token
636 private List
<Token
> getUnreferencedDynamicPcd () throws PlatformPcdPreprocessException
{
637 List
<Token
> tokenArray
= new ArrayList
<Token
>();
639 List
<DynamicPcdBuildDefinitions
.PcdBuildData
> dynamicPcdBuildDataArray
= null;
640 DynamicPcdBuildDefinitions
.PcdBuildData pcdBuildData
= null;
641 List
<DynamicPcdBuildDefinitions
.PcdBuildData
.SkuInfo
> skuInfoList
= null;
642 Token
.PCD_TYPE pcdType
;
643 SkuInstance skuInstance
= null;
644 String primaryKey
= null;
645 boolean hasSkuId0
= false;
646 int index
, offset
, index2
;
648 String exceptionString
;
649 String hiiDefaultValue
;
650 String tokenSpaceStrRet
[];
651 String variableGuidString
[];
653 dynamicPcdBuildDataArray
= getAllDynamicPcdInfoFromFpd();
654 if (dynamicPcdBuildDataArray
== null) {
658 for (index2
= 0; index2
< dynamicPcdBuildDataArray
.size(); index2
++) {
659 pcdBuildData
= dynamicPcdBuildDataArray
.get(index2
);
660 tokenSpaceStrRet
= this.getGuidInfoFromSpd(pcdBuildData
.getTokenSpaceGuidCName());
662 if (tokenSpaceStrRet
== null) {
663 throw new PlatformPcdPreprocessException("Fail to get Token space guid for token" + pcdBuildData
.getCName());
666 primaryKey
= Token
.getPrimaryKeyString(pcdBuildData
.getCName(),
667 tokenSpaceStrRet
[1]);
669 if (pcdDbManager
.isTokenInDatabase(primaryKey
)) {
673 pcdType
= Token
.getPcdTypeFromString(pcdBuildData
.getItemType().toString());
674 if (pcdType
!= Token
.PCD_TYPE
.DYNAMIC_EX
) {
675 throw new PlatformPcdPreprocessException(
676 String
.format("In FPD file, it not allowed for DYNAMIC PCD %s who is no used by any module",
677 pcdBuildData
.getCName()));
681 // Create new token for unreference dynamic PCD token
683 token
= new Token(pcdBuildData
.getCName(), tokenSpaceStrRet
[1]);
684 token
.datumSize
= pcdBuildData
.getMaxDatumSize();
687 token
.datumType
= Token
.getdatumTypeFromString(pcdBuildData
.getDatumType().toString());
688 token
.tokenNumber
= Long
.decode(pcdBuildData
.getToken().toString());
689 token
.dynamicExTokenNumber
= token
.tokenNumber
;
690 token
.isDynamicPCD
= true;
691 token
.updateSupportPcdType(pcdType
);
693 exceptionString
= verifyDatum(token
.cName
,
698 if (exceptionString
!= null) {
699 throw new PlatformPcdPreprocessException(exceptionString
);
702 skuInfoList
= pcdBuildData
.getSkuInfoList();
707 for (index
= 0; index
< skuInfoList
.size(); index
++) {
708 skuInstance
= new SkuInstance();
710 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.
712 temp
= skuInfoList
.get(index
).getSkuId().toString();
713 skuInstance
.id
= Integer
.decode(temp
);
714 if (skuInstance
.id
== 0) {
718 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.
720 if (skuInfoList
.get(index
).getValue() != null) {
721 skuInstance
.value
.setValue(skuInfoList
.get(index
).getValue().toString());
722 if ((exceptionString
= verifyDatum(token
.cName
,
724 skuInfoList
.get(index
).getValue().toString(),
726 token
.datumSize
)) != null) {
727 throw new PlatformPcdPreprocessException(exceptionString
);
730 token
.skuData
.add(skuInstance
);
736 // Judge whether is HII group case.
738 if (skuInfoList
.get(index
).getVariableName() != null) {
739 exceptionString
= null;
740 if (skuInfoList
.get(index
).getVariableGuid() == null) {
741 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
742 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",
745 if (exceptionString
!= null) {
746 throw new PlatformPcdPreprocessException(exceptionString
);
750 if (skuInfoList
.get(index
).getVariableOffset() == null) {
751 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
752 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",
755 if (exceptionString
!= null) {
756 throw new PlatformPcdPreprocessException(exceptionString
);
760 if (skuInfoList
.get(index
).getHiiDefaultValue() == null) {
761 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
762 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",
765 if (exceptionString
!= null) {
766 throw new PlatformPcdPreprocessException(exceptionString
);
770 if (skuInfoList
.get(index
).getHiiDefaultValue() != null) {
771 hiiDefaultValue
= skuInfoList
.get(index
).getHiiDefaultValue().toString();
773 hiiDefaultValue
= null;
776 if ((exceptionString
= verifyDatum(token
.cName
,
780 token
.datumSize
)) != null) {
781 throw new PlatformPcdPreprocessException(exceptionString
);
784 offset
= Integer
.decode(skuInfoList
.get(index
).getVariableOffset());
785 if (offset
> 0xFFFF) {
786 throw new PlatformPcdPreprocessException(
787 String
.format("In FPD file, for dynamic PCD %s , the variable offset defined in sku %d data "+
788 "exceed 64K, it is not allowed!",
794 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.
796 variableGuidString
= this.getGuidInfoFromSpd(skuInfoList
.get(index
).getVariableGuid().toString());
797 if (variableGuidString
== null) {
798 throw new PlatformPcdPreprocessException(
799 String
.format("In FPD file, for dynamic PCD %s, the variable guid %s can be found in all SPD file!",
801 skuInfoList
.get(index
).getVariableGuid().toString()));
803 String variableStr
= skuInfoList
.get(index
).getVariableName();
804 Pattern pattern
= Pattern
.compile("0x([a-fA-F0-9]){4}");
805 Matcher matcher
= pattern
.matcher(variableStr
);
806 List
<String
> varNameList
= new ArrayList
<String
>();
807 while (matcher
.find()){
808 String str
= variableStr
.substring(matcher
.start(),matcher
.end());
809 varNameList
.add(str
);
812 skuInstance
.value
.setHiiData(varNameList
,
813 translateSchemaStringToUUID(variableGuidString
[1]),
814 skuInfoList
.get(index
).getVariableOffset(),
815 skuInfoList
.get(index
).getHiiDefaultValue().toString());
816 token
.skuData
.add(skuInstance
);
820 if (skuInfoList
.get(index
).getVpdOffset() != null) {
821 skuInstance
.value
.setVpdData(skuInfoList
.get(index
).getVpdOffset());
822 token
.skuData
.add(skuInstance
);
826 exceptionString
= String
.format("In FPD file, for dynamic PCD %s, the dynamic info must "+
827 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",
829 throw new PlatformPcdPreprocessException(exceptionString
);
833 exceptionString
= String
.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+
834 "no sku id = 0 data, which is required for every dynamic PCD",
836 throw new PlatformPcdPreprocessException(exceptionString
);
839 tokenArray
.add(token
);
846 Translate the schema string to UUID instance.
848 In schema, the string of UUID is defined as following two types string:
849 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
850 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
852 2) GuidNamingConvention: pattern =
853 [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}
855 This function will convert string and create uuid instance.
857 @param uuidString UUID string in XML file
859 @return UUID UUID instance
861 private UUID
translateSchemaStringToUUID(String uuidString
)
862 throws PlatformPcdPreprocessException
{
864 String
[] splitStringArray
;
869 if (uuidString
== null) {
873 if (uuidString
.length() == 0) {
877 if (uuidString
.equals("0") ||
878 uuidString
.equalsIgnoreCase("0x0")) {
879 return new UUID(0, 0);
882 uuidString
= uuidString
.replaceAll("\\{", "");
883 uuidString
= uuidString
.replaceAll("\\}", "");
886 // If the UUID schema string is GuidArrayType type then need translate
887 // to GuidNamingConvention type at first.
889 if ((uuidString
.charAt(0) == '0') && ((uuidString
.charAt(1) == 'x') || (uuidString
.charAt(1) == 'X'))) {
890 splitStringArray
= uuidString
.split("," );
891 if (splitStringArray
.length
!= 11) {
892 throw new PlatformPcdPreprocessException ("Wrong format for UUID string: " + uuidString
);
896 // Remove blank space from these string and remove header string "0x"
898 for (index
= 0; index
< 11; index
++) {
899 splitStringArray
[index
] = splitStringArray
[index
].trim();
900 splitStringArray
[index
] = splitStringArray
[index
].substring(2, splitStringArray
[index
].length());
904 // Add heading '0' to normalize the string length
906 for (index
= 3; index
< 11; index
++) {
907 chLen
= splitStringArray
[index
].length();
908 for (chIndex
= 0; chIndex
< 2 - chLen
; chIndex
++) {
909 splitStringArray
[index
] = "0" + splitStringArray
[index
];
914 // construct the final GuidNamingConvention string
916 temp
= String
.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
927 splitStringArray
[10]);
931 return UUID
.fromString(uuidString
);