4 This module contains all classes releted to PCD token.
6 Copyright (c) 2006, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 package org
.tianocore
.build
.pcd
.entity
;
18 import java
.math
.BigInteger
;
19 import java
.util
.ArrayList
;
20 import java
.util
.HashMap
;
21 import java
.util
.List
;
23 import java
.util
.UUID
;
25 import org
.tianocore
.build
.pcd
.action
.ActionMessage
;
26 import org
.tianocore
.build
.pcd
.exception
.EntityException
;
28 /** This class is to descript a PCD token object. The information of a token mainly
29 comes from MSA, SPD and setting produced by platform developer.
33 /// Enumeration macro defintion for PCD type.
34 /// BUGBUG: Not use upcase charater is to facility for reading. It may be changed
36 public enum PCD_TYPE
{FEATURE_FLAG
, FIXED_AT_BUILD
, PATCHABLE_IN_MODULE
, DYNAMIC
,
40 /// Enumeration macro definition for datum type. All type mainly comes from ProcessBind.h.
41 /// Wizard maybe expand this type as "int, unsigned int, short, unsigned short etc" in
44 public enum DATUM_TYPE
{UINT8
, UINT16
, UINT32
, UINT64
, BOOLEAN
, POINTER
, UNKNOWN
}
47 /// Enumeration macor defintion for usage of PCD
49 public enum PCD_USAGE
{ALWAYS_PRODUCED
, ALWAYS_CONSUMED
, SOMETIMES_PRODUCED
,
50 SOMETIMES_CONSUMED
, UNKNOWN
}
53 /// cName is to identify a PCD entry and will be used for generating autogen.h/autogen.c.
54 /// cName will be defined in MSA, SPD and FPD, can be regarded as primary key with token space guid.
59 /// Token space name is the guid defined by token itself in package or module level. This
60 /// name mainly for DynamicEx type. For other PCD type token, his token space name is the
61 /// assignedtokenSpaceName as follows.
62 /// tokenSpaceName is defined in MSA, SPD, FPD, can be regarded as primary key with cName.
64 public UUID tokenSpaceName
;
67 /// tokenNumber is allocated by platform. tokenNumber indicate an index for this token in
68 /// platform token space.
69 /// tokenNumber is defined in SPD, FPD.
71 public int tokenNumber
;
74 /// All supported PCD type, this value can be retrieved from SPD
75 /// Currently, only record all PCD type for this token in FPD file.
77 public List
<PCD_TYPE
> supportedPcdType
;
80 /// If the token's item type is Dynamic or DynamicEx type, isDynamicPCD
83 public boolean isDynamicPCD
;
86 /// datumSize is to descript the fix size or max size for this token.
87 /// datumSize is defined in SPD.
92 /// datum type is to descript what type can be expressed by a PCD token.
93 /// For same PCD used in different module, the datum type should be unique.
94 /// So it belong memeber to Token class.
96 public DATUM_TYPE datumType
;
99 /// skuData contains all value for SkuNumber of token.
100 /// This field is for Dynamic or DynamicEx type PCD,
102 public List
<SkuInstance
> skuData
;
105 /// consumers array record all module private information who consume this PCD token.
107 public Map
<String
, UsageInstance
> consumers
;
109 public Token(String cName
, UUID tokenSpaceName
) {
110 UUID nullUUID
= new UUID(0, 0);
113 this.tokenSpaceName
= (tokenSpaceName
== null) ? nullUUID
: tokenSpaceName
;
114 this.tokenNumber
= 0;
115 this.datumType
= DATUM_TYPE
.UNKNOWN
;
117 this.skuData
= new ArrayList
<SkuInstance
>();
119 this.consumers
= new HashMap
<String
, UsageInstance
>();
120 this.supportedPcdType
= new ArrayList
<PCD_TYPE
>();
126 SupportPcdType should be gotten from SPD file actually, but now it just
127 record all PCD type for this token in FPD file.
129 @param pcdType new PCD type found in FPD file for this token.
131 public void updateSupportPcdType(PCD_TYPE pcdType
) {
133 boolean found
= false;
134 for (index
= 0; index
< this.supportedPcdType
.size(); index
++) {
135 if (this.supportedPcdType
.get(index
) == pcdType
) {
141 this.supportedPcdType
.add(pcdType
);
146 Judge whether pcdType is belong to dynamic type. Dynamic type includes
147 DYNAMIC and DYNAMIC_EX.
153 public static boolean isDynamic(PCD_TYPE pcdType
) {
154 if ((pcdType
== PCD_TYPE
.DYNAMIC
) ||
155 (pcdType
== PCD_TYPE
.DYNAMIC_EX
)) {
163 Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database
165 @param cName Token name.
166 @param tokenSpaceName The token space guid defined in MSA or SPD
167 @param platformtokenSpaceName The token space guid for current platform token space,
169 @return primary key for this token in token database.
171 public static String
getPrimaryKeyString(String cName
, UUID tokenSpaceName
) {
172 UUID nullUUID
= new UUID(0, 0);
174 if (tokenSpaceName
== null) {
175 return cName
+ "_" + nullUUID
.toString().replace('-', '_');
177 return cName
+ "_" + tokenSpaceName
.toString().replace('-', '_');
182 If skudata list contains more than one data, then Sku mechanism is enable.
186 public boolean isSkuEnable() {
187 if (this.skuData
.size() > 1) {
194 Get the token primary key in token database.
198 public String
getPrimaryKeyString () {
199 return Token
.getPrimaryKeyString(cName
, tokenSpaceName
);
203 Judge datumType is valid
205 @param type The datumType want to be judged.
207 @retval TRUE - The type is valid.
208 @retval FALSE - The type is invalid.
210 public static boolean isValiddatumType(DATUM_TYPE type
) {
211 if ((type
.ordinal() < DATUM_TYPE
.UINT8
.ordinal() ) ||
212 (type
.ordinal() > DATUM_TYPE
.POINTER
.ordinal())) {
219 Judge pcdType is valid
221 @param type The PCdType want to be judged.
223 @retval TRUE - The type is valid.
224 @retval FALSE - The type is invalid.
226 public static boolean isValidpcdType(PCD_TYPE type
) {
227 if ((type
.ordinal() < PCD_TYPE
.FEATURE_FLAG
.ordinal() ) ||
228 (type
.ordinal() > PCD_TYPE
.DYNAMIC_EX
.ordinal())) {
235 Add an usage instance for token
237 @param usageInstance The usage instance
239 @retval TRUE - Success to add usage instance.
240 @retval FALSE - Fail to add usage instance
242 public boolean addUsageInstance(UsageInstance usageInstance
)
243 throws EntityException
{
246 if (isUsageInstanceExist(usageInstance
.moduleName
,
247 usageInstance
.moduleGUID
,
248 usageInstance
.packageName
,
249 usageInstance
.packageGUID
,
251 usageInstance
.version
)) {
252 exceptionStr
= String
.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+
253 "in modules PcdPeim in <ModuleSA> to make sure no duplicated definitions!",
254 usageInstance
.parentToken
.cName
,
255 usageInstance
.moduleName
);
256 throw new EntityException(exceptionStr
);
259 consumers
.put(usageInstance
.getPrimaryKey(), usageInstance
);
264 Judge whether exist an usage instance for this token
266 @param moduleName the name of module
267 @param moduleGuid the GUID name of modules
268 @param packageName the name of package contains this module
269 @param packageGuid the GUID name of package contains this module
270 @param arch the architecture string
271 @param version the version string
273 @return boolean whether exist an usage instance for this token.
275 public boolean isUsageInstanceExist(String moduleName
,
281 String keyStr
= UsageInstance
.getPrimaryKey(moduleName
,
287 return (consumers
.get(keyStr
) != null);
291 Get the PCD_TYPE according to the string of PCD_TYPE
293 @param pcdTypeStr The string of PCD_TYPE
297 public static PCD_TYPE
getpcdTypeFromString(String pcdTypeStr
) {
298 if (pcdTypeStr
== null) {
299 return PCD_TYPE
.UNKNOWN
;
302 if (pcdTypeStr
.equalsIgnoreCase("FEATURE_FLAG")) {
303 return PCD_TYPE
.FEATURE_FLAG
;
304 } else if (pcdTypeStr
.equalsIgnoreCase("FIXED_AT_BUILD")) {
305 return PCD_TYPE
.FIXED_AT_BUILD
;
306 } else if (pcdTypeStr
.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {
307 return PCD_TYPE
.PATCHABLE_IN_MODULE
;
308 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC")) {
309 return PCD_TYPE
.DYNAMIC
;
310 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC_EX")) {
311 return PCD_TYPE
.DYNAMIC_EX
;
313 return PCD_TYPE
.UNKNOWN
;
318 Get the string of given datumType. This string will be used for generating autogen files
320 @param datumType Given datumType
322 @return The string of datum type.
324 public static String
getStringOfdatumType(DATUM_TYPE datumType
) {
343 Get the datumType according to a string.
345 @param datumTypeStr The string of datumType
349 public static DATUM_TYPE
getdatumTypeFromString(String datumTypeStr
) {
350 if (datumTypeStr
.equalsIgnoreCase("UINT8")) {
351 return DATUM_TYPE
.UINT8
;
352 } else if (datumTypeStr
.equalsIgnoreCase("UINT16")) {
353 return DATUM_TYPE
.UINT16
;
354 } else if (datumTypeStr
.equalsIgnoreCase("UINT32")) {
355 return DATUM_TYPE
.UINT32
;
356 } else if (datumTypeStr
.equalsIgnoreCase("UINT64")) {
357 return DATUM_TYPE
.UINT64
;
358 } else if (datumTypeStr
.equalsIgnoreCase("VOID*")) {
359 return DATUM_TYPE
.POINTER
;
360 } else if (datumTypeStr
.equalsIgnoreCase("BOOLEAN")) {
361 return DATUM_TYPE
.BOOLEAN
;
363 return DATUM_TYPE
.UNKNOWN
;
367 Get string of given pcdType
369 @param pcdType The given PcdType
371 @return The string of PCD_TYPE.
373 public static String
getStringOfpcdType(PCD_TYPE pcdType
) {
376 return "FEATURE_FLAG";
378 return "FIXED_AT_BUILD";
379 case PATCHABLE_IN_MODULE
:
380 return "PATCHABLE_IN_MODULE";
390 Get the PCD_USAGE according to a string
392 @param usageStr The string of PCD_USAGE
394 @return The PCD_USAGE
396 public static PCD_USAGE
getUsageFromString(String usageStr
) {
397 if (usageStr
== null) {
398 return PCD_USAGE
.UNKNOWN
;
401 if (usageStr
.equalsIgnoreCase("ALWAYS_PRODUCED")) {
402 return PCD_USAGE
.ALWAYS_PRODUCED
;
403 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_PRODUCED")) {
404 return PCD_USAGE
.SOMETIMES_PRODUCED
;
405 } else if (usageStr
.equalsIgnoreCase("ALWAYS_CONSUMED")) {
406 return PCD_USAGE
.ALWAYS_CONSUMED
;
407 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_CONSUMED")) {
408 return PCD_USAGE
.SOMETIMES_CONSUMED
;
411 return PCD_USAGE
.UNKNOWN
;
415 Get the string of given PCD_USAGE
417 @param usage The given PCD_USAGE
419 @return The string of PDC_USAGE.
421 public static String
getStringOfUsage(PCD_USAGE usage
) {
423 case ALWAYS_PRODUCED
:
424 return "ALWAYS_PRODUCED";
425 case ALWAYS_CONSUMED
:
426 return "ALWAYS_CONSUMED";
427 case SOMETIMES_PRODUCED
:
428 return "SOMETIMES_PRODUCED";
429 case SOMETIMES_CONSUMED
:
430 return "SOMETIMES_CONSUMED";
436 Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h
438 @param datumType The given datumType
440 @return string of datum type for autogen.
442 public static String
GetAutogenDefinedatumTypeString(DATUM_TYPE datumType
) {
463 Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen
465 @param datumType The given datumType
467 @return string of datum type.
469 public static String
getAutogendatumTypeString(DATUM_TYPE datumType
) {
488 Get the datumType string for generating some MACROs in autogen file of Library
490 @param datumType The given datumType
492 @return String of datum for genrating bit charater.
494 public static String
getAutogenLibrarydatumTypeString(DATUM_TYPE datumType
) {
514 UUID defined in Schems is object, this function is to tranlate this object
517 @param uuidObj The object comes from schema.
519 @return The traslated UUID instance.
521 public static UUID
getGUIDFromSchemaObject(Object uuidObj
) {
523 if (uuidObj
.toString().equalsIgnoreCase("0")) {
524 uuid
= new UUID(0,0);
526 uuid
= UUID
.fromString(uuidObj
.toString());
532 public DynamicTokenValue
getDefaultSku() {
533 DynamicTokenValue dynamicData
;
535 for (index
= 0; index
< this.skuData
.size(); index
++) {
536 if (skuData
.get(index
).id
== 0) {
537 return skuData
.get(index
).value
;
545 Get default value for a token, For HII type, HiiDefaultValue of default
546 SKU 0 will be returned; For Default type, the defaultvalue of default SKU
551 public String
getDynamicDefaultValue() {
552 DynamicTokenValue dynamicData
= getDefaultSku();
553 if (hasDefaultValue()) {
554 switch (dynamicData
.type
) {
556 return dynamicData
.hiiDefaultValue
;
558 return dynamicData
.value
;
566 // BugBug: We need change this algorithm accordingly when schema is updated
567 // to support no default value.
569 public boolean hasDefaultValue () {
571 boolean isInteger
= true;
572 DynamicTokenValue dynamicValue
= null;
574 if (this.isDynamicPCD
) {
575 dynamicValue
= getDefaultSku();
576 switch (dynamicValue
.type
) {
578 return !isValidNullValue(dynamicValue
.hiiDefaultValue
);
582 return !isValidNullValue(dynamicValue
.value
);
589 public boolean isValidNullValue(String judgedValue
) {
591 BigInteger bigIntValue
;
597 intValue
= Integer
.decode(judgedValue
);
603 if (judgedValue
.length() > 2){
604 if ((judgedValue
.charAt(0) == '0') &&
605 ((judgedValue
.charAt(1) == 'x') ||
606 (judgedValue
.charAt(1) == 'X'))) {
607 bigIntValue
= new BigInteger(judgedValue
.substring(2, judgedValue
.length()), 16);
608 if (bigIntValue
.bitCount() == 0) {
612 bigIntValue
= new BigInteger(judgedValue
);
613 if (bigIntValue
.bitCount() == 0) {
618 bigIntValue
= new BigInteger(judgedValue
);
619 if (bigIntValue
.bitCount() == 0) {
625 if (judgedValue
.equalsIgnoreCase("false")) {
630 if (judgedValue
.equalsIgnoreCase("") ||
631 judgedValue
.equalsIgnoreCase("\"\"") ||
632 judgedValue
.equalsIgnoreCase("L\"\"") ||
633 (judgedValue
.length() == 0) ||
634 judgedValue
.equalsIgnoreCase("{}")) {
642 Judege whether current value is UNICODE string type.
645 public boolean isUnicodeStringType () {
646 String str
= getDynamicDefaultValue();
652 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
653 str
.startsWith("L\"") &&
654 str
.endsWith("\"")) {
661 public String
getStringTypeString () {
662 return getDefaultSku().value
.substring(2, getDefaultSku().value
.length() - 1);