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
.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
.pcd
.entity
.UsageIdentification
;
26 import org
.tianocore
.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 String tokenSpaceName
;
67 /// tokenNumber is allocated by platform. tokenNumber indicate an index for this token in
68 /// platform token space. For Dynamic, dynamicEx type, this number will be re-adjust by
69 /// PCD run-time database autogen tools.
71 public long tokenNumber
;
74 /// This token number is retrieved from FPD file for DynamicEx type.
76 public long dynamicExTokenNumber
;
79 /// All supported PCD type, this value can be retrieved from SPD
80 /// Currently, only record all PCD type for this token in FPD file.
82 public List
<PCD_TYPE
> supportedPcdType
;
85 /// If the token's item type is Dynamic or DynamicEx type, isDynamicPCD
88 public boolean isDynamicPCD
;
91 /// datumSize is to descript the fix size or max size for this token.
92 /// datumSize is defined in SPD.
97 /// datum type is to descript what type can be expressed by a PCD token.
98 /// For same PCD used in different module, the datum type should be unique.
99 /// So it belong memeber to Token class.
101 public DATUM_TYPE datumType
;
104 /// skuData contains all value for SkuNumber of token.
105 /// This field is for Dynamic or DynamicEx type PCD,
107 public List
<SkuInstance
> skuData
;
110 /// consumers array record all module private information who consume this PCD token.
112 public Map
<String
, UsageInstance
> consumers
;
115 Constructure function for Token class
117 @param cName The name of token
118 @param tokenSpaceName The name of token space, it is a guid string
120 public Token(String cName
, String tokenSpaceName
) {
122 this.tokenSpaceName
= tokenSpaceName
;
123 this.tokenNumber
= 0;
124 this.datumType
= DATUM_TYPE
.UNKNOWN
;
126 this.skuData
= new ArrayList
<SkuInstance
>();
128 this.consumers
= new HashMap
<String
, UsageInstance
>();
129 this.supportedPcdType
= new ArrayList
<PCD_TYPE
>();
135 SupportPcdType should be gotten from SPD file actually, but now it just
136 record all PCD type for this token in FPD file.
138 @param pcdType new PCD type found in FPD file for this token.
140 public void updateSupportPcdType(PCD_TYPE pcdType
) {
141 for (int index
= 0; index
< this.supportedPcdType
.size(); index
++) {
142 if (supportedPcdType
.get(index
) == pcdType
) {
148 // If not found, add the pcd type to member variable supportedPcdType
150 supportedPcdType
.add(pcdType
);
154 Judge whether pcdType is belong to dynamic type. Dynamic type includes
155 DYNAMIC and DYNAMIC_EX.
157 @param pcdType the judged pcd type
161 public static boolean isDynamic(PCD_TYPE pcdType
) {
162 if ((pcdType
== PCD_TYPE
.DYNAMIC
) ||
163 (pcdType
== PCD_TYPE
.DYNAMIC_EX
)) {
170 public boolean isDynamicEx() {
171 for (int i
= 0; i
< supportedPcdType
.size(); i
++) {
172 if (supportedPcdType
.get(i
) == PCD_TYPE
.DYNAMIC_EX
) {
181 Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database
183 @param cName Token name.
184 @param tokenSpaceName The token space guid string defined in MSA or SPD
186 @retval primary key for this token in token database.
188 public static String
getPrimaryKeyString(String cName
, String tokenSpaceName
) {
189 if (tokenSpaceName
== null) {
190 return cName
+ "_nullTokenSpaceGuid";
192 return cName
+ "_" + tokenSpaceName
.toString().replace('-', '_');
197 If skudata list contains more than one data, then Sku mechanism is enable.
199 @retval boolean if the number of sku data exceed to 1
201 public boolean isSkuEnable() {
202 if (this.skuData
.size() > 1) {
209 If Hii type for value of token
213 public boolean isHiiEnable() {
214 if (getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.HII_TYPE
) {
221 If Vpd type for value of token
225 public boolean isVpdEnable() {
226 if (getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.VPD_TYPE
) {
233 Get the token primary key in token database.
237 public String
getPrimaryKeyString () {
238 return Token
.getPrimaryKeyString(cName
, tokenSpaceName
);
242 Judge datumType is valid
244 @param type The datumType want to be judged.
246 @retval TRUE - The type is valid.
247 @retval FALSE - The type is invalid.
249 public static boolean isValiddatumType(DATUM_TYPE type
) {
250 if ((type
.ordinal() < DATUM_TYPE
.UINT8
.ordinal() ) ||
251 (type
.ordinal() > DATUM_TYPE
.POINTER
.ordinal())) {
258 Judge pcdType is valid
260 @param type The PCdType want to be judged.
262 @retval TRUE - The type is valid.
263 @retval FALSE - The type is invalid.
265 public static boolean isValidpcdType(PCD_TYPE type
) {
266 if ((type
.ordinal() < PCD_TYPE
.FEATURE_FLAG
.ordinal() ) ||
267 (type
.ordinal() > PCD_TYPE
.DYNAMIC_EX
.ordinal())) {
274 Add an usage instance for token
276 @param usageInstance The usage instance
278 @retval TRUE - Success to add usage instance.
279 @retval FALSE - Fail to add usage instance
281 public boolean addUsageInstance(UsageInstance usageInstance
) throws EntityException
{
284 if (isUsageInstanceExist(usageInstance
.usageId
)) {
285 exceptionStr
= String
.format("[PCD Collection Tool Exception] PCD %s for module %s has already exist in database, Please check all PCD build entries "+
286 "in modules %s in <ModuleSA> to make sure no duplicated definitions in FPD file!",
287 usageInstance
.parentToken
.cName
,
288 usageInstance
.usageId
.moduleName
,
289 usageInstance
.usageId
.moduleName
);
290 throw new EntityException(exceptionStr
);
294 // Put usage instance into usage instance database of this PCD token.
296 consumers
.put(usageInstance
.getPrimaryKey(), usageInstance
);
302 Judge whether exist an usage instance for this token
304 @param usageId The UsageInstance identification for usage instance
306 @return boolean whether exist an usage instance for this token.
308 public boolean isUsageInstanceExist(UsageIdentification usageId
) {
309 String keyStr
= UsageInstance
.getPrimaryKey(usageId
);
311 return (consumers
.get(keyStr
) != null);
315 Get the PCD_TYPE according to the string of PCD_TYPE
317 @param pcdTypeStr The string of PCD_TYPE
321 public static PCD_TYPE
getpcdTypeFromString(String pcdTypeStr
) {
322 if (pcdTypeStr
== null) {
323 return PCD_TYPE
.UNKNOWN
;
326 if (pcdTypeStr
.equalsIgnoreCase("FEATURE_FLAG")) {
327 return PCD_TYPE
.FEATURE_FLAG
;
328 } else if (pcdTypeStr
.equalsIgnoreCase("FIXED_AT_BUILD")) {
329 return PCD_TYPE
.FIXED_AT_BUILD
;
330 } else if (pcdTypeStr
.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {
331 return PCD_TYPE
.PATCHABLE_IN_MODULE
;
332 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC")) {
333 return PCD_TYPE
.DYNAMIC
;
334 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC_EX")) {
335 return PCD_TYPE
.DYNAMIC_EX
;
337 return PCD_TYPE
.UNKNOWN
;
342 Get the string of given datumType. This string will be used for generating autogen files
344 @param datumType Given datumType
346 @return The string of datum type.
348 public static String
getStringOfdatumType(DATUM_TYPE datumType
) {
367 Get the datumType according to a string.
369 @param datumTypeStr The string of datumType
373 public static DATUM_TYPE
getdatumTypeFromString(String datumTypeStr
) {
374 if (datumTypeStr
.equalsIgnoreCase("UINT8")) {
375 return DATUM_TYPE
.UINT8
;
376 } else if (datumTypeStr
.equalsIgnoreCase("UINT16")) {
377 return DATUM_TYPE
.UINT16
;
378 } else if (datumTypeStr
.equalsIgnoreCase("UINT32")) {
379 return DATUM_TYPE
.UINT32
;
380 } else if (datumTypeStr
.equalsIgnoreCase("UINT64")) {
381 return DATUM_TYPE
.UINT64
;
382 } else if (datumTypeStr
.equalsIgnoreCase("VOID*")) {
383 return DATUM_TYPE
.POINTER
;
384 } else if (datumTypeStr
.equalsIgnoreCase("BOOLEAN")) {
385 return DATUM_TYPE
.BOOLEAN
;
387 return DATUM_TYPE
.UNKNOWN
;
391 Get string of given pcdType
393 @param pcdType The given PcdType
395 @return The string of PCD_TYPE.
397 public static String
getStringOfpcdType(PCD_TYPE pcdType
) {
400 return "FEATURE_FLAG";
402 return "FIXED_AT_BUILD";
403 case PATCHABLE_IN_MODULE
:
404 return "PATCHABLE_IN_MODULE";
414 Get the PCD_USAGE according to a string
416 @param usageStr The string of PCD_USAGE
418 @return The PCD_USAGE
420 public static PCD_USAGE
getUsageFromString(String usageStr
) {
421 if (usageStr
== null) {
422 return PCD_USAGE
.UNKNOWN
;
425 if (usageStr
.equalsIgnoreCase("ALWAYS_PRODUCED")) {
426 return PCD_USAGE
.ALWAYS_PRODUCED
;
427 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_PRODUCED")) {
428 return PCD_USAGE
.SOMETIMES_PRODUCED
;
429 } else if (usageStr
.equalsIgnoreCase("ALWAYS_CONSUMED")) {
430 return PCD_USAGE
.ALWAYS_CONSUMED
;
431 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_CONSUMED")) {
432 return PCD_USAGE
.SOMETIMES_CONSUMED
;
435 return PCD_USAGE
.UNKNOWN
;
439 Get the string of given PCD_USAGE
441 @param usage The given PCD_USAGE
443 @return The string of PDC_USAGE.
445 public static String
getStringOfUsage(PCD_USAGE usage
) {
447 case ALWAYS_PRODUCED
:
448 return "ALWAYS_PRODUCED";
449 case ALWAYS_CONSUMED
:
450 return "ALWAYS_CONSUMED";
451 case SOMETIMES_PRODUCED
:
452 return "SOMETIMES_PRODUCED";
453 case SOMETIMES_CONSUMED
:
454 return "SOMETIMES_CONSUMED";
460 Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h
462 @param datumType The given datumType
464 @return string of datum type for autogen.
466 public static String
GetAutogenDefinedatumTypeString(DATUM_TYPE datumType
) {
487 Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen
489 @param datumType The given datumType
491 @return string of datum type.
494 public static String
getAutogendatumTypeString(DATUM_TYPE datumType
) {
513 Get the datumType string for generating some MACROs in autogen file of Library
515 @param datumType The given datumType
517 @return String of datum for genrating bit charater.
519 public static String
getAutogenLibrarydatumTypeString(DATUM_TYPE datumType
) {
539 Get the sku data who id is 0.
541 @retval DynamicTokenValue the value of this dyanmic token.
543 public DynamicTokenValue
getDefaultSku() {
544 DynamicTokenValue dynamicData
;
547 for (index
= 0; index
< this.skuData
.size(); index
++) {
548 if (skuData
.get(index
).id
== 0) {
549 return skuData
.get(index
).value
;
557 Get the number of Sku data for this token
559 @retval int the number of sku data
561 public int getSkuIdCount () {
562 return this.skuData
.size();
566 Get the size of PCD value, this PCD is POINTER type.
568 @param str the string of the value
571 private void getCurrentSizeFromDefaultValue (String str
, ArrayList
<Integer
> al
) {
572 if (isValidNullValue(str
)) {
573 al
.add(new Integer(0));
576 // isValidNullValue has already make sure that str here
577 // always contain a valid default value of the following 3
579 // 1) "Hello world" //Assci string
580 // 2) L"Hello" //Unicode string
581 // 3) {0x01, 0x02, 0x03} //Byte stream
583 if (str
.startsWith("\"")) {
584 al
.add(new Integer(str
.length() - 2));
585 } else if (str
.startsWith("L\"")){
587 // Unicode is 2 bytes each.
589 al
.add(new Integer((str
.length() - 3) * 2));
590 } else if (str
.startsWith("{")) {
592 // We count the number of "," in the string.
593 // The number of byte is one plus the number of
600 pos
= str2
.indexOf(",", 0);
604 pos
= str2
.indexOf(",", pos
);
607 al
.add(new Integer(cnt
));
613 This method can be used to get the MAX and current size
614 for pointer type dynamic(ex) PCD entry
616 public ArrayList
<Integer
> getPointerTypeSize () {
617 ArrayList
<Integer
> al
= new ArrayList
<Integer
>();
620 // For VPD_enabled and HII_enabled, we can only return the MAX size.
621 // For the default DATA type dynamic PCD entry, we will return
622 // the MAX size and current size for each SKU_ID.
624 al
.add(new Integer(this.datumSize
));
626 if (!this.isVpdEnable()) {
628 if (this.isHiiEnable()){
629 for (idx
= 0; idx
< this.skuData
.size(); idx
++) {
630 String str
= this.skuData
.get(idx
).value
.hiiDefaultValue
;
631 getCurrentSizeFromDefaultValue(str
, al
);
634 for (idx
= 0; idx
< this.skuData
.size(); idx
++) {
635 String str
= this.skuData
.get(idx
).value
.value
;
636 getCurrentSizeFromDefaultValue(str
, al
);
645 Get default value for a token, For HII type, HiiDefaultValue of default
646 SKU 0 will be returned; For Default type, the defaultvalue of default SKU
651 public String
getDynamicDefaultValue() {
652 DynamicTokenValue dynamicData
= getDefaultSku();
653 if (hasDefaultValue()) {
654 switch (dynamicData
.type
) {
656 return dynamicData
.value
;
664 // BugBug: We need change this algorithm accordingly when schema is updated
665 // to support no default value.
667 public boolean hasDefaultValue () {
669 boolean isInteger
= true;
670 DynamicTokenValue dynamicValue
= null;
676 if (this.isDynamicPCD
) {
677 dynamicValue
= getDefaultSku();
678 switch (dynamicValue
.type
) {
684 return !isValidNullValue(dynamicValue
.value
);
692 Judge the value is NULL value. NULL value means the value is uninitialized value
698 public boolean isValidNullValue(String judgedValue
) {
700 BigInteger bigIntValue
;
706 if (judgedValue
.length() > 2) {
707 if ((judgedValue
.charAt(0) == '0') &&
708 ((judgedValue
.charAt(1) == 'x') || (judgedValue
.charAt(1) == 'X'))){
709 subStr
= judgedValue
.substring(2, judgedValue
.length());
710 bigIntValue
= new BigInteger(subStr
, 16);
712 bigIntValue
= new BigInteger(judgedValue
);
715 bigIntValue
= new BigInteger(judgedValue
);
717 if (bigIntValue
.bitCount() == 0) {
722 if (judgedValue
.length() > 2){
723 if ((judgedValue
.charAt(0) == '0') &&
724 ((judgedValue
.charAt(1) == 'x') ||
725 (judgedValue
.charAt(1) == 'X'))) {
726 bigIntValue
= new BigInteger(judgedValue
.substring(2, judgedValue
.length()), 16);
727 if (bigIntValue
.bitCount() == 0) {
731 bigIntValue
= new BigInteger(judgedValue
);
732 if (bigIntValue
.bitCount() == 0) {
737 bigIntValue
= new BigInteger(judgedValue
);
738 if (bigIntValue
.bitCount() == 0) {
744 if (judgedValue
.equalsIgnoreCase("false")) {
749 if (judgedValue
.equalsIgnoreCase("") ||
750 judgedValue
.equalsIgnoreCase("\"\"") ||
751 judgedValue
.equalsIgnoreCase("L\"\"") ||
752 (judgedValue
.length() == 0) ||
753 judgedValue
.equalsIgnoreCase("{0}")) {
761 Is the string value in Unicode
765 public boolean isHiiDefaultValueUnicodeStringType() {
766 DynamicTokenValue dynamicData
= getDefaultSku();
768 if (dynamicData
== null)
771 return dynamicData
.hiiDefaultValue
.startsWith("L\"")
772 && dynamicData
.hiiDefaultValue
.endsWith("\"");
776 Is the string value in ANSCI
780 public boolean isHiiDefaultValueASCIIStringType() {
781 DynamicTokenValue dynamicData
= getDefaultSku();
783 if (dynamicData
== null)
786 return dynamicData
.hiiDefaultValue
.startsWith("\"")
787 && dynamicData
.hiiDefaultValue
.endsWith("\"");
791 Judege whether current value is UNICODE string type.
794 public boolean isUnicodeStringType () {
795 String str
= getDynamicDefaultValue();
801 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
802 str
.startsWith("L\"") &&
803 str
.endsWith("\"")) {
810 public boolean isASCIIStringType () {
811 String str
= getDynamicDefaultValue();
817 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
818 str
.startsWith("\"") &&
819 str
.endsWith("\"")) {
826 public boolean isByteStreamType () {
827 String str
= getDynamicDefaultValue();
833 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
834 str
.startsWith("{") &&
843 public String
getStringTypeString () {
844 return getDefaultSku().value
.substring(2, getDefaultSku().value
.length() - 1);