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
;
24 import org
.tianocore
.pcd
.entity
.UsageIdentification
;
25 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.
35 public enum PCD_TYPE
{FEATURE_FLAG
, FIXED_AT_BUILD
, PATCHABLE_IN_MODULE
, DYNAMIC
,
39 /// Enumeration macro definition for datum type. All type mainly comes from ProcessBind.h.
40 /// Wizard maybe expand this type as "int, unsigned int, short, unsigned short etc" in
43 public enum DATUM_TYPE
{UINT8
, UINT16
, UINT32
, UINT64
, BOOLEAN
, POINTER
, UNKNOWN
}
46 /// Enumeration macor defintion for usage of PCD
48 public enum PCD_USAGE
{ALWAYS_PRODUCED
, ALWAYS_CONSUMED
, SOMETIMES_PRODUCED
,
49 SOMETIMES_CONSUMED
, UNKNOWN
}
52 /// cName is to identify a PCD entry and will be used for generating autogen.h/autogen.c.
53 /// cName will be defined in MSA, SPD and FPD, can be regarded as primary key with token space guid.
58 /// Token space name is the guid defined by token itself in package or module level. This
59 /// name mainly for DynamicEx type. For other PCD type token, his token space name is the
60 /// assignedtokenSpaceName as follows.
61 /// tokenSpaceName is defined in MSA, SPD, FPD, can be regarded as primary key with cName.
63 public String tokenSpaceName
;
66 /// tokenNumber is allocated by platform. tokenNumber indicate an index for this token in
67 /// platform token space. For Dynamic, dynamicEx type, this number will be re-adjust by
68 /// PCD run-time database autogen tools.
70 public long tokenNumber
;
73 /// This token number is retrieved from FPD file for DynamicEx type.
75 public long dynamicExTokenNumber
;
78 /// All supported PCD type, this value can be retrieved from SPD
79 /// Currently, only record all PCD type for this token in FPD file.
81 public List
<PCD_TYPE
> supportedPcdType
;
84 /// If the token's item type is Dynamic or DynamicEx type, isDynamicPCD
87 public boolean isDynamicPCD
;
90 /// datumSize is to descript the fix size or max size for this token.
91 /// datumSize is defined in SPD.
96 /// datum type is to descript what type can be expressed by a PCD token.
97 /// For same PCD used in different module, the datum type should be unique.
98 /// So it belong memeber to Token class.
100 public DATUM_TYPE datumType
;
103 /// skuData contains all value for SkuNumber of token.
104 /// This field is for Dynamic or DynamicEx type PCD,
106 public List
<SkuInstance
> skuData
;
109 /// consumers array record all module private information who consume this PCD token.
111 public Map
<String
, UsageInstance
> consumers
;
114 Constructure function for Token class
116 @param cName The name of token
117 @param tokenSpaceName The name of token space, it is a guid string
119 public Token(String cName
, String tokenSpaceName
) {
121 this.tokenSpaceName
= tokenSpaceName
;
122 this.tokenNumber
= 0;
123 this.datumType
= DATUM_TYPE
.UNKNOWN
;
125 this.skuData
= new ArrayList
<SkuInstance
>();
127 this.consumers
= new HashMap
<String
, UsageInstance
>();
128 this.supportedPcdType
= new ArrayList
<PCD_TYPE
>();
134 SupportPcdType should be gotten from SPD file actually, but now it just
135 record all PCD type for this token in FPD file.
137 @param pcdType new PCD type found in FPD file for this token.
139 public void updateSupportPcdType(PCD_TYPE pcdType
) {
140 for (int index
= 0; index
< this.supportedPcdType
.size(); index
++) {
141 if (supportedPcdType
.get(index
) == pcdType
) {
147 // If not found, add the pcd type to member variable supportedPcdType
149 supportedPcdType
.add(pcdType
);
153 Judge whether pcdType is belong to dynamic type. Dynamic type includes
154 DYNAMIC and DYNAMIC_EX.
156 @param pcdType the judged pcd type
160 public static boolean isDynamic(PCD_TYPE pcdType
) {
161 if ((pcdType
== PCD_TYPE
.DYNAMIC
) ||
162 (pcdType
== PCD_TYPE
.DYNAMIC_EX
)) {
169 public boolean isDynamicEx() {
170 for (int i
= 0; i
< supportedPcdType
.size(); i
++) {
171 if (supportedPcdType
.get(i
) == PCD_TYPE
.DYNAMIC_EX
) {
180 Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database
182 @param cName Token name.
183 @param tokenSpaceName The token space guid string defined in MSA or SPD
185 @retval primary key for this token in token database.
187 public static String
getPrimaryKeyString(String cName
, String tokenSpaceName
) {
188 if (tokenSpaceName
== null) {
189 return cName
+ "_nullTokenSpaceGuid";
191 return cName
+ "_" + tokenSpaceName
.toString().replace('-', '_');
196 If skudata list contains more than one data, then Sku mechanism is enable.
198 @retval boolean if the number of sku data exceed to 1
200 public boolean isSkuEnable() {
201 if (this.skuData
.size() > 1) {
208 If Hii type for value of token
212 public boolean isHiiEnable() {
213 if (getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.HII_TYPE
) {
220 If Vpd type for value of token
224 public boolean isVpdEnable() {
225 if (getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.VPD_TYPE
) {
232 Get the token primary key in token database.
236 public String
getPrimaryKeyString () {
237 return Token
.getPrimaryKeyString(cName
, tokenSpaceName
);
241 Judge datumType is valid
243 @param type The datumType want to be judged.
245 @retval TRUE - The type is valid.
246 @retval FALSE - The type is invalid.
248 public static boolean isValiddatumType(DATUM_TYPE type
) {
249 if ((type
.ordinal() < DATUM_TYPE
.UINT8
.ordinal() ) ||
250 (type
.ordinal() > DATUM_TYPE
.POINTER
.ordinal())) {
257 Judge pcdType is valid
259 @param type The PCdType want to be judged.
261 @retval TRUE - The type is valid.
262 @retval FALSE - The type is invalid.
264 public static boolean isValidpcdType(PCD_TYPE type
) {
265 if ((type
.ordinal() < PCD_TYPE
.FEATURE_FLAG
.ordinal() ) ||
266 (type
.ordinal() > PCD_TYPE
.DYNAMIC_EX
.ordinal())) {
273 Add an usage instance for token
275 @param usageInstance The usage instance
277 @retval TRUE - Success to add usage instance.
278 @retval FALSE - Fail to add usage instance
280 public boolean addUsageInstance(UsageInstance usageInstance
) throws EntityException
{
283 if (isUsageInstanceExist(usageInstance
.usageId
)) {
284 exceptionStr
= String
.format("[PCD Collection Tool Exception] PCD %s for module %s has already exist in database, Please check all PCD build entries "+
285 "in modules %s in <ModuleSA> to make sure no duplicated definitions in FPD file!",
286 usageInstance
.parentToken
.cName
,
287 usageInstance
.usageId
.moduleName
,
288 usageInstance
.usageId
.moduleName
);
289 throw new EntityException(exceptionStr
);
293 // Put usage instance into usage instance database of this PCD token.
295 consumers
.put(usageInstance
.getPrimaryKey(), usageInstance
);
301 Judge whether exist an usage instance for this token
303 @param usageId The UsageInstance identification for usage instance
305 @return boolean whether exist an usage instance for this token.
307 public boolean isUsageInstanceExist(UsageIdentification usageId
) {
308 String keyStr
= UsageInstance
.getPrimaryKey(usageId
);
310 return (consumers
.get(keyStr
) != null);
314 Get the PCD_TYPE according to the string of PCD_TYPE
316 @param pcdTypeStr The string of PCD_TYPE
320 public static PCD_TYPE
getpcdTypeFromString(String pcdTypeStr
) {
321 if (pcdTypeStr
== null) {
322 return PCD_TYPE
.UNKNOWN
;
325 if (pcdTypeStr
.equalsIgnoreCase("FEATURE_FLAG")) {
326 return PCD_TYPE
.FEATURE_FLAG
;
327 } else if (pcdTypeStr
.equalsIgnoreCase("FIXED_AT_BUILD")) {
328 return PCD_TYPE
.FIXED_AT_BUILD
;
329 } else if (pcdTypeStr
.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {
330 return PCD_TYPE
.PATCHABLE_IN_MODULE
;
331 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC")) {
332 return PCD_TYPE
.DYNAMIC
;
333 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC_EX")) {
334 return PCD_TYPE
.DYNAMIC_EX
;
336 return PCD_TYPE
.UNKNOWN
;
341 Get the string of given datumType. This string will be used for generating autogen files
343 @param datumType Given datumType
345 @return The string of datum type.
347 public static String
getStringOfdatumType(DATUM_TYPE datumType
) {
366 Get the datumType according to a string.
368 @param datumTypeStr The string of datumType
372 public static DATUM_TYPE
getdatumTypeFromString(String datumTypeStr
) {
373 if (datumTypeStr
.equalsIgnoreCase("UINT8")) {
374 return DATUM_TYPE
.UINT8
;
375 } else if (datumTypeStr
.equalsIgnoreCase("UINT16")) {
376 return DATUM_TYPE
.UINT16
;
377 } else if (datumTypeStr
.equalsIgnoreCase("UINT32")) {
378 return DATUM_TYPE
.UINT32
;
379 } else if (datumTypeStr
.equalsIgnoreCase("UINT64")) {
380 return DATUM_TYPE
.UINT64
;
381 } else if (datumTypeStr
.equalsIgnoreCase("VOID*")) {
382 return DATUM_TYPE
.POINTER
;
383 } else if (datumTypeStr
.equalsIgnoreCase("BOOLEAN")) {
384 return DATUM_TYPE
.BOOLEAN
;
386 return DATUM_TYPE
.UNKNOWN
;
390 Get string of given pcdType
392 @param pcdType The given PcdType
394 @return The string of PCD_TYPE.
396 public static String
getStringOfpcdType(PCD_TYPE pcdType
) {
399 return "FEATURE_FLAG";
401 return "FIXED_AT_BUILD";
402 case PATCHABLE_IN_MODULE
:
403 return "PATCHABLE_IN_MODULE";
413 Get the PCD_USAGE according to a string
415 @param usageStr The string of PCD_USAGE
417 @return The PCD_USAGE
419 public static PCD_USAGE
getUsageFromString(String usageStr
) {
420 if (usageStr
== null) {
421 return PCD_USAGE
.UNKNOWN
;
424 if (usageStr
.equalsIgnoreCase("ALWAYS_PRODUCED")) {
425 return PCD_USAGE
.ALWAYS_PRODUCED
;
426 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_PRODUCED")) {
427 return PCD_USAGE
.SOMETIMES_PRODUCED
;
428 } else if (usageStr
.equalsIgnoreCase("ALWAYS_CONSUMED")) {
429 return PCD_USAGE
.ALWAYS_CONSUMED
;
430 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_CONSUMED")) {
431 return PCD_USAGE
.SOMETIMES_CONSUMED
;
434 return PCD_USAGE
.UNKNOWN
;
438 Get the string of given PCD_USAGE
440 @param usage The given PCD_USAGE
442 @return The string of PDC_USAGE.
444 public static String
getStringOfUsage(PCD_USAGE usage
) {
446 case ALWAYS_PRODUCED
:
447 return "ALWAYS_PRODUCED";
448 case ALWAYS_CONSUMED
:
449 return "ALWAYS_CONSUMED";
450 case SOMETIMES_PRODUCED
:
451 return "SOMETIMES_PRODUCED";
452 case SOMETIMES_CONSUMED
:
453 return "SOMETIMES_CONSUMED";
459 Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h
461 @param datumType The given datumType
463 @return string of datum type for autogen.
465 public static String
GetAutogenDefinedatumTypeString(DATUM_TYPE datumType
) {
486 Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen
488 @param datumType The given datumType
490 @return string of datum type.
493 public static String
getAutogendatumTypeString(DATUM_TYPE datumType
) {
512 Get the datumType string for generating some MACROs in autogen file of Library
514 @param datumType The given datumType
516 @return String of datum for genrating bit charater.
518 public static String
getAutogenLibrarydatumTypeString(DATUM_TYPE datumType
) {
538 Get the sku data who id is 0.
540 @retval DynamicTokenValue the value of this dyanmic token.
542 public DynamicTokenValue
getDefaultSku() {
545 for (index
= 0; index
< this.skuData
.size(); index
++) {
546 if (skuData
.get(index
).id
== 0) {
547 return skuData
.get(index
).value
;
555 Get the number of Sku data for this token
557 @retval int the number of sku data
559 public int getSkuIdCount () {
560 return this.skuData
.size();
564 Get the size of PCD value, this PCD is POINTER type.
566 @param str the string of the value
569 private void getCurrentSizeFromDefaultValue (String str
, ArrayList
<Integer
> al
) {
570 if (isValidNullValue(str
)) {
571 al
.add(new Integer(0));
574 // isValidNullValue has already make sure that str here
575 // always contain a valid default value of the following 3
577 // 1) "Hello world" //Assci string
578 // 2) L"Hello" //Unicode string
579 // 3) {0x01, 0x02, 0x03} //Byte stream
581 if (str
.startsWith("\"")) {
582 al
.add(new Integer(str
.length() - 2));
583 } else if (str
.startsWith("L\"")){
585 // Unicode is 2 bytes each.
587 al
.add(new Integer((str
.length() - 3) * 2));
588 } else if (str
.startsWith("{")) {
590 // We count the number of "," in the string.
591 // The number of byte is one plus the number of
598 pos
= str2
.indexOf(",", 0);
602 pos
= str2
.indexOf(",", pos
);
605 al
.add(new Integer(cnt
));
611 This method can be used to get the MAX and current size
612 for pointer type dynamic(ex) PCD entry
614 public ArrayList
<Integer
> getPointerTypeSize () {
615 ArrayList
<Integer
> al
= new ArrayList
<Integer
>();
618 // For VPD_enabled and HII_enabled, we can only return the MAX size.
619 // For the default DATA type dynamic PCD entry, we will return
620 // the MAX size and current size for each SKU_ID.
622 al
.add(new Integer(this.datumSize
));
624 if (!this.isVpdEnable()) {
626 if (this.isHiiEnable()){
627 for (idx
= 0; idx
< this.skuData
.size(); idx
++) {
628 String str
= this.skuData
.get(idx
).value
.hiiDefaultValue
;
629 getCurrentSizeFromDefaultValue(str
, al
);
632 for (idx
= 0; idx
< this.skuData
.size(); idx
++) {
633 String str
= this.skuData
.get(idx
).value
.value
;
634 getCurrentSizeFromDefaultValue(str
, al
);
643 Get default value for a token, For HII type, HiiDefaultValue of default
644 SKU 0 will be returned; For Default type, the defaultvalue of default SKU
649 public String
getDynamicDefaultValue() {
650 DynamicTokenValue dynamicData
= getDefaultSku();
651 if (hasDefaultValue()) {
652 switch (dynamicData
.type
) {
654 return dynamicData
.value
;
662 // BugBug: We need change this algorithm accordingly when schema is updated
663 // to support no default value.
665 public boolean hasDefaultValue () {
666 DynamicTokenValue dynamicValue
= null;
672 if (this.isDynamicPCD
) {
673 dynamicValue
= getDefaultSku();
674 switch (dynamicValue
.type
) {
680 return !isValidNullValue(dynamicValue
.value
);
688 Judge the value is NULL value. NULL value means the value is uninitialized value
694 public boolean isValidNullValue(String judgedValue
) {
696 BigInteger bigIntValue
;
702 if (judgedValue
.length() > 2) {
703 if ((judgedValue
.charAt(0) == '0') &&
704 ((judgedValue
.charAt(1) == 'x') || (judgedValue
.charAt(1) == 'X'))){
705 subStr
= judgedValue
.substring(2, judgedValue
.length());
706 bigIntValue
= new BigInteger(subStr
, 16);
708 bigIntValue
= new BigInteger(judgedValue
);
711 bigIntValue
= new BigInteger(judgedValue
);
713 if (bigIntValue
.bitCount() == 0) {
718 if (judgedValue
.length() > 2){
719 if ((judgedValue
.charAt(0) == '0') &&
720 ((judgedValue
.charAt(1) == 'x') ||
721 (judgedValue
.charAt(1) == 'X'))) {
722 bigIntValue
= new BigInteger(judgedValue
.substring(2, judgedValue
.length()), 16);
723 if (bigIntValue
.bitCount() == 0) {
727 bigIntValue
= new BigInteger(judgedValue
);
728 if (bigIntValue
.bitCount() == 0) {
733 bigIntValue
= new BigInteger(judgedValue
);
734 if (bigIntValue
.bitCount() == 0) {
740 if (judgedValue
.equalsIgnoreCase("false")) {
745 if (judgedValue
.equalsIgnoreCase("") ||
746 judgedValue
.equalsIgnoreCase("\"\"") ||
747 judgedValue
.equalsIgnoreCase("L\"\"") ||
748 (judgedValue
.length() == 0) ||
749 judgedValue
.equalsIgnoreCase("{0}")) {
757 Is the string value in Unicode
761 public boolean isHiiDefaultValueUnicodeStringType() {
762 DynamicTokenValue dynamicData
= getDefaultSku();
764 if (dynamicData
== null)
767 return dynamicData
.hiiDefaultValue
.startsWith("L\"")
768 && dynamicData
.hiiDefaultValue
.endsWith("\"");
772 Is the string value in ANSCI
776 public boolean isHiiDefaultValueASCIIStringType() {
777 DynamicTokenValue dynamicData
= getDefaultSku();
779 if (dynamicData
== null)
782 return dynamicData
.hiiDefaultValue
.startsWith("\"")
783 && dynamicData
.hiiDefaultValue
.endsWith("\"");
787 Judege whether current value is UNICODE string type.
790 public boolean isUnicodeStringType () {
791 String str
= getDynamicDefaultValue();
797 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
798 str
.startsWith("L\"") &&
799 str
.endsWith("\"")) {
806 public boolean isASCIIStringType () {
807 String str
= getDynamicDefaultValue();
813 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
814 str
.startsWith("\"") &&
815 str
.endsWith("\"")) {
822 public boolean isByteStreamType () {
823 String str
= getDynamicDefaultValue();
829 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
830 str
.startsWith("{") &&
839 public String
getStringTypeString () {
840 return getDefaultSku().value
.substring(2, getDefaultSku().value
.length() - 1);