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
;
25 This class is to descript a PCD token object. The information of a token mainly
26 comes from MSA, SPD and setting produced by platform developer.
30 /// Enumeration macro defintion for PCD type.
32 public static enum PCD_TYPE
{FEATURE_FLAG
, FIXED_AT_BUILD
, PATCHABLE_IN_MODULE
, DYNAMIC
,
36 /// Enumeration macro definition for datum type. All type mainly comes from ProcessBind.h.
37 /// Wizard maybe expand this type as "int, unsigned int, short, unsigned short etc" in
40 public static enum DATUM_TYPE
{UINT8
, UINT16
, UINT32
, UINT64
, BOOLEAN
, POINTER
, UNKNOWN
}
43 /// Enumeration macor defintion for usage of PCD
45 public static enum PCD_USAGE
{ALWAYS_PRODUCED
, ALWAYS_CONSUMED
, SOMETIMES_PRODUCED
,
46 SOMETIMES_CONSUMED
, UNKNOWN
}
49 /// cName is to identify a PCD entry and will be used for generating autogen.h/autogen.c.
50 /// cName will be defined in MSA, SPD and FPD, can be regarded as primary key with token space guid.
55 /// Token space name is the guid defined by token itself in package or module level. This
56 /// name mainly for DynamicEx type. For other PCD type token, his token space name is the
57 /// assignedtokenSpaceName as follows.
58 /// tokenSpaceName is defined in MSA, SPD, FPD, can be regarded as primary key with cName.
60 public String tokenSpaceName
;
63 /// tokenNumber is allocated by platform. tokenNumber indicate an index for this token in
64 /// platform token space. For Dynamic, dynamicEx type, this number will be re-adjust by
65 /// PCD run-time database autogen tools.
67 public long tokenNumber
;
70 /// This token number is retrieved from FPD file for DynamicEx type.
72 public long dynamicExTokenNumber
;
75 /// All supported PCD type, this value can be retrieved from SPD
76 /// Currently, only record all PCD type for this token in FPD file.
78 public List
<PCD_TYPE
> supportedPcdType
;
81 /// If the token's item type is Dynamic or DynamicEx type, isDynamicPCD
84 public boolean isDynamicPCD
;
87 /// datumSize is to descript the fix size or max size for this token.
88 /// datumSize is defined in SPD.
93 /// datum type is to descript what type can be expressed by a PCD token.
94 /// For same PCD used in different module, the datum type should be unique.
95 /// So it belong memeber to Token class.
97 public DATUM_TYPE datumType
;
100 /// skuData contains all value for SkuNumber of token.
101 /// This field is for Dynamic or DynamicEx type PCD,
103 public List
<SkuInstance
> skuData
;
106 /// consumers array record all module private information who consume this PCD token.
108 public Map
<String
, UsageInstance
> consumers
;
111 Constructure function for Token class
113 @param cName The name of token
114 @param tokenSpaceName The name of token space, it is a guid string
116 public Token(String cName
, String tokenSpaceName
) {
118 this.tokenSpaceName
= tokenSpaceName
;
119 this.tokenNumber
= 0;
120 this.datumType
= DATUM_TYPE
.UNKNOWN
;
122 this.skuData
= new ArrayList
<SkuInstance
>();
124 this.consumers
= new HashMap
<String
, UsageInstance
>();
125 this.supportedPcdType
= new ArrayList
<PCD_TYPE
>();
131 SupportPcdType should be gotten from SPD file actually, but now it just
132 record all PCD type for this token in FPD file.
134 @param pcdType new PCD type found in FPD file for this token.
136 public void updateSupportPcdType(PCD_TYPE pcdType
) {
137 int size
= supportedPcdType
.size();
138 for (int index
= 0; index
< size
; index
++) {
139 if (supportedPcdType
.get(index
) == pcdType
) {
145 // If not found, add the pcd type to member variable supportedPcdType
147 supportedPcdType
.add(pcdType
);
151 Judge whether pcdType is belong to dynamic type. Dynamic type includes
152 DYNAMIC and DYNAMIC_EX.
154 @param pcdType the judged pcd type
158 public static boolean isDynamic(PCD_TYPE pcdType
) {
159 if ((pcdType
== PCD_TYPE
.DYNAMIC
) ||
160 (pcdType
== PCD_TYPE
.DYNAMIC_EX
)) {
168 The pcd type is DynamicEx?
170 @retval true Is DynamicEx type
171 @retval false not DynamicEx type
173 public boolean isDynamicEx() {
174 int size
= supportedPcdType
.size();
175 for (int i
= 0; i
< size
; i
++) {
176 if (supportedPcdType
.get(i
) == PCD_TYPE
.DYNAMIC_EX
) {
185 Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database
187 @param cName Token name.
188 @param tokenSpaceName The token space guid string defined in MSA or SPD
190 @retval primary key for this token in token database.
192 public static String
getPrimaryKeyString(String cName
, String tokenSpaceName
) {
193 if (tokenSpaceName
== null) {
194 return cName
+ "_nullTokenSpaceGuid";
196 return cName
+ "_" + tokenSpaceName
.toString().replace('-', '_').toLowerCase();
201 If skudata list contains more than one data, then Sku mechanism is enable.
203 @retval boolean if the number of sku data exceed to 1
205 public boolean isSkuEnable() {
206 if (this.skuData
.size() > 1) {
213 If Hii type for value of token
217 public boolean isHiiEnable() {
218 if (getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.HII_TYPE
) {
225 If Vpd type for value of token
229 public boolean isVpdEnable() {
230 if (getDefaultSku().type
== DynamicTokenValue
.VALUE_TYPE
.VPD_TYPE
) {
237 Get the token primary key in token database.
241 public String
getPrimaryKeyString () {
242 return Token
.getPrimaryKeyString(cName
, tokenSpaceName
);
246 Judge datumType is valid
248 @param type The datumType want to be judged.
250 @retval TRUE - The type is valid.
251 @retval FALSE - The type is invalid.
253 public static boolean isValiddatumType(DATUM_TYPE type
) {
254 if ((type
.ordinal() < DATUM_TYPE
.UINT8
.ordinal() ) ||
255 (type
.ordinal() > DATUM_TYPE
.POINTER
.ordinal())) {
262 Judge pcdType is valid
264 @param type The PCdType want to be judged.
266 @retval TRUE - The type is valid.
267 @retval FALSE - The type is invalid.
269 public static boolean isValidpcdType(PCD_TYPE type
) {
270 if ((type
.ordinal() < PCD_TYPE
.FEATURE_FLAG
.ordinal() ) ||
271 (type
.ordinal() > PCD_TYPE
.DYNAMIC_EX
.ordinal())) {
278 Add an usage instance for token
280 @param usageInstance The usage instance
282 @retval TRUE - Success to add usage instance.
283 @retval FALSE - Fail to add usage instance
285 public boolean addUsageInstance(UsageInstance usageInstance
) {
286 if (isUsageInstanceExist(usageInstance
.usageId
)) {
291 // Put usage instance into usage instance database of this PCD token.
293 consumers
.put(usageInstance
.getPrimaryKey(), usageInstance
);
299 Judge whether exist an usage instance for this token
301 @param usageId The UsageInstance identification for usage instance
303 @return boolean whether exist an usage instance for this token.
305 public boolean isUsageInstanceExist(UsageIdentification usageId
) {
306 String keyStr
= UsageInstance
.getPrimaryKey(usageId
);
308 return (consumers
.get(keyStr
) != null);
312 Get the PCD_TYPE according to the string of PCD_TYPE
314 @param pcdTypeStr The string of PCD_TYPE
318 public static PCD_TYPE
getPcdTypeFromString(String pcdTypeStr
) {
319 if (pcdTypeStr
== null) {
320 return PCD_TYPE
.UNKNOWN
;
323 if (pcdTypeStr
.equalsIgnoreCase("FEATURE_FLAG")) {
324 return PCD_TYPE
.FEATURE_FLAG
;
325 } else if (pcdTypeStr
.equalsIgnoreCase("FIXED_AT_BUILD")) {
326 return PCD_TYPE
.FIXED_AT_BUILD
;
327 } else if (pcdTypeStr
.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {
328 return PCD_TYPE
.PATCHABLE_IN_MODULE
;
329 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC")) {
330 return PCD_TYPE
.DYNAMIC
;
331 } else if (pcdTypeStr
.equalsIgnoreCase("DYNAMIC_EX")) {
332 return PCD_TYPE
.DYNAMIC_EX
;
334 return PCD_TYPE
.UNKNOWN
;
339 Get the string of given datumType. This string will be used for generating autogen files
341 @param datumType Given datumType
343 @return The string of datum type.
345 public static String
getStringOfdatumType(DATUM_TYPE datumType
) {
346 return datumType
.toString();
350 Get the datumType according to a string.
352 @param datumTypeStr The string of datumType
356 public static DATUM_TYPE
getdatumTypeFromString(String datumTypeStr
) {
357 if (datumTypeStr
.equalsIgnoreCase("UINT8")) {
358 return DATUM_TYPE
.UINT8
;
359 } else if (datumTypeStr
.equalsIgnoreCase("UINT16")) {
360 return DATUM_TYPE
.UINT16
;
361 } else if (datumTypeStr
.equalsIgnoreCase("UINT32")) {
362 return DATUM_TYPE
.UINT32
;
363 } else if (datumTypeStr
.equalsIgnoreCase("UINT64")) {
364 return DATUM_TYPE
.UINT64
;
365 } else if (datumTypeStr
.equalsIgnoreCase("VOID*")) {
366 return DATUM_TYPE
.POINTER
;
367 } else if (datumTypeStr
.equalsIgnoreCase("BOOLEAN")) {
368 return DATUM_TYPE
.BOOLEAN
;
370 return DATUM_TYPE
.UNKNOWN
;
374 Get string of given pcdType
376 @param pcdType The given PcdType
378 @return The string of PCD_TYPE.
380 public static String
getStringOfpcdType(PCD_TYPE pcdType
) {
381 return pcdType
.toString();
385 Get the PCD_USAGE according to a string
387 @param usageStr The string of PCD_USAGE
389 @return The PCD_USAGE
391 public static PCD_USAGE
getUsageFromString(String usageStr
) {
392 if (usageStr
== null) {
393 return PCD_USAGE
.UNKNOWN
;
396 if (usageStr
.equalsIgnoreCase("ALWAYS_PRODUCED")) {
397 return PCD_USAGE
.ALWAYS_PRODUCED
;
398 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_PRODUCED")) {
399 return PCD_USAGE
.SOMETIMES_PRODUCED
;
400 } else if (usageStr
.equalsIgnoreCase("ALWAYS_CONSUMED")) {
401 return PCD_USAGE
.ALWAYS_CONSUMED
;
402 } else if (usageStr
.equalsIgnoreCase("SOMETIMES_CONSUMED")) {
403 return PCD_USAGE
.SOMETIMES_CONSUMED
;
406 return PCD_USAGE
.UNKNOWN
;
410 Get the string of given PCD_USAGE
412 @param usage The given PCD_USAGE
414 @return The string of PDC_USAGE.
416 public static String
getStringOfUsage(PCD_USAGE usage
) {
417 return usage
.toString();
421 Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h
423 @param datumType The given datumType
425 @return string of datum type for autogen.
427 public static String
GetAutogenDefinedatumTypeString(DATUM_TYPE datumType
) {
448 Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen
450 @param datumType The given datumType
452 @return string of datum type.
455 public static String
getAutogendatumTypeString(DATUM_TYPE datumType
) {
474 Get the datumType string for generating some MACROs in autogen file of Library
476 @param datumType The given datumType
478 @return String of datum for genrating bit charater.
480 public static String
getAutogenLibrarydatumTypeString(DATUM_TYPE datumType
) {
500 Get the sku data who id is 0.
502 @retval DynamicTokenValue the value of this dyanmic token.
504 public DynamicTokenValue
getDefaultSku() {
506 int size
= skuData
.size();
507 for (index
= 0; index
< size
; index
++) {
508 if (skuData
.get(index
).id
== 0) {
509 return skuData
.get(index
).value
;
517 Get the number of Sku data for this token
519 @retval int the number of sku data
521 public int getSkuIdCount () {
522 return this.skuData
.size();
526 Get the size of PCD value, this PCD is POINTER type.
528 @param str the string of the value
529 @param al the array list for outer parameter.
531 private void getCurrentSizeFromDefaultValue (String str
, ArrayList
<Integer
> al
) {
532 if (isValidNullValue(str
)) {
533 al
.add(new Integer(0));
536 // isValidNullValue has already make sure that str here
537 // always contain a valid default value of the following 3
539 // 1) "Hello world" //Assci string
540 // 2) L"Hello" //Unicode string
541 // 3) {0x01, 0x02, 0x03} //Byte stream
543 if (str
.startsWith("\"")) {
544 al
.add(new Integer(str
.length() - 2));
545 } else if (str
.startsWith("L\"")){
547 // Unicode is 2 bytes each.
549 al
.add(new Integer((str
.length() - 3) * 2));
550 } else if (str
.startsWith("{")) {
552 // We count the number of "," in the string.
553 // The number of byte is one plus the number of
560 pos
= str2
.indexOf(",", 0);
564 pos
= str2
.indexOf(",", pos
);
567 al
.add(new Integer(cnt
));
573 This method can be used to get the MAX and current size
574 for pointer type dynamic(ex) PCD entry
576 public ArrayList
<Integer
> getPointerTypeSize () {
577 ArrayList
<Integer
> al
= new ArrayList
<Integer
>();
580 // For VPD_enabled and HII_enabled, we can only return the MAX size.
581 // For the default DATA type dynamic PCD entry, we will return
582 // the MAX size and current size for each SKU_ID.
584 al
.add(new Integer(this.datumSize
));
586 if (!this.isVpdEnable()) {
588 if (this.isHiiEnable()){
589 for (idx
= 0; idx
< this.skuData
.size(); idx
++) {
590 String str
= this.skuData
.get(idx
).value
.hiiDefaultValue
;
591 getCurrentSizeFromDefaultValue(str
, al
);
594 for (idx
= 0; idx
< this.skuData
.size(); idx
++) {
595 String str
= this.skuData
.get(idx
).value
.value
;
596 getCurrentSizeFromDefaultValue(str
, al
);
605 Get default value for a token, For HII type, HiiDefaultValue of default
606 SKU 0 will be returned; For Default type, the defaultvalue of default SKU
609 @return String get the default value for a DYNAMIC type PCD.
611 public String
getDynamicDefaultValue() {
612 DynamicTokenValue dynamicData
= getDefaultSku();
613 if (hasDefaultValue()) {
614 switch (dynamicData
.type
) {
616 return dynamicData
.value
;
624 Judge whether a DYNAMIC PCD has default value.
626 @return whether a DYNAMIC PCD has default value.
628 public boolean hasDefaultValue () {
629 DynamicTokenValue dynamicValue
= null;
635 if (this.isDynamicPCD
) {
636 dynamicValue
= getDefaultSku();
637 switch (dynamicValue
.type
) {
643 return !isValidNullValue(dynamicValue
.value
);
651 Judge the value is NULL value. NULL value means the value is uninitialized value
653 @param judgedValue the want want to be judged
655 @return boolean whether the value of PCD is NULL.
657 public boolean isValidNullValue(String judgedValue
) {
659 BigInteger bigIntValue
;
665 if (judgedValue
.length() > 2) {
666 if ((judgedValue
.charAt(0) == '0') &&
667 ((judgedValue
.charAt(1) == 'x') || (judgedValue
.charAt(1) == 'X'))){
668 subStr
= judgedValue
.substring(2, judgedValue
.length());
669 bigIntValue
= new BigInteger(subStr
, 16);
671 bigIntValue
= new BigInteger(judgedValue
);
674 bigIntValue
= new BigInteger(judgedValue
);
676 if (bigIntValue
.bitCount() == 0) {
681 if (judgedValue
.length() > 2){
682 if ((judgedValue
.charAt(0) == '0') &&
683 ((judgedValue
.charAt(1) == 'x') ||
684 (judgedValue
.charAt(1) == 'X'))) {
685 bigIntValue
= new BigInteger(judgedValue
.substring(2, judgedValue
.length()), 16);
686 if (bigIntValue
.bitCount() == 0) {
690 bigIntValue
= new BigInteger(judgedValue
);
691 if (bigIntValue
.bitCount() == 0) {
696 bigIntValue
= new BigInteger(judgedValue
);
697 if (bigIntValue
.bitCount() == 0) {
703 if (judgedValue
.equalsIgnoreCase("false")) {
708 if (judgedValue
.equalsIgnoreCase("\"\"") ||
709 judgedValue
.equalsIgnoreCase("L\"\"") ||
710 (judgedValue
.length() == 0)) {
712 } else if (judgedValue
.trim().charAt(0) == '{') {
713 int start
= judgedValue
.indexOf('{');
714 int end
= judgedValue
.lastIndexOf('}');
715 String
[] strValueArray
= judgedValue
.substring(start
+ 1, end
).split(",");
716 if (strValueArray
.length
> 1) {
719 if (strValueArray
[0].matches("(0x)?(0X)?0*")) {
729 Is the string value in Unicode
731 @return boolean the string value is UNICODE type string.
733 public boolean isHiiDefaultValueUnicodeStringType() {
734 DynamicTokenValue dynamicData
= getDefaultSku();
736 if (dynamicData
== null)
739 return dynamicData
.hiiDefaultValue
.startsWith("L\"")
740 && dynamicData
.hiiDefaultValue
.endsWith("\"");
744 Is the string value in ANSCI
746 @return boolean whether the dfault value for HII case is string type.
748 public boolean isHiiDefaultValueASCIIStringType() {
749 DynamicTokenValue dynamicData
= getDefaultSku();
751 if (dynamicData
== null)
754 return dynamicData
.hiiDefaultValue
.startsWith("\"")
755 && dynamicData
.hiiDefaultValue
.endsWith("\"");
759 Judege whether current value is UNICODE string type.
761 @return boolean whether the value is UNICODE string.
763 public boolean isUnicodeStringType () {
764 String str
= getDynamicDefaultValue();
770 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
771 str
.startsWith("L\"") &&
772 str
.endsWith("\"")) {
780 Judge whether the string type is ANSIC string.
782 @return boolean whether the string type is ANSIC string
784 public boolean isASCIIStringType () {
785 String str
= getDynamicDefaultValue();
791 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
792 str
.startsWith("\"") &&
793 str
.endsWith("\"")) {
801 Judge whether the string value is byte array.
803 @return boolean whether the string value is byte array.
806 public boolean isByteStreamType () {
807 String str
= getDynamicDefaultValue();
813 if (datumType
== Token
.DATUM_TYPE
.POINTER
&&
814 str
.startsWith("{") &&
824 Get string value for ANSIC string type
826 @return String the string value
828 public String
getStringTypeString () {
829 return getDefaultSku().value
.substring(2, getDefaultSku().value
.length() - 1);