-/** @file\r
- CollectPCDAction class.\r
-\r
- This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
- This class will be used for wizard and build tools, So it can *not* inherit\r
- from buildAction or wizardAction.\r
- \r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-package org.tianocore.build.pcd.action;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.math.BigInteger;\r
-import java.util.ArrayList;\r
-import java.util.Comparator;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.UUID;\r
-import java.util.regex.Matcher;\r
-import java.util.regex.Pattern;\r
-\r
-import org.apache.xmlbeans.XmlException;\r
-import org.apache.xmlbeans.XmlObject;\r
-import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
-import org.tianocore.FrameworkModulesDocument;\r
-import org.tianocore.ModuleSADocument;\r
-import org.tianocore.PcdBuildDefinitionDocument;\r
-import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;\r
-import org.tianocore.PlatformSurfaceAreaDocument;\r
-import org.tianocore.build.fpd.FpdParserTask;\r
-import org.tianocore.build.global.GlobalData;\r
-import org.tianocore.build.id.FpdModuleIdentification;\r
-import org.tianocore.build.id.ModuleIdentification;\r
-import org.tianocore.pcd.action.ActionMessage;\r
-import org.tianocore.pcd.entity.CommonDefinition;\r
-import org.tianocore.pcd.entity.DynamicTokenValue;\r
-import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
-import org.tianocore.pcd.entity.SkuInstance;\r
-import org.tianocore.pcd.entity.Token;\r
-import org.tianocore.pcd.entity.UsageIdentification;\r
-import org.tianocore.pcd.entity.UsageInstance;\r
-import org.tianocore.pcd.exception.EntityException;\r
-\r
-/** Module Info class is the data structure to hold information got from GlobalData.\r
-*/\r
-class ModuleInfo {\r
- ///\r
- /// Module's ID for a <ModuleSA>\r
- /// \r
- private FpdModuleIdentification moduleId;\r
- ///\r
- /// <PcdBuildDefinition> xmlobject in FPD file for a <ModuleSA>\r
- /// \r
- private PcdBuildDefinitionDocument.PcdBuildDefinition pcdBuildDef;\r
-\r
- public ModuleInfo (FpdModuleIdentification moduleId, XmlObject pcdDef) {\r
- this.moduleId = moduleId;\r
- this.pcdBuildDef = ((PcdBuildDefinitionDocument)pcdDef).getPcdBuildDefinition();\r
- }\r
-\r
- public FpdModuleIdentification getModuleId (){\r
- return moduleId;\r
- }\r
-\r
- public PcdBuildDefinitionDocument.PcdBuildDefinition getPcdBuildDef(){\r
- return pcdBuildDef;\r
- }\r
-}\r
-\r
-/** This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
- This class will be used for wizard and build tools, So it can *not* inherit\r
- from buildAction or UIAction.\r
-**/\r
-public class CollectPCDAction {\r
- ///\r
- /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.\r
- /// \r
- private MemoryDatabaseManager dbManager;\r
- ///\r
- /// Workspacepath hold the workspace information.\r
- /// \r
- private String workspacePath;\r
- ///\r
- /// FPD file is the root file. \r
- /// \r
- private String fpdFilePath;\r
- ///\r
- /// Message level for CollectPCDAction.\r
- /// \r
- private int originalMessageLevel;\r
- ///\r
- /// Cache the fpd docment instance for private usage.\r
- /// \r
- private PlatformSurfaceAreaDocument fpdDocInstance;\r
- ///\r
- /// xmlObject name\r
- /// \r
- private static String xmlObjectName = "PcdBuildDefinition"; \r
- \r
- /**\r
- Set WorkspacePath parameter for this action class.\r
-\r
- @param workspacePath parameter for this action\r
- **/\r
- public void setWorkspacePath(String workspacePath) {\r
- this.workspacePath = workspacePath;\r
- }\r
-\r
- /**\r
- Set action message level for CollectPcdAction tool.\r
-\r
- The message should be restored when this action exit.\r
-\r
- @param actionMessageLevel parameter for this action\r
- **/\r
- public void setActionMessageLevel(int actionMessageLevel) {\r
- originalMessageLevel = ActionMessage.messageLevel;\r
- ActionMessage.messageLevel = actionMessageLevel;\r
- }\r
-\r
- /**\r
- Set FPDFileName parameter for this action class.\r
-\r
- @param fpdFilePath fpd file path\r
- **/\r
- public void setFPDFilePath(String fpdFilePath) {\r
- this.fpdFilePath = fpdFilePath;\r
- }\r
-\r
- /**\r
- Common function interface for outer.\r
- \r
- @param workspacePath The path of workspace of current build or analysis.\r
- @param fpdFilePath The fpd file path of current build or analysis.\r
- @param messageLevel The message level for this Action.\r
- \r
- @throws Exception The exception of this function. Because it can *not* be predict\r
- where the action class will be used. So only Exception can be throw.\r
- \r
- **/\r
- public void perform(String workspacePath, String fpdFilePath, \r
- int messageLevel) throws Exception {\r
- setWorkspacePath(workspacePath);\r
- setFPDFilePath(fpdFilePath);\r
- setActionMessageLevel(messageLevel);\r
- checkParameter();\r
- execute();\r
- ActionMessage.messageLevel = originalMessageLevel;\r
- }\r
-\r
- /**\r
- Core execution function for this action class.\r
- \r
- This function work flows will be:\r
- 1) Collect and prepocess PCD information from FPD file, all PCD\r
- information will be stored into memory database.\r
- 2) Generate 3 strings for\r
- a) All modules using Dynamic(Ex) PCD entry.(Token Number)\r
- b) PEI PCDDatabase (C Structure) for PCD Service PEIM.\r
- c) DXE PCD Database (C structure) for PCD Service DXE.\r
- \r
- \r
- @throws EntityException Exception indicate failed to execute this action.\r
- \r
- **/\r
- public void execute() throws EntityException {\r
- //\r
- // Get memoryDatabaseManager instance from GlobalData.\r
- // The memoryDatabaseManager should be initialized for whatever build\r
- // tools or wizard tools\r
- //\r
- if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {\r
- throw new EntityException("The instance of PCD memory database manager is null");\r
- }\r
-\r
- //\r
- // Collect all PCD information defined in FPD file.\r
- // Evenry token defind in FPD will be created as an token into \r
- // memory database.\r
- //\r
- createTokenInDBFromFPD();\r
- \r
- //\r
- // Generate for PEI, DXE PCD DATABASE's definition and initialization.\r
- //\r
- genPcdDatabaseSourceCode ();\r
- \r
- }\r
-\r
- /**\r
- This function generates source code for PCD Database.\r
- \r
- @param void\r
- @throws EntityException If the token does *not* exist in memory database.\r
-\r
- **/\r
- private void genPcdDatabaseSourceCode()\r
- throws EntityException {\r
- String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions();\r
-\r
- ArrayList<Token> alPei = new ArrayList<Token> ();\r
- ArrayList<Token> alDxe = new ArrayList<Token> ();\r
-\r
- dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);\r
- PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);\r
- pcdPeiDatabase.genCode();\r
- MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString() + \r
- PcdDatabase.getPcdPeiDatabaseDefinitions();\r
- MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();\r
-\r
- PcdDatabase pcdDxeDatabase = new PcdDatabase(alDxe, "DXE", alPei.size());\r
- pcdDxeDatabase.genCode();\r
- MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString() + \r
- PcdDatabase.getPcdDxeDatabaseDefinitions();\r
- MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();\r
- }\r
-\r
- /**\r
- Get component array from FPD.\r
- \r
- This function maybe provided by some Global class.\r
- \r
- @return List<ModuleInfo> the component array.\r
- \r
- */\r
- private List<ModuleInfo> getComponentsFromFPD() \r
- throws EntityException {\r
- List<ModuleInfo> allModules = new ArrayList<ModuleInfo>();\r
- FrameworkModulesDocument.FrameworkModules fModules = null;\r
- ModuleSADocument.ModuleSA[] modules = null;\r
- Map<FpdModuleIdentification, XmlObject> pcdBuildDefinitions = null;\r
-\r
- pcdBuildDefinitions = GlobalData.getFpdPcdBuildDefinitions();\r
- if (pcdBuildDefinitions == null) {\r
- return null;\r
- }\r
-\r
- //\r
- // Loop map to retrieve all PCD build definition and Module id \r
- // \r
- Iterator item = pcdBuildDefinitions.keySet().iterator();\r
- while (item.hasNext()){\r
- FpdModuleIdentification id = (FpdModuleIdentification) item.next();\r
- allModules.add(new ModuleInfo(id, pcdBuildDefinitions.get(id))); \r
- }\r
- \r
- return allModules;\r
- }\r
-\r
- /**\r
- Create token instance object into memory database, the token information\r
- comes for FPD file. Normally, FPD file will contain all token platform \r
- informations.\r
- \r
- @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.\r
- \r
- @throws EntityException Failed to parse FPD xml file.\r
- \r
- **/\r
- private void createTokenInDBFromFPD() \r
- throws EntityException {\r
- int index = 0;\r
- int index2 = 0;\r
- int pcdIndex = 0;\r
- List<PcdBuildDefinition.PcdData> pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();\r
- PcdBuildDefinition.PcdData pcdBuildData = null;\r
- Token token = null;\r
- List<ModuleInfo> modules = null;\r
- String primaryKey = null;\r
- String exceptionString = null;\r
- UsageInstance usageInstance = null;\r
- String primaryKey1 = null;\r
- String primaryKey2 = null;\r
- boolean isDuplicate = false;\r
- Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
- Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;\r
- long tokenNumber = 0;\r
- String moduleName = null;\r
- String datum = null;\r
- int maxDatumSize = 0;\r
- String[] tokenSpaceStrRet = null;\r
- UsageIdentification usageId = null;\r
- ModuleIdentification moduleId = null;\r
-\r
- //\r
- // ----------------------------------------------\r
- // 1), Get all <ModuleSA> from FPD file.\r
- // ----------------------------------------------\r
- // \r
- modules = getComponentsFromFPD();\r
-\r
- if (modules == null) {\r
- throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");\r
- }\r
-\r
- //\r
- // -------------------------------------------------------------------\r
- // 2), Loop all modules to process <PcdBuildDeclarations> for each module.\r
- // -------------------------------------------------------------------\r
- // \r
- for (index = 0; index < modules.size(); index ++) {\r
- //\r
- // It is legal for a module does not contains ANY pcd build definitions.\r
- // \r
- if (modules.get(index).getPcdBuildDef() == null) {\r
- continue;\r
- }\r
- \r
- pcdBuildDataArray = modules.get(index).getPcdBuildDef().getPcdDataList();\r
-\r
- moduleName = modules.get(index).getModuleId().getModule().getName();\r
-\r
- //\r
- // ----------------------------------------------------------------------\r
- // 2.1), Loop all Pcd entry for a module and add it into memory database.\r
- // ----------------------------------------------------------------------\r
- // \r
- for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {\r
- pcdBuildData = pcdBuildDataArray.get(pcdIndex);\r
- \r
- try {\r
- tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
- } catch ( Exception e ) {\r
- throw new EntityException ("Faile get Guid for token " + pcdBuildData.getCName() + ":" + e.getMessage());\r
- }\r
-\r
- if (tokenSpaceStrRet == null) {\r
- throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r
- } \r
-\r
- primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r
- pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
- datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
- tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r
- if (pcdBuildData.getValue() != null) {\r
- datum = pcdBuildData.getValue().toString();\r
- } else {\r
- datum = null;\r
- }\r
- maxDatumSize = pcdBuildData.getMaxDatumSize();\r
-\r
- if ((pcdType == Token.PCD_TYPE.FEATURE_FLAG) &&\r
- (datumType != Token.DATUM_TYPE.BOOLEAN)){\r
- exceptionString = String.format("[FPD file error] For PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+\r
- "datum type of this PCD entry is not BOOLEAN!",\r
- pcdBuildData.getCName(),\r
- moduleName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- //\r
- // -------------------------------------------------------------------------------------------\r
- // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule\r
- // -------------------------------------------------------------------------------------------\r
- // \r
- if (!Token.isDynamic(pcdType)) {\r
- //\r
- // Value is required.\r
- // \r
- if (datum == null) {\r
- exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!",\r
- pcdBuildData.getCName(),\r
- moduleName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- //\r
- // Check whether the datum size is matched datum type.\r
- // \r
- if ((exceptionString = verifyDatum(pcdBuildData.getCName(), \r
- moduleName,\r
- datum,\r
- datumType,\r
- maxDatumSize)) != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
- }\r
-\r
- //\r
- // ---------------------------------------------------------------------------------\r
- // 2.1.2), Create token or update token information for current anaylized PCD data.\r
- // ---------------------------------------------------------------------------------\r
- // \r
- if (dbManager.isTokenInDatabase(primaryKey)) {\r
- //\r
- // If the token is already exist in database, do some necessary checking\r
- // and add a usage instance into this token in database\r
- // \r
- token = dbManager.getTokenByKey(primaryKey);\r
- \r
- //\r
- // checking for DatumType, DatumType should be unique for one PCD used in different\r
- // modules.\r
- // \r
- if (token.datumType != datumType) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD entry %s is %s, which is different with %s defined in before!",\r
- pcdBuildData.getCName(), \r
- pcdBuildData.getDatumType().toString(), \r
- Token.getStringOfdatumType(token.datumType));\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- //\r
- // Check token number is valid\r
- // \r
- if (tokenNumber != token.tokenNumber) {\r
- exceptionString = String.format("[FPD file error] The token number of PCD entry %s in module %s is different with same PCD entry in other modules!",\r
- pcdBuildData.getCName(),\r
- moduleName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- //\r
- // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.\r
- // \r
- if (token.isDynamicPCD != Token.isDynamic(pcdType)) {\r
- exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+\r
- "is different with others module's",\r
- token.cName,\r
- moduleName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- if (token.isDynamicPCD) {\r
- //\r
- // Check datum is equal the datum in dynamic information.\r
- // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,\r
- // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.\r
- // \r
- if (!token.isSkuEnable() && \r
- (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&\r
- (datum != null)) {\r
- if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+\r
- "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+\r
- "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",\r
- token.cName,\r
- moduleName);\r
- throw new EntityException(exceptionString);\r
- }\r
- }\r
-\r
- if ((maxDatumSize != 0) &&\r
- (maxDatumSize != token.datumSize)){\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+\r
- "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",\r
- token.cName,\r
- moduleName,\r
- maxDatumSize,\r
- token.datumSize);\r
- throw new EntityException(exceptionString);\r
- }\r
- }\r
- \r
- } else {\r
- //\r
- // If the token is not in database, create a new token instance and add\r
- // a usage instance into this token in database.\r
- // \r
- try {\r
- tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
- } catch (Exception e) {\r
- throw new EntityException("Fail to get token space guid for token " + token.cName);\r
- }\r
-\r
- if (tokenSpaceStrRet == null) {\r
- throw new EntityException("Fail to get token space guid for token " + token.cName);\r
- }\r
-\r
- token = new Token(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r
- \r
- token.datumType = datumType;\r
- token.tokenNumber = tokenNumber;\r
- token.isDynamicPCD = Token.isDynamic(pcdType);\r
- token.datumSize = maxDatumSize;\r
- \r
- if (token.isDynamicPCD) {\r
- //\r
- // For Dynamic and Dynamic Ex type, need find the dynamic information\r
- // in <DynamicPcdBuildDefinition> section in FPD file.\r
- // \r
- updateDynamicInformation(moduleName, \r
- token,\r
- datum,\r
- maxDatumSize);\r
- }\r
- \r
- dbManager.addTokenToDatabase(primaryKey, token);\r
- }\r
-\r
- //\r
- // -----------------------------------------------------------------------------------\r
- // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.\r
- // -----------------------------------------------------------------------------------\r
- // \r
- token.updateSupportPcdType(pcdType);\r
-\r
- //\r
- // ------------------------------------------------\r
- // 2.1.4), Create an usage instance for this token.\r
- // ------------------------------------------------\r
- // \r
- moduleId = modules.get(index).getModuleId().getModule();\r
- usageId = new UsageIdentification (moduleId.getName(), \r
- moduleId.getGuid(), \r
- moduleId.getPackage().getName(), \r
- moduleId.getPackage().getGuid(), \r
- modules.get(index).getModuleId().getArch(),\r
- moduleId.getVersion(),\r
- moduleId.getModuleType());\r
- usageInstance = new UsageInstance(token, \r
- usageId,\r
- pcdType,\r
- datum,\r
- maxDatumSize);\r
- token.addUsageInstance(usageInstance);\r
- }\r
- }\r
-\r
- //\r
- // ------------------------------------------------\r
- // 3), Add unreference dynamic_Ex pcd token into Pcd database.\r
- // ------------------------------------------------\r
- // \r
- List<Token> tokenArray = getUnreferencedDynamicPcd();\r
- if (tokenArray != null) {\r
- for (index = 0; index < tokenArray.size(); index ++) {\r
- dbManager.addTokenToDatabase(tokenArray.get(index).getPrimaryKeyString(), \r
- tokenArray.get(index));\r
- }\r
- }\r
- }\r
-\r
- private List<Token> getUnreferencedDynamicPcd () throws EntityException {\r
- List<Token> tokenArray = new ArrayList<Token>();\r
- Token token = null;\r
- DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
- List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
- DynamicPcdBuildDefinitions.PcdBuildData pcdBuildData = null;\r
- List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r
- Token.PCD_TYPE pcdType;\r
- SkuInstance skuInstance = null;\r
- String primaryKey = null;\r
- boolean hasSkuId0 = false;\r
- int index, offset, index2;\r
- String temp;\r
- String exceptionString;\r
- String hiiDefaultValue;\r
- String tokenSpaceStrRet[];\r
- String variableGuidString[];\r
-\r
- //\r
- // Open fpd document to get <DynamicPcdBuildDefinition> Section.\r
- // BUGBUG: the function should be move GlobalData in furture.\r
- // \r
- if (fpdDocInstance == null) {\r
- try {\r
- fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
- } catch(IOException ioE) {\r
- throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
- } catch(XmlException xmlE) {\r
- throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
- }\r
- }\r
-\r
- dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
- if (dynamicPcdBuildDefinitions == null) {\r
- return null;\r
- }\r
-\r
- dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
- for (index2 = 0; index2 < dynamicPcdBuildDataArray.size(); index2 ++) {\r
- pcdBuildData = dynamicPcdBuildDataArray.get(index2);\r
- try {\r
- tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(pcdBuildData.getTokenSpaceGuidCName());\r
- } catch ( Exception e ) {\r
- throw new EntityException ("Faile get Guid for token " + pcdBuildData.getCName() + ":" + e.getMessage());\r
- }\r
-\r
- if (tokenSpaceStrRet == null) {\r
- throw new EntityException ("Fail to get Token space guid for token" + pcdBuildData.getCName());\r
- } \r
-\r
- primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r
- tokenSpaceStrRet[1]);\r
-\r
- if (dbManager.isTokenInDatabase(primaryKey)) {\r
- continue;\r
- }\r
-\r
- pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
- if (pcdType != Token.PCD_TYPE.DYNAMIC_EX) {\r
- throw new EntityException (String.format("[FPD file error] It not allowed for DYNAMIC PCD %s who is no used by any module",\r
- pcdBuildData.getCName()));\r
- }\r
-\r
- //\r
- // Create new token for unreference dynamic PCD token\r
- // \r
- token = new Token(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r
- token.datumSize = pcdBuildData.getMaxDatumSize();\r
- \r
-\r
- token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
- token.tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r
- token.dynamicExTokenNumber = token.tokenNumber;\r
- token.isDynamicPCD = true; \r
- token.updateSupportPcdType(pcdType);\r
-\r
- exceptionString = verifyDatum(token.cName, \r
- null,\r
- null, \r
- token.datumType, \r
- token.datumSize);\r
- if (exceptionString != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- skuInfoList = pcdBuildData.getSkuInfoList();\r
-\r
- //\r
- // Loop all sku data \r
- // \r
- for (index = 0; index < skuInfoList.size(); index ++) {\r
- skuInstance = new SkuInstance();\r
- //\r
- // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
- // \r
- temp = skuInfoList.get(index).getSkuId().toString();\r
- skuInstance.id = Integer.decode(temp);\r
- if (skuInstance.id == 0) {\r
- hasSkuId0 = true;\r
- }\r
- //\r
- // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
- // \r
- if (skuInfoList.get(index).getValue() != null) {\r
- skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
- if ((exceptionString = verifyDatum(token.cName, \r
- null, \r
- skuInfoList.get(index).getValue().toString(), \r
- token.datumType, \r
- token.datumSize)) != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- token.skuData.add(skuInstance);\r
-\r
- continue;\r
- }\r
-\r
- //\r
- // Judge whether is HII group case.\r
- // \r
- if (skuInfoList.get(index).getVariableName() != null) {\r
- exceptionString = null;\r
- if (skuInfoList.get(index).getVariableGuid() == null) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
- "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
- token.cName,\r
- index);\r
- if (exceptionString != null) {\r
- throw new EntityException(exceptionString);\r
- } \r
- }\r
-\r
- if (skuInfoList.get(index).getVariableOffset() == null) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
- "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
- token.cName,\r
- index);\r
- if (exceptionString != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
- }\r
-\r
- if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
- "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
- token.cName,\r
- index);\r
- if (exceptionString != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
- }\r
-\r
- if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
- hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
- } else {\r
- hiiDefaultValue = null;\r
- }\r
-\r
- if ((exceptionString = verifyDatum(token.cName, \r
- null, \r
- hiiDefaultValue, \r
- token.datumType, \r
- token.datumSize)) != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
- if (offset > 0xFFFF) {\r
- throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+\r
- "exceed 64K, it is not allowed!",\r
- token.cName,\r
- index));\r
- }\r
-\r
- //\r
- // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
- // \r
- variableGuidString = GlobalData.getGuidInfoFromCname(skuInfoList.get(index).getVariableGuid().toString());\r
- if (variableGuidString == null) {\r
- throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r
- token.cName, \r
- skuInfoList.get(index).getVariableGuid().toString()));\r
- }\r
- String variableStr = skuInfoList.get(index).getVariableName();\r
- Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
- Matcher matcher = pattern.matcher(variableStr);\r
- List<String> varNameList = new ArrayList<String>();\r
- while (matcher.find()){\r
- String str = variableStr.substring(matcher.start(),matcher.end());\r
- varNameList.add(str);\r
- }\r
-\r
- skuInstance.value.setHiiData(varNameList,\r
- translateSchemaStringToUUID(variableGuidString[1]),\r
- skuInfoList.get(index).getVariableOffset(),\r
- skuInfoList.get(index).getHiiDefaultValue().toString());\r
- token.skuData.add(skuInstance);\r
- continue;\r
- }\r
-\r
- if (skuInfoList.get(index).getVpdOffset() != null) {\r
- skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
- token.skuData.add(skuInstance);\r
- continue;\r
- }\r
-\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r
- "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
- token.cName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- if (!hasSkuId0) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
- "no sku id = 0 data, which is required for every dynamic PCD",\r
- token.cName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- tokenArray.add(token);\r
- }\r
-\r
- return tokenArray;\r
- }\r
-\r
- /**\r
- Verify the datum value according its datum size and datum type, this\r
- function maybe moved to FPD verification tools in future.\r
- \r
- @param cName\r
- @param moduleName\r
- @param datum\r
- @param datumType\r
- @param maxDatumSize\r
- \r
- @return String\r
- */\r
- /***/\r
- public String verifyDatum(String cName,\r
- String moduleName,\r
- String datum, \r
- Token.DATUM_TYPE datumType, \r
- int maxDatumSize) {\r
- String exceptionString = null;\r
- int value;\r
- BigInteger value64;\r
- String subStr;\r
- int index;\r
-\r
- if (moduleName == null) {\r
- moduleName = "section <DynamicPcdBuildDefinitions>";\r
- } else {\r
- moduleName = "module " + moduleName;\r
- }\r
-\r
- if (maxDatumSize == 0) {\r
- exceptionString = String.format("[FPD file error] You maybe miss <MaxDatumSize> for PCD %s in %s",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
-\r
- switch (datumType) {\r
- case UINT8:\r
- if (maxDatumSize != 1) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
- "is UINT8, but datum size is %d, they are not matched!",\r
- cName,\r
- moduleName,\r
- maxDatumSize);\r
- return exceptionString;\r
- }\r
-\r
- if (datum != null) {\r
- try {\r
- value = Integer.decode(datum);\r
- } catch (NumberFormatException nfeExp) {\r
- exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+\r
- "digital format of UINT8",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
- if (value > 0xFF) {\r
- exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+\r
- " the max size of UINT8 - 0xFF",\r
- cName, \r
- moduleName,\r
- datum);\r
- return exceptionString;\r
- }\r
- }\r
- break;\r
- case UINT16:\r
- if (maxDatumSize != 2) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
- "is UINT16, but datum size is %d, they are not matched!",\r
- cName,\r
- moduleName,\r
- maxDatumSize);\r
- return exceptionString;\r
- }\r
- if (datum != null) {\r
- try {\r
- value = Integer.decode(datum);\r
- } catch (NumberFormatException nfeExp) {\r
- exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+\r
- "not valid digital of UINT16",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
- if (value > 0xFFFF) {\r
- exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
- "which exceed the range of UINT16 - 0xFFFF",\r
- cName, \r
- moduleName,\r
- datum);\r
- return exceptionString;\r
- }\r
- }\r
- break;\r
- case UINT32:\r
- if (maxDatumSize != 4) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
- "is UINT32, but datum size is %d, they are not matched!",\r
- cName,\r
- moduleName,\r
- maxDatumSize);\r
- return exceptionString;\r
- }\r
-\r
- if (datum != null) {\r
- try {\r
- if (datum.length() > 2) {\r
- if ((datum.charAt(0) == '0') && \r
- ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
- subStr = datum.substring(2, datum.length());\r
- value64 = new BigInteger(subStr, 16);\r
- } else {\r
- value64 = new BigInteger(datum);\r
- }\r
- } else {\r
- value64 = new BigInteger(datum);\r
- }\r
- } catch (NumberFormatException nfeExp) {\r
- exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+\r
- "valid digital of UINT32",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
-\r
- if (value64.bitLength() > 32) {\r
- exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+\r
- "exceed the range of UINT32 - 0xFFFFFFFF",\r
- cName, \r
- moduleName,\r
- datum);\r
- return exceptionString;\r
- }\r
- }\r
- break;\r
- case UINT64:\r
- if (maxDatumSize != 8) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
- "is UINT64, but datum size is %d, they are not matched!",\r
- cName,\r
- moduleName,\r
- maxDatumSize);\r
- return exceptionString;\r
- }\r
-\r
- if (datum != null) {\r
- try {\r
- if (datum.length() > 2) {\r
- if ((datum.charAt(0) == '0') && \r
- ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){\r
- subStr = datum.substring(2, datum.length());\r
- value64 = new BigInteger(subStr, 16);\r
- } else {\r
- value64 = new BigInteger(datum);\r
- }\r
- } else {\r
- value64 = new BigInteger(datum);\r
- }\r
- } catch (NumberFormatException nfeExp) {\r
- exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+\r
- " digital of UINT64",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
-\r
- if (value64.bitLength() > 64) {\r
- exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+\r
- "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF",\r
- cName, \r
- moduleName,\r
- datum);\r
- return exceptionString;\r
- }\r
- }\r
- break;\r
- case BOOLEAN:\r
- if (maxDatumSize != 1) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
- "is BOOLEAN, but datum size is %d, they are not matched!",\r
- cName,\r
- moduleName,\r
- maxDatumSize);\r
- return exceptionString;\r
- }\r
-\r
- if (datum != null) {\r
- if (!(datum.equalsIgnoreCase("TRUE") ||\r
- datum.equalsIgnoreCase("FALSE"))) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+\r
- "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
-\r
- }\r
- break;\r
- case POINTER:\r
- if (datum == null) {\r
- break;\r
- }\r
-\r
- char ch = datum.charAt(0);\r
- int start, end;\r
- String strValue;\r
- //\r
- // For void* type PCD, only three datum is support:\r
- // 1) Unicode: string with start char is "L"\r
- // 2) Ansci: String start char is ""\r
- // 3) byte array: String start char "{"\r
- // \r
- if (ch == 'L') {\r
- start = datum.indexOf('\"');\r
- end = datum.lastIndexOf('\"');\r
- if ((start > end) || \r
- (end > datum.length())||\r
- ((start == end) && (datum.length() > 0))) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
- "a UNICODE string because start with L\", but format maybe"+\r
- "is not right, correct UNICODE string is L\"...\"!",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
-\r
- strValue = datum.substring(start + 1, end);\r
- if ((strValue.length() * 2) > maxDatumSize) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
- "a UNICODE string, but the datum size is %d exceed to <MaxDatumSize> : %d",\r
- cName,\r
- moduleName,\r
- strValue.length() * 2, \r
- maxDatumSize);\r
- return exceptionString;\r
- }\r
- } else if (ch == '\"'){\r
- start = datum.indexOf('\"');\r
- end = datum.lastIndexOf('\"');\r
- if ((start > end) || \r
- (end > datum.length())||\r
- ((start == end) && (datum.length() > 0))) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID* and datum is "+\r
- "a ANSCII string because start with \", but format maybe"+\r
- "is not right, correct ANSIC string is \"...\"!",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
- strValue = datum.substring(start + 1, end);\r
- if ((strValue.length()) > maxDatumSize) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is "+\r
- "a ANSCI string, but the datum size is %d which exceed to <MaxDatumSize> : %d",\r
- cName,\r
- moduleName,\r
- strValue.length(),\r
- maxDatumSize);\r
- return exceptionString;\r
- }\r
- } else if (ch =='{') {\r
- String[] strValueArray;\r
-\r
- start = datum.indexOf('{');\r
- end = datum.lastIndexOf('}');\r
- strValue = datum.substring(start + 1, end);\r
- strValue = strValue.trim();\r
- if (strValue.length() == 0) {\r
- exceptionString = String.format ("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+\r
- "it is byte array in fact, but '{}' is not valid for NULL datam but"+\r
- " need use '{0}'",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
- strValueArray = strValue.split(",");\r
- for (index = 0; index < strValueArray.length; index ++) {\r
- try{\r
- value = Integer.decode(strValueArray[index].trim());\r
- } catch (NumberFormatException nfeEx) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and "+\r
- "it is byte array in fact. For every byte in array should be a valid"+\r
- "byte digital, but element %s is not a valid byte digital!",\r
- cName,\r
- moduleName,\r
- strValueArray[index]);\r
- return exceptionString;\r
- }\r
- if (value > 0xFF) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, "+\r
- "it is byte array in fact. But the element of %s exceed the byte range",\r
- cName,\r
- moduleName,\r
- strValueArray[index]);\r
- return exceptionString;\r
- }\r
- }\r
-\r
- if (strValueArray.length > maxDatumSize) {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*, and datum is byte"+\r
- "array, but the number of bytes is %d which exceed to <MaxDatumSzie> : %d!",\r
- cName,\r
- moduleName,\r
- strValueArray.length,\r
- maxDatumSize);\r
- return exceptionString;\r
- }\r
- } else {\r
- exceptionString = String.format("[FPD file error] The datum type of PCD %s in %s is VOID*. For VOID* type, you have three format choise:\n "+\r
- "1) UNICODE string: like L\"xxxx\";\r\n"+\r
- "2) ANSIC string: like \"xxx\";\r\n"+\r
- "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+\r
- "But the datum in seems does not following above format!",\r
- cName, \r
- moduleName);\r
- return exceptionString;\r
- }\r
- break;\r
- default:\r
- exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+\r
- "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN",\r
- cName,\r
- moduleName);\r
- return exceptionString;\r
- }\r
- return null;\r
- }\r
-\r
- /**\r
- Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.\r
- \r
- This function should be implemented in GlobalData in future.\r
- \r
- @param token The token instance which has hold module's PCD information\r
- @param moduleName The name of module who will use this Dynamic PCD.\r
- \r
- @return DynamicPcdBuildDefinitions.PcdBuildData\r
- */\r
- /***/\r
- private DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFPD(Token token,\r
- String moduleName)\r
- throws EntityException {\r
- int index = 0;\r
- String exceptionString = null;\r
- String dynamicPrimaryKey = null;\r
- DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
- List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
- String[] tokenSpaceStrRet = null;\r
-\r
- //\r
- // If FPD document is not be opened, open and initialize it.\r
- // BUGBUG: The code should be moved into GlobalData in future.\r
- // \r
- if (fpdDocInstance == null) {\r
- try {\r
- fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
- } catch(IOException ioE) {\r
- throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
- } catch(XmlException xmlE) {\r
- throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
- }\r
- }\r
- \r
- dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
- if (dynamicPcdBuildDefinitions == null) {\r
- exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+\r
- "PCD entry %s in module %s!",\r
- token.cName,\r
- moduleName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
- for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
- //String tokenSpaceGuidString = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName())[1];\r
- String tokenSpaceGuidString = null;\r
- try {\r
- tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r
- } catch (Exception e) {\r
- throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
- }\r
- \r
- if (tokenSpaceStrRet == null) {\r
- throw new EntityException ("Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName());\r
- }\r
-\r
- dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
- tokenSpaceStrRet[1]);\r
- if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {\r
- return dynamicPcdBuildDataArray.get(index);\r
- }\r
- }\r
-\r
- return null;\r
- }\r
-\r
- /**\r
- Update dynamic information for PCD entry.\r
- \r
- Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in\r
- FPD file.\r
- \r
- @param moduleName The name of the module who use this PCD\r
- @param token The token instance\r
- @param datum The <datum> in module's PCD information\r
- @param maxDatumSize The <maxDatumSize> in module's PCD information\r
- \r
- @return Token\r
- */\r
- private Token updateDynamicInformation(String moduleName, \r
- Token token,\r
- String datum,\r
- int maxDatumSize) \r
- throws EntityException {\r
- int index = 0;\r
- int offset;\r
- String exceptionString = null;\r
- DynamicTokenValue dynamicValue;\r
- SkuInstance skuInstance = null;\r
- String temp;\r
- boolean hasSkuId0 = false;\r
- Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
- long tokenNumber = 0;\r
- String hiiDefaultValue = null;\r
- String[] variableGuidString = null;\r
-\r
- List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r
- DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null;\r
-\r
- dynamicInfo = getDynamicInfoFromFPD(token, moduleName);\r
- if (dynamicInfo == null) {\r
- exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+\r
- "there is no dynamic information in <DynamicPcdBuildDefinitions> "+\r
- "in FPD file, but it is required!",\r
- token.cName,\r
- moduleName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- token.datumSize = dynamicInfo.getMaxDatumSize();\r
-\r
- exceptionString = verifyDatum(token.cName, \r
- moduleName,\r
- null, \r
- token.datumType, \r
- token.datumSize);\r
- if (exceptionString != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- if ((maxDatumSize != 0) && \r
- (maxDatumSize != token.datumSize)) {\r
- exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+\r
- "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",\r
- token.cName,\r
- moduleName, \r
- maxDatumSize,\r
- dynamicInfo.getMaxDatumSize());\r
- throw new EntityException(exceptionString);\r
- }\r
- tokenNumber = Long.decode(dynamicInfo.getToken().toString());\r
- if (tokenNumber != token.tokenNumber) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s, the token number in module %s is 0x%x, but"+\r
- "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",\r
- token.cName,\r
- moduleName,\r
- token.tokenNumber,\r
- tokenNumber);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- pcdType = Token.getpcdTypeFromString(dynamicInfo.getItemType().toString());\r
- token.dynamicExTokenNumber = tokenNumber;\r
-\r
- skuInfoList = dynamicInfo.getSkuInfoList();\r
-\r
- //\r
- // Loop all sku data \r
- // \r
- for (index = 0; index < skuInfoList.size(); index ++) {\r
- skuInstance = new SkuInstance();\r
- //\r
- // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
- // \r
- temp = skuInfoList.get(index).getSkuId().toString();\r
- skuInstance.id = Integer.decode(temp);\r
- if (skuInstance.id == 0) {\r
- hasSkuId0 = true;\r
- }\r
- //\r
- // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
- // \r
- if (skuInfoList.get(index).getValue() != null) {\r
- skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
- if ((exceptionString = verifyDatum(token.cName, \r
- null, \r
- skuInfoList.get(index).getValue().toString(), \r
- token.datumType, \r
- token.datumSize)) != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- token.skuData.add(skuInstance);\r
-\r
- //\r
- // Judege wether is same of datum between module's information\r
- // and dynamic information.\r
- // \r
- if (datum != null) {\r
- if ((skuInstance.id == 0) &&\r
- !datum.toString().equalsIgnoreCase(skuInfoList.get(index).getValue().toString())) {\r
- exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+\r
- "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+\r
- " or you could not define value for a dynamic PCD in every <ModuleSA>!"; \r
- throw new EntityException(exceptionString);\r
- }\r
- }\r
- continue;\r
- }\r
-\r
- //\r
- // Judge whether is HII group case.\r
- // \r
- if (skuInfoList.get(index).getVariableName() != null) {\r
- exceptionString = null;\r
- if (skuInfoList.get(index).getVariableGuid() == null) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
- "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
- token.cName,\r
- index);\r
- if (exceptionString != null) {\r
- throw new EntityException(exceptionString);\r
- } \r
- }\r
-\r
- if (skuInfoList.get(index).getVariableOffset() == null) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
- "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
- token.cName,\r
- index);\r
- if (exceptionString != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
- }\r
-\r
- if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
- "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
- token.cName,\r
- index);\r
- if (exceptionString != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
- }\r
-\r
- if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
- hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
- } else {\r
- hiiDefaultValue = null;\r
- }\r
-\r
- if ((exceptionString = verifyDatum(token.cName, \r
- null, \r
- hiiDefaultValue, \r
- token.datumType, \r
- token.datumSize)) != null) {\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
- if (offset > 0xFFFF) {\r
- throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+\r
- "exceed 64K, it is not allowed!",\r
- token.cName,\r
- index));\r
- }\r
-\r
- //\r
- // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
- // \r
- variableGuidString = GlobalData.getGuidInfoFromCname(skuInfoList.get(index).getVariableGuid().toString());\r
- if (variableGuidString == null) {\r
- throw new EntityException(String.format("[GUID Error] For dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r
- token.cName, \r
- skuInfoList.get(index).getVariableGuid().toString()));\r
- }\r
- String variableStr = skuInfoList.get(index).getVariableName();\r
- Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
- Matcher matcher = pattern.matcher(variableStr);\r
- List<String> varNameList = new ArrayList<String>();\r
- while (matcher.find()){\r
- String str = variableStr.substring(matcher.start(),matcher.end());\r
- varNameList.add(str);\r
- }\r
- \r
- skuInstance.value.setHiiData(varNameList,\r
- translateSchemaStringToUUID(variableGuidString[1]),\r
- skuInfoList.get(index).getVariableOffset(),\r
- skuInfoList.get(index).getHiiDefaultValue().toString());\r
- token.skuData.add(skuInstance);\r
- continue;\r
- }\r
-\r
- if (skuInfoList.get(index).getVpdOffset() != null) {\r
- skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
- token.skuData.add(skuInstance);\r
- continue;\r
- }\r
-\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+\r
- "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
- token.cName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- if (!hasSkuId0) {\r
- exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
- "no sku id = 0 data, which is required for every dynamic PCD",\r
- token.cName);\r
- throw new EntityException(exceptionString);\r
- }\r
-\r
- return token;\r
- }\r
-\r
- /**\r
- Translate the schema string to UUID instance.\r
- \r
- In schema, the string of UUID is defined as following two types string:\r
- 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
- )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
- \r
- 2) GuidNamingConvention: pattern =\r
- [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}\r
- \r
- This function will convert string and create uuid instance.\r
- \r
- @param uuidString UUID string in XML file\r
- \r
- @return UUID UUID instance\r
- **/\r
- private UUID translateSchemaStringToUUID(String uuidString) \r
- throws EntityException {\r
- String temp;\r
- String[] splitStringArray;\r
- int index;\r
- int chIndex;\r
- int chLen;\r
-\r
- if (uuidString == null) {\r
- return null;\r
- }\r
-\r
- if (uuidString.length() == 0) {\r
- return null;\r
- }\r
-\r
- if (uuidString.equals("0") ||\r
- uuidString.equalsIgnoreCase("0x0")) {\r
- return new UUID(0, 0);\r
- }\r
-\r
- uuidString = uuidString.replaceAll("\\{", "");\r
- uuidString = uuidString.replaceAll("\\}", "");\r
-\r
- //\r
- // If the UUID schema string is GuidArrayType type then need translate \r
- // to GuidNamingConvention type at first.\r
- // \r
- if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
- splitStringArray = uuidString.split("," );\r
- if (splitStringArray.length != 11) {\r
- throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);\r
- }\r
-\r
- //\r
- // Remove blank space from these string and remove header string "0x"\r
- // \r
- for (index = 0; index < 11; index ++) {\r
- splitStringArray[index] = splitStringArray[index].trim();\r
- splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
- }\r
-\r
- //\r
- // Add heading '0' to normalize the string length\r
- // \r
- for (index = 3; index < 11; index ++) {\r
- chLen = splitStringArray[index].length();\r
- for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {\r
- splitStringArray[index] = "0" + splitStringArray[index];\r
- }\r
- }\r
-\r
- //\r
- // construct the final GuidNamingConvention string\r
- // \r
- temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
- splitStringArray[0],\r
- splitStringArray[1],\r
- splitStringArray[2],\r
- splitStringArray[3],\r
- splitStringArray[4],\r
- splitStringArray[5],\r
- splitStringArray[6],\r
- splitStringArray[7],\r
- splitStringArray[8],\r
- splitStringArray[9],\r
- splitStringArray[10]);\r
- uuidString = temp;\r
- }\r
-\r
- return UUID.fromString(uuidString);\r
- }\r
-\r
- /**\r
- check parameter for this action.\r
- \r
- @throws EntityException Bad parameter.\r
- **/\r
- private void checkParameter() throws EntityException {\r
- File file = null;\r
-\r
- if((fpdFilePath == null) ||(workspacePath == null)) {\r
- throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
- }\r
-\r
- if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {\r
- throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
- }\r
-\r
- file = new File(workspacePath);\r
- if(!file.exists()) {\r
- throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");\r
- }\r
-\r
- file = new File(fpdFilePath);\r
-\r
- if(!file.exists()) {\r
- throw new EntityException("FPD File " + fpdFilePath + " does not exist!");\r
- }\r
- }\r
-\r
- /**\r
- Test case function\r
-\r
- @param argv parameter from command line\r
- **/\r
- public static void main(String argv[]) throws EntityException {\r
- CollectPCDAction ca = new CollectPCDAction();\r
- String projectDir = "x:/edk2";\r
- ca.setWorkspacePath(projectDir);\r
- ca.setFPDFilePath(projectDir + "/EdkNt32Pkg/Nt32.fpd");\r
- ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);\r
- GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
- projectDir,\r
- "tools_def.txt");\r
- System.out.println("After initInfo!");\r
- FpdParserTask fpt = new FpdParserTask();\r
- fpt.parseFpdFile(new File(projectDir + "/EdkNt32Pkg/Nt32.fpd"));\r
- ca.execute();\r
- }\r
-}\r